SMAUG
Simulating Machine Learning Applications on gem5-Aladdin
tensor.cpp
1 #include "smaug/core/tensor.h"
3 #include "smaug/core/globals.h"
4 #include "smaug/utility/thread_pool.h"
5 
6 namespace smaug {
7 
8 TensorShapeProto* TensorShape::asTensorShapeProto() {
9  TensorShapeProto* shapeProto = new TensorShapeProto();
10  *shapeProto->mutable_dims() = { dims_.begin(), dims_.end() };
11  shapeProto->set_layout(layout);
12  shapeProto->set_alignment(alignment);
13  return shapeProto;
14 }
15 
16 TensorProto* Tensor::asTensorProto() {
17  TensorProto* tensorProto = new TensorProto();
18  tensorProto->set_name(name);
19  tensorProto->set_data_type(dataType);
20  tensorProto->set_allocated_shape(shape.asTensorShapeProto());
21  tensorProto->set_data_format(dataFormat);
22  // Copy the tensor data into the proto.
23  TensorData* protoData = new TensorData();
24  void* rawPtr = tensorData.get();
25  switch (dataType) {
26  case Float16:
27  // Add 1 to cover the case when the storage size is odd.
28  protoData->mutable_half_data()->Resize(
29  (shape.storageSize() + 1) / 2, 0);
30  memcpy(protoData->mutable_half_data()->mutable_data(), rawPtr,
31  shape.storageSize() * sizeof(float16));
32  break;
33  case Float32:
34  protoData->mutable_float_data()->Resize(shape.storageSize(), 0);
35  memcpy(protoData->mutable_float_data()->mutable_data(), rawPtr,
36  shape.storageSize() * sizeof(float));
37  break;
38  case Float64:
39  protoData->mutable_double_data()->Resize(shape.storageSize(), 0);
40  memcpy(protoData->mutable_double_data()->mutable_data(), rawPtr,
41  shape.storageSize() * sizeof(double));
42  break;
43  case Int32:
44  protoData->mutable_int_data()->Resize(shape.storageSize(), 0);
45  memcpy(protoData->mutable_int_data()->mutable_data(), rawPtr,
46  shape.storageSize() * sizeof(int));
47  break;
48  case Int64:
49  protoData->mutable_int64_data()->Resize(shape.storageSize(), 0);
50  memcpy(protoData->mutable_int64_data()->mutable_data(), rawPtr,
51  shape.storageSize() * sizeof(int64_t));
52  break;
53  case Bool:
54  protoData->mutable_bool_data()->Resize(shape.storageSize(), 0);
55  memcpy(protoData->mutable_bool_data()->mutable_data(), rawPtr,
56  shape.storageSize() * sizeof(bool));
57  break;
58  default:
59  assert(false && "Unknown data type!");
60  }
61  tensorProto->set_allocated_data(protoData);
62  return tensorProto;
63 }
64 
66  Tile* tile = &tiles[index];
67  copyDataToTile(tile);
68  return tile->tensor;
69 }
70 
71 void TiledTensor::setTile(int index,
72  const std::vector<int>& origin,
73  Tensor* tensor,
74  bool copyData) {
75  Tile* tile = &tiles[index];
76  tile->tensor = tensor;
77  tile->origin = origin;
78  tile->hasOrigin = true;
79  if (copyData)
80  copyDataToTile(tile);
81 }
82 
83 void* TiledTensor::tileCopyWorker(void* _args) {
84  auto args = reinterpret_cast<CopyTilesArgs*>(_args);
85  TiledTensor* tiledTensor = args->tiledTensor;
86  int start = args->start;
87  int numTiles = args->numTiles;
88  TileDataOperation op = args->op;
89  for (int i = start; i < start + numTiles; i++) {
90  Tile* tile = tiledTensor->getTile(i);
91  if (op == Scatter)
92  tiledTensor->copyDataToTile(tile);
93  else if (op == Gather)
94  tiledTensor->gatherDataFromTile(tile);
95  }
96  delete args;
97  return nullptr;
98 }
99 
101  int totalNumTiles = tiles.size();
102  int numTilesPerThread = std::ceil(totalNumTiles * 1.0 / threadPool->size());
103  int remainingTiles = totalNumTiles;
104  while (remainingTiles > 0) {
105  int numTiles = std::min(numTilesPerThread, remainingTiles);
106  auto args = new CopyTilesArgs(
107  this, totalNumTiles - remainingTiles, numTiles, op);
108  int cpuid =
109  threadPool->dispatchThread(tileCopyWorker, (void*)args);
110  assert(cpuid != -1 && "Failed to dispatch thread!");
111  remainingTiles -= numTiles;
112  }
114 }
115 
117  // Don't copy if all the tiles have data filled.
118  if (dataFilled)
119  return;
120 
121  assert(origTensor != nullptr &&
122  "TiledTensor must have the original tensor to copy data from!");
123  if (fastForwardMode || !threadPool || tiles.size() == 1) {
124  for (auto index = startIndex(); !index.end(); ++index)
125  copyDataToTile(&tiles[index]);
126  } else {
128  }
129  dataFilled = true;
130 }
131 
133  // Don't copy if the tile already has data, or if the tile is the original
134  // tensor (we have only one tile).
135  if (tile->hasData || tile->tensor == origTensor)
136  return;
137 
138  // Perform the data copy.
139  assert(tile->hasOrigin &&
140  "Must set the tile's origin in the original tensor!");
141  if (useRawTensor) {
142  // Use the raw tensor copy function for the unary tile.
143  copyRawTensorData(tile->tensor, origTensor, 0, tile->origin[0],
144  tile->tensor->getShape().storageSize());
145  } else {
146  std::vector<int> dstOrigin(tile->tensor->ndims(), 0);
147  copyTensorRegion(tile->tensor, origTensor, dstOrigin, tile->origin,
148  tile->tensor->getShape().dims());
149  }
150  tile->hasData = true;
151 }
152 
154  assert(origTensor != nullptr &&
155  "TiledTensor must have the original tensor to copy data to!");
156  const TensorShape& tensorShape = origTensor->getShape();
157  int ndims = tensorShape.ndims();
158  if (tiles.size() == 1) {
159  // No need to copy data if the tile is the original tensor.
160  return;
161  }
162 
163  if (fastForwardMode || !threadPool) {
164  for (auto index = startIndex(); !index.end(); ++index)
165  gatherDataFromTile(&tiles[index]);
166  } else {
168  }
169 }
170 
172  // Perform the data copy.
173  assert(tile->hasOrigin &&
174  "Must set the tile's origin in the original tensor!");
175  if (useRawTensor) {
176  // Use the raw tensor copy function for the unary tile.
177  copyRawTensorData(origTensor, tile->tensor, tile->origin[0], 0,
178  tile->tensor->getShape().storageSize());
179  } else {
180  std::vector<int> srcOrigin(tile->tensor->ndims(), 0);
182  tile->tensor,
183  tile->origin,
184  srcOrigin,
185  tile->tensor->getShape().dims());
186  }
187 }
188 
189 } // namespace smaug
smaug::Tensor
Tensor represents a single multi-dimensional array of data.
Definition: tensor.h:344
smaug::Tensor::asTensorProto
TensorProto * asTensorProto()
Serializes this Tensor to a TensorProto.
Definition: tensor.cpp:16
smaug::TiledTensor::Tile
A tile is a rectangular portion of a larger Tensor.
Definition: tensor.h:630
smaug::threadPool
ThreadPool * threadPool
The user-space thread pool used by SMAUG to run multithreaded tasks.
Definition: globals.cpp:7
smaug::ThreadPool::joinThreadPool
void joinThreadPool()
Wait for all threads in the pool to finish work.
Definition: thread_pool.cpp:103
smaug::TensorBase::dataFormat
DataStorageFormat dataFormat
Indicates the compression format of the data.
Definition: tensor.h:324
smaug::TensorBase::name
std::string name
Name of of the Tensor.
Definition: tensor.h:317
smaug::TiledTensor::getTileWithData
Tensor * getTileWithData(int index)
Returns a Tensor at the specified tile position, with data copied from the original tensor.
Definition: tensor.cpp:65
smaug::TensorBase::shape
TensorShape shape
Shape of the Tensor.
Definition: tensor.h:319
smaug::copyTensorRegion
void copyTensorRegion(Tensor *dest, Tensor *src, std::vector< int > destOrigin, std::vector< int > srcOrigin, std::vector< int > regionSize)
Copies a region of a source Tensor to a corresponding region in a destination Tensor.
Definition: tensor_utils.cpp:65
smaug::TiledTensor::origTensor
Tensor * origTensor
The original Tensor that was tiled into this TiledTensor.
Definition: tensor.h:687
smaug::TiledTensor::dataFilled
bool dataFilled
True if all the tiles have data filled.
Definition: tensor.h:690
smaug::TiledTensor::gatherDataFromTile
void gatherDataFromTile(Tile *tile)
Copy data from this tile to the original Tensor.
Definition: tensor.cpp:171
smaug::TiledTensor
A multidimensional container of Tensors.
Definition: tensor.h:552
smaug::TiledTensor::Tile::hasOrigin
bool hasOrigin
True if the tile has its origin set.
Definition: tensor.h:636
tensor_utils.h
Utility functions for copying/printing/tiling tensors.
smaug::TiledTensor::setTile
void setTile(int index, const std::vector< int > &origin, Tensor *tensor, bool copyData)
Set the specified tile to the provided Tensor, and optionally copy data into it.
Definition: tensor.cpp:71
smaug::copyRawTensorData
void copyRawTensorData(Tensor *dest, Tensor *src, int destOffset, int srcOffset, int copySize)
Directly copies a linear region of memory from dest to src, without taking dimensions/padding into ac...
Definition: tensor_utils.cpp:138
smaug::fastForwardMode
bool fastForwardMode
True if we are simulating in fast-forward mode.
Definition: globals.cpp:5
smaug::TiledTensor::Tile::hasData
bool hasData
True if we have copied data to this tile.
Definition: tensor.h:638
globals.h
SMAUG Global variables.
smaug::TensorShape::asTensorShapeProto
TensorShapeProto * asTensorShapeProto()
Return a TensorShapeProto that serializes this TensorShape.
Definition: tensor.cpp:8
smaug::TensorShape
TensorShape describes the shape of a Tensor.
Definition: tensor.h:35
smaug::TiledTensor::parallelCopyTileData
void parallelCopyTileData(TileDataOperation op)
Split the work (data filling or gathering) across multiple threads.
Definition: tensor.cpp:100
smaug::TiledTensor::useRawTensor
bool useRawTensor
True if we should use copyRawTensorData() for copying data.
Definition: tensor.h:684
smaug::TiledTensor::CopyTilesArgs
Definition: tensor.h:658
smaug
The smaug namespace is the parent namespace of all C++ code in SMAUG.
Definition: backend.cpp:38
smaug::TiledTensor::TileDataOperation
TileDataOperation
Specifies what to do with the data in the original Tensor and tiles.
Definition: tensor.h:651
smaug::TiledTensor::Tile::tensor
Tensor * tensor
The new smaller Tensor of this tile.
Definition: tensor.h:632
smaug::ThreadPool::size
int size() const
Returns the number of worker threads.
Definition: thread_pool.h:38
smaug::TiledTensor::untile
void untile()
Copies data from the TiledTensor into the original Tensor.
Definition: tensor.cpp:153
smaug::ThreadPool::dispatchThread
int dispatchThread(WorkerThreadFunc func, void *args)
Dispatch the function to a worker in the thread pool.
Definition: thread_pool.cpp:85
smaug::TiledTensor::copyDataToAllTiles
void copyDataToAllTiles()
Copies data (if needed) to all the tiles from the original Tensor.
Definition: tensor.cpp:116
smaug::TiledTensor::Scatter
@ Scatter
Copies data from a contiguous Tensor to the tiles.
Definition: tensor.h:653
smaug::TiledTensor::Tile::origin
std::vector< int > origin
The tile's coordinate origins in the original tensor.
Definition: tensor.h:634
smaug::TiledTensor::tiles
std::vector< Tile > tiles
The list of Tiles, indexed using a TensorIndexIterator.
Definition: tensor.h:693
smaug::TiledTensor::copyDataToTile
void copyDataToTile(Tile *tile)
Copy data (if needed) to this tile from the original Tensor.
Definition: tensor.cpp:132
smaug::TiledTensor::Gather
@ Gather
Copies data from the tiles to a contiguous Tensor.
Definition: tensor.h:655