SMAUG
Simulating Machine Learning Applications on gem5-Aladdin
ref_inner_product_op.cpp
1 #include "smaug/core/backend.h"
3 #include "smaug/operators/inner_product_op.h"
4 #include "smaug/operators/ref/ref_activation_fun_op.h"
5 #include "smaug/utility/debug_stream.h"
6 
7 #ifdef __cplusplus
8 extern "C" {
9 #endif
10 
29  float* b,
30  float* c,
31  int a_height,
32  int a_width,
33  int b_width,
34  int a_pad,
35  int b_pad,
36  int c_pad,
37  activation_type act_function,
38  activation_param_t act_params) {
39  int input_size = a_height * (a_width + a_pad);
40  int weight_size = a_width * (b_width + b_pad);
41  int result_size = a_height * (b_width + c_pad);
42  dmaLoad(a, a, input_size * sizeof(float));
43  dmaLoad(b, b, weight_size * sizeof(float));
44 
45  ARRAY_2D(float, _a, a, a_width + a_pad);
46  ARRAY_2D(float, _b, b, b_width + b_pad);
47  ARRAY_2D(float, _c, c, b_width + c_pad);
48 
49  matmul0:
50  for (int i = 0; i < a_height; i++) {
51  matmul1:
52  for (int j = 0; j < b_width; j++) {
53  float result = 0;
54  matmul2:
55  for (int k = 0; k < a_width; k++) {
56  float a_val = _a[i][k];
57  float b_val = _b[k][j];
58  result += a_val * b_val;
59  }
60  _c[i][j] = result;
61  }
62  }
63  if (act_function != NO_ACTIVATION) {
64  activation_fun(c, c, result_size, act_function, act_params);
65  }
66  dmaLoad(c, c, result_size * sizeof(float));
67 }
68 
88  float* b,
89  float* c,
90  int a_height,
91  int b_width,
92  int b_height,
93  int a_pad,
94  int b_pad,
95  int c_pad,
96  activation_type act_function,
97  activation_param_t act_params) {
98  int a_width = b_width;
99  int input_size = a_height * (a_width + a_pad);
100  int weight_size = b_height * (b_width + b_pad);
101  int result_size = a_height * (b_height + c_pad);
102  dmaLoad(a, a, input_size * sizeof(float));
103  dmaLoad(b, b, weight_size * sizeof(float));
104 
105  ARRAY_2D(float, _a, a, a_width);
106  ARRAY_2D(float, _b, b, b_width);
107  ARRAY_2D(float, _c, c, b_height);
108 
109  matmul0:
110  for (int i = 0; i < a_height; i++) {
111  matmul1:
112  for (int j = 0; j < b_height; j++) {
113  float result = 0;
114  matmul2:
115  for (int k = 0; k < a_width; k++) {
116  float a_val = _a[i][k];
117  float b_val = _b[j][k];
118  result += a_val * b_val;
119  }
120  _c[i][j] = result;
121  }
122  }
123  if (act_function != NO_ACTIVATION) {
124  activation_fun(c, c, result_size, act_function, act_params);
125  }
126  dmaLoad(c, c, result_size * sizeof(float));
127 }
128 
129 #ifdef __cplusplus
130 }
131 #endif
132 
133 namespace smaug {
134 
135 template <>
136 void InnerProductOp<ReferenceBackend>::run() {
137  auto input = getInput(Inputs);
138  auto weights = getInput(Weights);
139  auto output = getOutput(Outputs);
140  const TensorShape& inputShape = input->getShape();
141  const TensorShape& weightShape = weights->getShape();
142  const TensorShape& outputShape = output->getShape();
143  assert(inputShape.getLayout() == DataLayout::NC);
144  assert(weightShape.getLayout() == DataLayout::NC ||
145  weightShape.getLayout() == DataLayout::CN);
146  assert(outputShape.getLayout() == DataLayout::NC);
147  dout(2) << *weights << "\n";
148 
149  float* inputData = input->data<float>();
150  float* weightData = weights->data<float>();
151  float* outputData = output->data<float>();
152  mapArrayToAccel(ref::kInnerProductHw, "a", inputData,
153  inputShape.storageSize() * sizeof(float));
154  mapArrayToAccel(ref::kInnerProductHw, "b", weightData,
155  weightShape.storageSize() * sizeof(float));
156  mapArrayToAccel(ref::kInnerProductHw, "c", outputData,
157  outputShape.storageSize() * sizeof(float));
158  bool weightsTransposed = weightShape.getLayout() == DataLayout::NC;
159  auto func = weightsTransposed ? ref_inner_product_ab_times_cb
161  int actIdx = weightsTransposed ? 1 : 0;
162  int neuronIdx = weightsTransposed ? 0 : 1;
163  invokeKernel(ref::kInnerProductHw, func, inputData, weightData, outputData,
164  inputShape[0], weightShape[actIdx], weightShape[neuronIdx],
165  inputShape.getPadding(1), weightShape.getPadding(1),
166  outputShape.getPadding(1), actInfo.function, actInfo.params);
167 }
168 
169 } // namespace smaug
activation_type
enum _activation_type activation_type
The activation function to apply to an operator's output in hardware.
smaug::dout
const DebugStream & dout(int debugLevel)
Returns a DebugStream instance for the given debug level.
Definition: debug_stream.cpp:16
ref_inner_product_ab_times_cb
void ref_inner_product_ab_times_cb(float *a, float *b, float *c, int a_height, int b_width, int b_height, int a_pad, int b_pad, int c_pad, activation_type act_function, activation_param_t act_params)
Definition: ref_inner_product_op.cpp:87
ref_inner_product_ab_times_bc
void ref_inner_product_ab_times_bc(float *a, float *b, float *c, int a_height, int a_width, int b_width, int a_pad, int b_pad, int c_pad, activation_type act_function, activation_param_t act_params)
Definition: ref_inner_product_op.cpp:28
_activation_param_t
Parameters to the activation function hardware.
Definition: common.h:194
smaug
The smaug namespace is the parent namespace of all C++ code in SMAUG.
Definition: backend.cpp:38
common.h
Utilities for writing and invoking Aladdin kernels from Operators.
smaug::mapArrayToAccel
void mapArrayToAccel(unsigned reqCode, const char *arrayName, void *baseAddr, size_t size)
Maps an array of data to the accelerator.
Definition: common.cpp:12
smaug::invokeKernel
void invokeKernel(int accelIdx, unsigned reqCode, const Kernel &kernel, Args &&... args)
The generic blocking interface for all accelerator kernel functions.
Definition: common.h:72