15 std::string input0Name = std::string(
"input_0");
16 std::string input1Name = std::string(
"input_1");
17 std::string outputName = std::string(
"output0_");
20 std::string blockName;
31 TosaSerializationOperator* op =
nullptr;
33 std::vector<TosaSerializationTensor*> tensors;
34 std::vector<TosaSerializationOperator*> operators;
35 DType inputDType0 =
ArmNNToDType(inputs[0]->GetDataType());
36 DType inputDType1 =
ArmNNToDType(inputs[1]->GetDataType());
37 DType outputDType0 =
ArmNNToDType(outputs[0]->GetDataType());
38 bool isInputInt8 = (inputDType0 == DType_INT8);
43 if(input0Name.find(
"input_") != std::string::npos)
46 tensors.push_back(
new TosaSerializationTensor(input0Name, inputShape0, inputDType0, {}));
48 if(input1Name.find(
"input_") != std::string::npos)
51 tensors.push_back(
new TosaSerializationTensor(input1Name, inputShape1, inputDType1, {}));
58 std::string outputElemenwiseBinaryName;
62 tensors.push_back(
new TosaSerializationTensor(outputElemenwiseBinaryName, outputShape0, DType_INT32, {}));
66 tensors.push_back(
new TosaSerializationTensor(outputName, outputShape0, outputDType0, {}));
71 bool isMulDesc = descriptor ? descriptor->
m_Operation == BinaryOperation::Mul :
false;
72 bool isMulOp = (type == LayerType::Multiplication) || isMulDesc ?
true :
false;
73 if (isInputInt8 && !isMulOp)
75 TosaSerializationOperator* rescaleOp0 =
nullptr;
77 input0ElemenwiseBinaryName,
78 inputs[0]->GetQuantizationScale() / outputs[0]->GetQuantizationScale(),
79 inputs[0]->GetQuantizationOffset(),
86 tensors.push_back(
new TosaSerializationTensor(input0ElemenwiseBinaryName,
90 operators.push_back(rescaleOp0);
92 TosaSerializationOperator* rescaleOp1 =
nullptr;
94 input1ElemenwiseBinaryName,
95 inputs[1]->GetQuantizationScale() / outputs[0]->GetQuantizationScale(),
96 inputs[1]->GetQuantizationOffset(),
103 tensors.push_back(
new TosaSerializationTensor(input1ElemenwiseBinaryName,
107 operators.push_back(rescaleOp1);
110 std::string& elementwiseInput0Str = isInputInt8 ? input0ElemenwiseBinaryName : input0Name;
111 std::string& elementwiseInput1Str = isInputInt8 ? input1ElemenwiseBinaryName : input1Name;
112 std::string& elementwiseOutputStr = isInputInt8 ? outputElemenwiseBinaryName : outputName;
116 case LayerType::Addition:
118 op =
new TosaSerializationOperator(Op_ADD,
121 {input0Name, input1Name},
126 case LayerType::ElementwiseBinary:
130 case BinaryOperation::Add:
132 op =
new TosaSerializationOperator(Op_ADD,
135 {elementwiseInput0Str, elementwiseInput1Str},
136 {elementwiseOutputStr});
140 case BinaryOperation::Maximum:
142 op =
new TosaSerializationOperator(Op_MAXIMUM,
145 {elementwiseInput0Str, elementwiseInput1Str},
146 {elementwiseOutputStr});
150 case BinaryOperation::Mul:
153 TosaMulAttribute mulAttribute(shift);
157 op =
new TosaSerializationOperator(Op_MUL,
158 Attribute_MulAttribute,
160 {input0Name, input1Name},
161 {elementwiseOutputStr});
165 case BinaryOperation::Sub:
167 op =
new TosaSerializationOperator(Op_SUB,
170 {elementwiseInput0Str, elementwiseInput1Str},
171 {elementwiseOutputStr});
175 case BinaryOperation::SqDiff:
177 throw Exception(
"TOSA mappings of Squared Difference operator "
178 "implemented under ConvertSquaredDifferenceToTosaOperator().");
181 throw Exception(
"ConvertElementwiseBinaryToTosaOperator: Unsupported layer type.");
185 case LayerType::Multiplication:
188 TosaMulAttribute mulAttribute(shift);
189 op =
new TosaSerializationOperator(Op_MUL,
190 Attribute_MulAttribute,
192 {input0Name, input1Name},
197 case LayerType::Subtraction:
199 op =
new TosaSerializationOperator(Op_SUB,
202 {input0Name, input1Name},
208 throw Exception(
"ConvertElementwiseBinaryToTosaOperator: Unsupported layer type.");
211 operators.push_back(op);
215 if (inputDType0 == DType_INT8)
218 float input0QScale = inputs[0]->IsQuantized()?inputs[0]->GetQuantizationScale():1.0f;
219 float input1QScale = inputs[1]->IsQuantized()?inputs[1]->GetQuantizationScale():1.0f;
220 float outputQScale = outputs[0]->IsQuantized()?outputs[0]->GetQuantizationScale():1.0f;
221 double combinedQScale = input0QScale * input1QScale / outputQScale;
223 TosaSerializationOperator* rescaleOp =
nullptr;
228 outputs[0]->GetQuantizationOffset(),
234 tensors.push_back(
new TosaSerializationTensor(outputName,
238 operators.push_back(rescaleOp);
241 return new TosaSerializationBasicBlock(blockName,
245 {input0Name, input1Name},
std::string GenerateUniqueOutputName(const Layer &layer, uint32_t layerSlot=0)
const std::string mainName
DType ArmNNToDType(const DataType &type)
std::vector< int32_t > GetTosaTensorShape(const TensorShape &shape)
std::string GenerateUniqueInputName(const armnn::InputSlot &slot)
std::string GetUniqueTosaMappingID()
void CreateRescaleTosaOperator(const std::string &inputName, const std::string &outputName, double scale, int32_t input_zp, int32_t output_zp, bool input_unsigned, bool output_unsigned, bool double_round, bool scale32, TosaSerializationOperator **op)
Base class for all ArmNN exceptions so that users can filter to just those.
const InputSlot & GetInputSlot(unsigned int index) const override
Get a const input slot handle by slot index.
BinaryOperation m_Operation
Specifies the elementwiseBinary operation to execute.