24 "ConvertSoftmaxToTosaOperator: Softmax currently only supports Int8 Quantized inputs");
27 "ConvertSoftmaxToTosaOperator: Softmax must have only one input");
30 "ConvertSoftmaxToTosaOperator: Softmax must have at least one output");
32 std::string inputName = std::string(
"input_");
33 std::string outputName = std::string(
"output0_");
104 std::vector<TosaSerializationTensor *> tensors;
105 std::vector<TosaSerializationOperator *> operators;
116 if (inputName.find(
"input_") != std::string::npos)
118 tensors.push_back(
new TosaSerializationTensor(inputName, inputShape0, inputDType0, {}));
126 std::vector<uint8_t> uint8Data;
129 const std::vector<int32_t> singleValueShape(rank,1);
130 auto axis =
static_cast<int32_t
>(rank - 1);
131 TosaAxisAttribute tosaAxisAttribute(axis);
134 std::vector<int32_t> reduceShape = inputShape0;
135 reduceShape[
static_cast<unsigned long>(axis)] = 1;
137 TosaSerializationOperator *rescaleOp1 =
nullptr;
139 false,
false,
false,
true, &rescaleOp1);
141 tensors.push_back(
new TosaSerializationTensor(outputNameRescale1, inputShape0, DType_INT32, {}));
142 operators.push_back(rescaleOp1);
144 auto *reduceMaxOp1 =
new TosaSerializationOperator(Op_REDUCE_MAX,
145 Attribute_AxisAttribute,
147 {outputNameRescale1},
148 {outputNameReduceMax1});
149 tensors.push_back(
new TosaSerializationTensor(outputNameReduceMax1, reduceShape, DType_INT32, {}));
150 operators.push_back(reduceMaxOp1);
152 auto *subOp1 =
new TosaSerializationOperator(Op_SUB,
155 {outputNameRescale1, outputNameReduceMax1},
157 tensors.push_back(
new TosaSerializationTensor(outputNameSub1, inputShape0, DType_INT32, {}));
158 operators.push_back(subOp1);
160 TosaSerializationOperator *rescaleOp2 =
nullptr;
162 tensors.push_back(
new TosaSerializationTensor(outputNameRescale2, inputShape0, DType_INT16, {}));
163 operators.push_back(rescaleOp2);
165 std::array<std::vector <int16_t>, 4> lookupTables;
168 const std::vector<int16_t> first = lookupTables[0];
169 const std::vector<int16_t> table1(&first[0],&first[0]+513);
170 const std::vector<int16_t> second = lookupTables[1];
171 const std::vector<int16_t> table2(&second[0],&second[0]+513);
172 const std::vector<int16_t> third = lookupTables[2];
173 const std::vector<int16_t> table3(&third[0],&third[0]+513);
174 const std::vector<int16_t> fourth = lookupTables[3];
175 const std::vector<int16_t> table4(&fourth[0],&fourth[0]+513);
177 TosaTableAttribute tosaTableAttribute1(table1);
178 TosaTableAttribute tosaTableAttribute2(table2);
179 TosaTableAttribute tosaTableAttribute3(table3);
180 TosaTableAttribute tosaTableAttribute4(table4);
182 auto* tableOp1 =
new TosaSerializationOperator(Op_TABLE,
183 Attribute_TableAttribute,
184 &tosaTableAttribute1,
185 {outputNameRescale2},
187 tensors.push_back(
new TosaSerializationTensor(outputNameTable1, inputShape0, DType_INT32, {}));
188 operators.push_back(tableOp1);
190 auto* tableOp2 =
new TosaSerializationOperator(Op_TABLE,
191 Attribute_TableAttribute,
192 &tosaTableAttribute2,
193 {outputNameRescale2},
195 tensors.push_back(
new TosaSerializationTensor(outputNameTable2, inputShape0, DType_INT32, {}));
196 operators.push_back(tableOp2);
198 auto* tableOp3 =
new TosaSerializationOperator(Op_TABLE,
199 Attribute_TableAttribute,
200 &tosaTableAttribute3,
201 {outputNameRescale2},
203 tensors.push_back(
new TosaSerializationTensor(outputNameTable3, inputShape0, DType_INT32, {}));
204 operators.push_back(tableOp3);
206 auto* tableOp4 =
new TosaSerializationOperator(Op_TABLE,
207 Attribute_TableAttribute,
208 &tosaTableAttribute4,
209 {outputNameRescale2},
211 tensors.push_back(
new TosaSerializationTensor(outputNameTable4, inputShape0, DType_INT32, {}));
212 operators.push_back(tableOp4);
214 TosaSerializationHandler::ConvertI32toU8({17}, uint8Data);
215 tensors.push_back(
new TosaSerializationTensor(inputNameConst1,singleValueShape, DType_INT32,uint8Data));
216 operators.push_back(
new TosaSerializationOperator(Op_CONST, Attribute_NONE,
nullptr, {}, {inputNameConst1}));
218 auto* logicalLOp1 =
new TosaSerializationOperator(Op_LOGICAL_LEFT_SHIFT,
221 {outputNameTable1, inputNameConst1},
222 {outputNameLogicalL1});
223 tensors.push_back(
new TosaSerializationTensor(outputNameLogicalL1, inputShape0, DType_INT32, {}));
224 operators.push_back(logicalLOp1);
226 TosaSerializationHandler::ConvertI32toU8({9}, uint8Data);
227 tensors.push_back(
new TosaSerializationTensor(inputNameConst2, singleValueShape, DType_INT32,uint8Data));
228 operators.push_back(
new TosaSerializationOperator(Op_CONST, Attribute_NONE,
nullptr, {}, {inputNameConst2}));
230 auto* logicalLOp2 =
new TosaSerializationOperator(Op_LOGICAL_LEFT_SHIFT,
233 {outputNameTable2, inputNameConst2},
234 {outputNameLogicalL2});
235 tensors.push_back(
new TosaSerializationTensor(outputNameLogicalL2, inputShape0, DType_INT32, {}));
236 operators.push_back(logicalLOp2);
238 TosaSerializationHandler::ConvertI32toU8({1}, uint8Data);
239 tensors.push_back(
new TosaSerializationTensor(inputNameConst3, singleValueShape, DType_INT32,uint8Data));
240 operators.push_back(
new TosaSerializationOperator(Op_CONST, Attribute_NONE,
nullptr, {}, {inputNameConst3}));
242 auto* logicalLOp3 =
new TosaSerializationOperator(Op_LOGICAL_LEFT_SHIFT,
245 {outputNameTable3, inputNameConst3},
246 {outputNameLogicalL3});
247 tensors.push_back(
new TosaSerializationTensor(outputNameLogicalL3, inputShape0, DType_INT32, {}));
248 operators.push_back(logicalLOp3);
250 bool rounding =
true;
251 TosaArithmeticRightShiftAttribute shiftRAttribute(rounding);
253 TosaSerializationHandler::ConvertI32toU8({7}, uint8Data);
254 tensors.push_back(
new TosaSerializationTensor(inputNameConst4, singleValueShape, DType_INT32,uint8Data));
255 operators.push_back(
new TosaSerializationOperator(Op_CONST, Attribute_NONE,
nullptr, {}, {inputNameConst4}));
257 auto* arithmeticROp1 =
new TosaSerializationOperator(Op_ARITHMETIC_RIGHT_SHIFT,
258 Attribute_ArithmeticRightShiftAttribute,
260 {outputNameTable4, inputNameConst4},
261 {outputNameArithmeticR1});
262 tensors.push_back(
new TosaSerializationTensor(outputNameArithmeticR1, inputShape0, DType_INT32, {}));
263 operators.push_back(arithmeticROp1);
265 auto* addOp1 =
new TosaSerializationOperator(Op_ADD,
268 {outputNameLogicalL1, outputNameLogicalL2},
270 tensors.push_back(
new TosaSerializationTensor(outputNameAdd1, inputShape0, DType_INT32, {}));
271 operators.push_back(addOp1);
273 auto* addOp2 =
new TosaSerializationOperator(Op_ADD,
276 {outputNameAdd1, outputNameLogicalL3},
278 tensors.push_back(
new TosaSerializationTensor(outputNameAdd2, inputShape0, DType_INT32, {}));
279 operators.push_back(addOp2);
281 auto* addOp3 =
new TosaSerializationOperator(Op_ADD,
284 {outputNameAdd2, outputNameArithmeticR1},
286 tensors.push_back(
new TosaSerializationTensor(outputNameAdd3, inputShape0, DType_INT32, {}));
287 operators.push_back(addOp3);
289 TosaSerializationHandler::ConvertI32toU8({12}, uint8Data);
290 tensors.push_back(
new TosaSerializationTensor(inputNameConst5, singleValueShape, DType_INT32,uint8Data));
291 operators.push_back(
new TosaSerializationOperator(Op_CONST, Attribute_NONE,
nullptr, {}, {inputNameConst5}));
293 auto* arithmeticROp2 =
new TosaSerializationOperator(Op_ARITHMETIC_RIGHT_SHIFT,
294 Attribute_ArithmeticRightShiftAttribute,
296 {outputNameAdd3, inputNameConst5},
297 {outputNameArithmeticR2});
298 tensors.push_back(
new TosaSerializationTensor(outputNameArithmeticR2, inputShape0, DType_INT32, {}));
299 operators.push_back(arithmeticROp2);
301 auto* reduceSumOp1 =
new TosaSerializationOperator(Op_REDUCE_SUM,
302 Attribute_AxisAttribute,
304 {outputNameArithmeticR2},
305 {outputNameReduceSum1});
306 tensors.push_back(
new TosaSerializationTensor(outputNameReduceSum1, reduceShape, DType_INT32, {}));
307 operators.push_back(reduceSumOp1);
309 auto* countLeadingZeroOp1 =
new TosaSerializationOperator(Op_CLZ,
312 {outputNameReduceSum1},
314 tensors.push_back(
new TosaSerializationTensor(outputNameCLZ1, reduceShape, DType_INT32, {}));
315 operators.push_back(countLeadingZeroOp1);
317 TosaSerializationHandler::ConvertI32toU8({1}, uint8Data);
318 tensors.push_back(
new TosaSerializationTensor(inputNameConst3a, singleValueShape, DType_INT32, uint8Data));
319 operators.push_back(
new TosaSerializationOperator(Op_CONST, Attribute_NONE,
nullptr, {}, {inputNameConst3a}));
321 auto* subOp2 =
new TosaSerializationOperator(Op_SUB,
324 {outputNameCLZ1, inputNameConst3a},
326 tensors.push_back(
new TosaSerializationTensor(outputNameSub2, reduceShape, DType_INT32, {}));
327 operators.push_back(subOp2);
330 auto* logicalLOp4 =
new TosaSerializationOperator(Op_LOGICAL_LEFT_SHIFT,
333 {outputNameReduceSum1, outputNameSub2},
334 {outputNameLogicalL4});
335 tensors.push_back(
new TosaSerializationTensor(outputNameLogicalL4, reduceShape, DType_INT32, {}));
336 operators.push_back(logicalLOp4);
338 TosaMulAttribute mulAttribute1(31);
340 TosaSerializationHandler::ConvertI32toU8({-1010580540}, uint8Data);
341 tensors.push_back(
new TosaSerializationTensor(inputNameConst6, singleValueShape, DType_INT32,uint8Data));
342 operators.push_back(
new TosaSerializationOperator(Op_CONST, Attribute_NONE,
nullptr, {}, {inputNameConst6}));
345 auto* mulOp1 =
new TosaSerializationOperator(Op_MUL,
346 Attribute_MulAttribute,
348 {outputNameLogicalL4, inputNameConst6},
350 tensors.push_back(
new TosaSerializationTensor(outputNameMul1, reduceShape, DType_INT32, {}));
351 operators.push_back(mulOp1);
353 TosaSerializationHandler::ConvertI32toU8({1515870810}, uint8Data);
354 tensors.push_back(
new TosaSerializationTensor(inputNameConst7, singleValueShape, DType_INT32,uint8Data));
355 operators.push_back(
new TosaSerializationOperator(Op_CONST, Attribute_NONE,
nullptr, {}, {inputNameConst7}));
358 auto* addOp4 =
new TosaSerializationOperator(Op_ADD,
361 {outputNameMul1, inputNameConst7},
363 tensors.push_back(
new TosaSerializationTensor(outputNameAdd4, reduceShape, DType_INT32, {}));
364 operators.push_back(addOp4);
367 auto* mulOp2 =
new TosaSerializationOperator(Op_MUL,
368 Attribute_MulAttribute,
370 {outputNameAdd4, outputNameLogicalL4},
372 tensors.push_back(
new TosaSerializationTensor(outputNameMul2, reduceShape, DType_INT32, {}));
373 operators.push_back(mulOp2);
375 TosaSerializationHandler::ConvertI32toU8({536870912}, uint8Data);
376 tensors.push_back(
new TosaSerializationTensor(inputNameConst8, singleValueShape, DType_INT32,uint8Data));
377 operators.push_back(
new TosaSerializationOperator(Op_CONST, Attribute_NONE,
nullptr, {}, {inputNameConst8}));
379 auto* subOp3 =
new TosaSerializationOperator(Op_SUB,
382 {inputNameConst8, outputNameMul2},
384 tensors.push_back(
new TosaSerializationTensor(outputNameSub3, reduceShape, DType_INT32, {}));
385 operators.push_back(subOp3);
387 auto* mulOp3 =
new TosaSerializationOperator(Op_MUL,
388 Attribute_MulAttribute,
390 {outputNameAdd4, outputNameSub3},
392 tensors.push_back(
new TosaSerializationTensor(outputNameMul3, reduceShape, DType_INT32, {}));
393 operators.push_back(mulOp3);
395 TosaMulAttribute mulAttribute2(0);
397 TosaSerializationHandler::ConvertI32toU8({4}, uint8Data);
398 tensors.push_back(
new TosaSerializationTensor(inputNameConst9, singleValueShape, DType_INT32,uint8Data));
399 operators.push_back(
new TosaSerializationOperator(Op_CONST, Attribute_NONE,
nullptr, {}, {inputNameConst9}));
401 auto* mulOp4 =
new TosaSerializationOperator(Op_MUL,
402 Attribute_MulAttribute,
404 {outputNameMul3, inputNameConst9},
406 tensors.push_back(
new TosaSerializationTensor(outputNameMul4, reduceShape, DType_INT32, {}));
407 operators.push_back(mulOp4);
409 auto* addOp5 =
new TosaSerializationOperator(Op_ADD,
412 {outputNameAdd4, outputNameMul4},
414 tensors.push_back(
new TosaSerializationTensor(outputNameAdd5, reduceShape, DType_INT32, {}));
415 operators.push_back(addOp5);
418 auto* mulOp5 =
new TosaSerializationOperator(Op_MUL,
419 Attribute_MulAttribute,
421 {outputNameAdd5, outputNameLogicalL4},
423 tensors.push_back(
new TosaSerializationTensor(outputNameMul5, reduceShape, DType_INT32, {}));
424 operators.push_back(mulOp5);
426 TosaSerializationHandler::ConvertI32toU8({536870912}, uint8Data);
427 tensors.push_back(
new TosaSerializationTensor(inputNameConst8a, singleValueShape, DType_INT32,uint8Data));
428 operators.push_back(
new TosaSerializationOperator(Op_CONST, Attribute_NONE,
nullptr, {}, {inputNameConst8a}));
430 auto* subOp4 =
new TosaSerializationOperator(Op_SUB,
433 {inputNameConst8a, outputNameMul5},
435 tensors.push_back(
new TosaSerializationTensor(outputNameSub4, reduceShape, DType_INT32, {}));
436 operators.push_back(subOp4);
438 auto* mulOp6 =
new TosaSerializationOperator(Op_MUL,
439 Attribute_MulAttribute,
441 {outputNameAdd5, outputNameSub4},
443 tensors.push_back(
new TosaSerializationTensor(outputNameMul6, reduceShape, DType_INT32, {}));
444 operators.push_back(mulOp6);
446 TosaSerializationHandler::ConvertI32toU8({4}, uint8Data);
447 tensors.push_back(
new TosaSerializationTensor(inputNameConst9a, singleValueShape, DType_INT32,uint8Data));
448 operators.push_back(
new TosaSerializationOperator(Op_CONST, Attribute_NONE,
nullptr, {}, {inputNameConst9a}));
450 auto* mulOp7 =
new TosaSerializationOperator(Op_MUL,
451 Attribute_MulAttribute,
453 {outputNameMul6, inputNameConst9a},
455 tensors.push_back(
new TosaSerializationTensor(outputNameMul7, reduceShape, DType_INT32, {}));
456 operators.push_back(mulOp7);
458 auto* addOp6 =
new TosaSerializationOperator(Op_ADD,
461 {outputNameAdd5, outputNameMul7},
463 tensors.push_back(
new TosaSerializationTensor(outputNameAdd6, reduceShape, DType_INT32, {}));
464 operators.push_back(addOp6);
467 auto* mulOp8 =
new TosaSerializationOperator(Op_MUL,
468 Attribute_MulAttribute,
470 {outputNameAdd6, outputNameLogicalL4},
472 tensors.push_back(
new TosaSerializationTensor(outputNameMul8, reduceShape, DType_INT32, {}));
473 operators.push_back(mulOp8);
475 TosaSerializationHandler::ConvertI32toU8({536870912}, uint8Data);
476 tensors.push_back(
new TosaSerializationTensor(inputNameConst8b, singleValueShape, DType_INT32,uint8Data));
477 operators.push_back(
new TosaSerializationOperator(Op_CONST, Attribute_NONE,
nullptr, {}, {inputNameConst8b}));
479 auto* subOp5 =
new TosaSerializationOperator(Op_SUB,
482 {inputNameConst8b, outputNameMul8},
484 tensors.push_back(
new TosaSerializationTensor(outputNameSub5, reduceShape, DType_INT32, {}));
485 operators.push_back(subOp5);
487 auto* mulOp9 =
new TosaSerializationOperator(Op_MUL,
488 Attribute_MulAttribute,
490 {outputNameAdd6, outputNameSub5},
492 tensors.push_back(
new TosaSerializationTensor(outputNameMul9, reduceShape, DType_INT32, {}));
493 operators.push_back(mulOp9);
495 TosaSerializationHandler::ConvertI32toU8({4}, uint8Data);
496 tensors.push_back(
new TosaSerializationTensor(inputNameConst9b, singleValueShape, DType_INT32,uint8Data));
497 operators.push_back(
new TosaSerializationOperator(Op_CONST, Attribute_NONE,
nullptr, {}, {inputNameConst9b}));
499 auto* mulOp10 =
new TosaSerializationOperator(Op_MUL,
500 Attribute_MulAttribute,
502 {outputNameMul9, inputNameConst9b},
504 tensors.push_back(
new TosaSerializationTensor(outputNameMul10, reduceShape, DType_INT32, {}));
505 operators.push_back(mulOp10);
507 auto* addOp7 =
new TosaSerializationOperator(Op_ADD,
510 {outputNameAdd6, outputNameMul10},
512 tensors.push_back(
new TosaSerializationTensor(outputNameAdd7, reduceShape, DType_INT32, {}));
513 operators.push_back(addOp7);
515 TosaMulAttribute mulAttribute3(30);
517 auto* mulOp11 =
new TosaSerializationOperator(Op_MUL,
518 Attribute_MulAttribute,
520 {outputNameAdd3, outputNameAdd7},
522 tensors.push_back(
new TosaSerializationTensor(outputNameMul11, outputShape0, DType_INT32, {}));
523 operators.push_back(mulOp11);
525 TosaSerializationHandler::ConvertI32toU8({35}, uint8Data);
526 tensors.push_back(
new TosaSerializationTensor(inputNameConst10, singleValueShape, DType_INT32,uint8Data));
527 operators.push_back(
new TosaSerializationOperator(Op_CONST, Attribute_NONE,
nullptr, {}, {inputNameConst10}));
529 auto* subOp6 =
new TosaSerializationOperator(Op_SUB,
532 {inputNameConst10, outputNameCLZ1},
534 tensors.push_back(
new TosaSerializationTensor(outputNameSub6, reduceShape, DType_INT32, {}));
535 operators.push_back(subOp6);
537 auto* arithmeticROp3 =
new TosaSerializationOperator(Op_ARITHMETIC_RIGHT_SHIFT,
538 Attribute_ArithmeticRightShiftAttribute,
540 {outputNameMul11, outputNameSub6},
541 {outputNameArithmeticR3});
542 tensors.push_back(
new TosaSerializationTensor(outputNameArithmeticR3, outputShape0, DType_INT32, {}));
543 operators.push_back(arithmeticROp3);
545 TosaSerializationOperator* rescaleOp3 =
nullptr;
547 false,
true, &rescaleOp3);
549 tensors.push_back(
new TosaSerializationTensor(outputName, outputShape0, outputDType0, {}));
550 operators.push_back(rescaleOp3);
552 return new TosaSerializationBasicBlock(blockName,
#define ARMNN_THROW_INVALIDARG_MSG_IF_FALSE(_cond, _str)
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)
void CalculateSoftmaxTableValues(double softmaxBeta, double scale, std::array< std::vector< int16_t >, 4 > &tables)
const InputSlot & GetInputSlot(unsigned int index) const override
Get a const input slot handle by slot index.
float GetQuantizationScale() const
unsigned int GetNumDimensions() const
int32_t GetQuantizationOffset() const
const TensorShape & GetShape() const
DataType GetDataType() const
constexpr bool IsQuantized8BitType(DataType dataType)
float m_Beta
Exponentiation value.