1 #include "smaug/core/backend.h"
4 #include "smaug/operators/smv/smv_unary_op_common.h"
5 #include "smaug/operators/smv/smv_relu_op.h"
6 #include "smaug/operators/smv/smv_elu_op.h"
7 #include "smaug/operators/smv/smv_tanh_op.h"
8 #include "smaug/operators/smv/smv_sigmoid_op.h"
9 #include "smaug/operators/smv/smv_kernels.h"
10 #include "smaug/utility/debug_stream.h"
20 OpType opType = op->getOpType();
21 if (opType == OpType::ReLU) {
22 auto reluOp =
dynamic_cast<SmvReluOp*
>(op);
23 params.slope = reluOp->getSlope();
25 function = activation_type::LRELU;
27 function = activation_type::RELU;
28 }
else if (opType == OpType::ELU) {
29 function = activation_type::ELU;
30 auto eluOp =
dynamic_cast<SmvEluOp*
>(op);
31 params.alpha = eluOp->getAlpha();
32 }
else if (opType == OpType::SELU) {
33 function = activation_type::SELU;
34 auto seluOp =
dynamic_cast<SmvSeluOp*
>(op);
35 params.alpha = seluOp->getAlpha();
36 params.lambda = seluOp->getLambda();
37 }
else if (opType == OpType::Tanh) {
38 function = activation_type::TANH;
39 }
else if (opType == OpType::HardTanh) {
40 function = activation_type::HARD_TANH;
42 params.min = hardTanhOp->getMin();
43 params.max = hardTanhOp->getMax();
44 }
else if (opType == OpType::Sigmoid) {
45 function = activation_type::SIGMOID;
46 }
else if (opType == OpType::Softmax) {
47 assert(
false &&
"Softmax should call its own run() implementation!");
49 return {
function, params };
54 assert(inputs.size() == outputs.size());
57 smv::kEltwiseOpHw,
"host_inputs", op->getInputsMemType());
59 smv::kEltwiseOpHw,
"host_results", op->getOutputsMemType());
60 for (
int i = 0; i < inputs.size(); i++) {
61 dout(1) <<
"Input: " << i <<
", output: " << i <<
"\n";
63 Tensor* outputTile = outputs[i];
64 const TensorShape& inputShape = inputTile->getShape();
65 const TensorShape& outputShape = outputTile->getShape();
67 inputTile->
data<float16>(),
68 inputShape.storageSize() *
sizeof(float16));
70 outputTile->
data<float16>(),
71 outputShape.storageSize() *
sizeof(float16));
74 inputTile->
data<float16>(), outputTile->
data<float16>(),
75 smv::spad0, smv::spad1, inputShape.storageSize(),
76 actParams.first, actParams.second);
86 std::min(SmvBackend::SpadSize() / inputs->getDataTypeSize(),
87 inputs->getShape().storageSize());
89 { 1, maxTileSize }, DataLayout::NC, SmvBackend::Alignment);
91 inputs, tileShape, op, copyData);
93 outputs, tileShape, op, copyData);
94 return { tiledInputs, tiledOutputs };
97 void run(UnaryOp<SmvBackend>* op, std::array<TiledTensor, 2>& tiledTensors) {
98 auto inputs = op->getInput(UnaryOp<SmvBackend>::Inputs);
99 auto outputs = op->getOutput(UnaryOp<SmvBackend>::Outputs);
102 auto stats = gem5::ScopedStats(
103 stats::kTensorPrepStart, stats::kTensorPrepEnd);
104 tiledTensors[0].copyDataToAllTiles();
107 runX(op, tiledTensors[0], tiledTensors[1]);
110 auto stats = gem5::ScopedStats(
111 stats::kTensorFinalStart, stats::kTensorFinalEnd);