22 if (inputs.size() != 1)
24 throw armnn::Exception(
"ConvertReluToTosaOperator: 1 input tensors required.");
27 if (outputs.size() != 1)
29 throw armnn::Exception(
"ConvertReluToTosaOperator: 1 output tensor required.");
32 std::string inputName = std::string(
"input_");
33 std::string outputName = std::string(
"output0_");
34 std::string blockName =
"";
36 int32_t clamp_min = 0;
37 int32_t clamp_max = 0;
38 float float_max = 0.0f;
41 case ActivationFunction::ReLu:
43 clamp_max = std::numeric_limits<int32_t>::max();
44 float_max = std::numeric_limits<float>::max();
48 case ActivationFunction::BoundedReLu:
50 clamp_max =
static_cast<int32_t
>(desc->
m_A);
51 float_max = desc->
m_A;
55 case ActivationFunction::LeakyReLu:
57 throw Exception(
"LeakyRelu TOSA mappings are performed in ConvertLeakyReluToTosaOperator().");
61 throw Exception(
"Activation function is not supported in ConvertReluToTosaOperator().");
73 std::vector<TosaSerializationTensor*> tensors;
74 std::vector<TosaSerializationOperator*> operators;
79 std::vector<int32_t> inputShape0;
80 DType inputDType0 = DType::DType_UNKNOWN;
81 if(inputName.find(
"input_") != std::string::npos)
85 tensors.push_back(
new TosaSerializationTensor(inputName, inputShape0, inputDType0, {}));
89 DType outputDType0 =
ArmNNToDType(outputs[0]->GetDataType());
90 tensors.push_back(
new TosaSerializationTensor(outputName, outputShape0, outputDType0, {}));
92 std::string clampInputNameStr = inputName;
93 if (inputDType0 == tosa::DType::DType_INT8 || inputDType0 == tosa::DType::DType_INT16)
96 clampInputNameStr = outputNameRescale;
98 double scale = inputs[0]->GetQuantizationScale() / outputs[0]->GetQuantizationScale();
99 int32_t input_zp = inputs[0]->GetQuantizationOffset();
100 int32_t output_zp = outputs[0]->GetQuantizationOffset();
102 clamp_min = output_zp;
104 if (desc->
m_Function == ActivationFunction::BoundedReLu)
106 clamp_max =
static_cast<int32_t
>(std::round(desc->
m_A / outputs[0]->GetQuantizationScale())) + output_zp;
109 if (inputDType0 == tosa::DType::DType_INT8)
112 clamp_min < std::numeric_limits<int8_t>::min() ? std::numeric_limits<int8_t>::min() : clamp_min;
114 clamp_max > std::numeric_limits<int8_t>::max() ? std::numeric_limits<int8_t>::max() : clamp_max;
119 clamp_min < std::numeric_limits<int16_t>::min() ? std::numeric_limits<int16_t>::min() : clamp_min;
121 clamp_max > std::numeric_limits<int16_t>::max() ? std::numeric_limits<int16_t>::max() : clamp_max;
124 TosaSerializationOperator* rescaleOp =
nullptr;
133 operators.push_back(rescaleOp);
134 tensors.push_back(
new TosaSerializationTensor(outputNameRescale,
140 TosaClampAttribute attribute(clamp_min, clamp_max, 0, float_max);
141 auto* clamp_op =
new TosaSerializationOperator(Op_CLAMP,
142 Attribute_ClampAttribute,
146 operators.push_back(clamp_op);
150 return new TosaSerializationBasicBlock(blockName,