ArmNN
 25.02
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
SoftmaxOperator.cpp File Reference
Include dependency graph for SoftmaxOperator.cpp:

Go to the source code of this file.

Functions

TosaSerializationBasicBlock * ConvertSoftmaxToTosaOperator (const Layer *layer, const std::vector< const TensorInfo * > &inputs, const std::vector< const TensorInfo * > &outputs, const SoftmaxDescriptor *softmaxDescriptor)
 

Function Documentation

◆ ConvertSoftmaxToTosaOperator()

TosaSerializationBasicBlock* ConvertSoftmaxToTosaOperator ( const Layer layer,
const std::vector< const TensorInfo * > &  inputs,
const std::vector< const TensorInfo * > &  outputs,
const SoftmaxDescriptor softmaxDescriptor 
)

Definition at line 17 of file SoftmaxOperator.cpp.

22 {
24  "ConvertSoftmaxToTosaOperator: Softmax currently only supports Int8 Quantized inputs");
25 
26  ARMNN_THROW_INVALIDARG_MSG_IF_FALSE(inputs.size() == 1,
27  "ConvertSoftmaxToTosaOperator: Softmax must have only one input");
28 
29  ARMNN_THROW_INVALIDARG_MSG_IF_FALSE(outputs.size() >= 1,
30  "ConvertSoftmaxToTosaOperator: Softmax must have at least one output");
31 
32  std::string inputName = std::string("input_");
33  std::string outputName = std::string("output0_");
34  std::string blockName = std::string("Op_SOFTMAX_block_") + GetUniqueTosaMappingID();
35 
36  std::string inputNameConst1 = std::string("intermediate_constant1_") + GetUniqueTosaMappingID();
37  std::string inputNameConst2 = std::string("intermediate_constant2_") + GetUniqueTosaMappingID();
38  std::string inputNameConst3 = std::string("intermediate_constant3_") + GetUniqueTosaMappingID();
39  std::string inputNameConst3a = std::string("intermediate_constant3a_") + GetUniqueTosaMappingID();
40  std::string inputNameConst4 = std::string("intermediate_constant4_") + GetUniqueTosaMappingID();
41  std::string inputNameConst5 = std::string("intermediate_constant5_") + GetUniqueTosaMappingID();
42  std::string inputNameConst6 = std::string("intermediate_constant6_") + GetUniqueTosaMappingID();
43  std::string inputNameConst7 = std::string("intermediate_constant7_") + GetUniqueTosaMappingID();
44  std::string inputNameConst8 = std::string("intermediate_constant8_") + GetUniqueTosaMappingID();
45  std::string inputNameConst8a = std::string("intermediate_constant8a_") + GetUniqueTosaMappingID();
46  std::string inputNameConst8b = std::string("intermediate_constant8b_") + GetUniqueTosaMappingID();
47  std::string inputNameConst9 = std::string("intermediate_constant9_") + GetUniqueTosaMappingID();
48  std::string inputNameConst9a = std::string("intermediate_constant9a_") + GetUniqueTosaMappingID();
49  std::string inputNameConst9b = std::string("intermediate_constant9b_") + GetUniqueTosaMappingID();
50  std::string inputNameConst10 = std::string("intermediate_constant10_") + GetUniqueTosaMappingID();
51 
52  std::string outputNameRescale1 = std::string("intermediate0_") + GetUniqueTosaMappingID();
53  std::string outputNameReduceMax1 = std::string("intermediate1_") + GetUniqueTosaMappingID();
54  std::string outputNameSub1 = std::string("intermediate2_") + GetUniqueTosaMappingID();
55  std::string outputNameRescale2 = std::string("intermediate3_") + GetUniqueTosaMappingID();
56  std::string outputNameTable1 = std::string("intermediate4_") + GetUniqueTosaMappingID();
57  std::string outputNameTable2 = std::string("intermediate5_") + GetUniqueTosaMappingID();
58  std::string outputNameTable3 = std::string("intermediate6_") + GetUniqueTosaMappingID();
59  std::string outputNameTable4 = std::string("intermediate7_") + GetUniqueTosaMappingID();
60  std::string outputNameLogicalL1 = std::string("intermediate8_") + GetUniqueTosaMappingID();
61  std::string outputNameLogicalL2 = std::string("intermediate9_") + GetUniqueTosaMappingID();
62  std::string outputNameLogicalL3 = std::string("intermediate10_") + GetUniqueTosaMappingID();
63  std::string outputNameArithmeticR1 = std::string("intermediate11_") + GetUniqueTosaMappingID();
64  std::string outputNameAdd1 = std::string("intermediate12_") + GetUniqueTosaMappingID();
65  std::string outputNameAdd2 = std::string("intermediate13_") + GetUniqueTosaMappingID();
66  std::string outputNameAdd3 = std::string("intermediate14_") + GetUniqueTosaMappingID();
67  std::string outputNameArithmeticR2 = std::string("intermediate15_") + GetUniqueTosaMappingID();
68  std::string outputNameReduceSum1 = std::string("intermediate16_") + GetUniqueTosaMappingID();
69  std::string outputNameCLZ1 = std::string("intermediate17_") + GetUniqueTosaMappingID();
70  std::string outputNameSub2 = std::string("intermediate18_") + GetUniqueTosaMappingID();
71  std::string outputNameLogicalL4 = std::string("intermediate19_") + GetUniqueTosaMappingID();
72  std::string outputNameMul1 = std::string("intermediate20_") + GetUniqueTosaMappingID();
73  std::string outputNameAdd4 = std::string("intermediate21_") + GetUniqueTosaMappingID();
74  std::string outputNameMul2 = std::string("intermediate22_") + GetUniqueTosaMappingID();
75  std::string outputNameSub3 = std::string("intermediate23_") + GetUniqueTosaMappingID();
76  std::string outputNameMul3 = std::string("intermediate24_") + GetUniqueTosaMappingID();
77  std::string outputNameMul4 = std::string("intermediate25_") + GetUniqueTosaMappingID();
78  std::string outputNameAdd5 = std::string("intermediate26_") + GetUniqueTosaMappingID();
79  std::string outputNameMul5 = std::string("intermediate27_") + GetUniqueTosaMappingID();
80  std::string outputNameSub4 = std::string("intermediate28_") + GetUniqueTosaMappingID();
81  std::string outputNameMul6 = std::string("intermediate29_") + GetUniqueTosaMappingID();
82  std::string outputNameMul7 = std::string("intermediate30_") + GetUniqueTosaMappingID();
83  std::string outputNameAdd6 = std::string("intermediate31_") + GetUniqueTosaMappingID();
84  std::string outputNameMul8 = std::string("intermediate32_") + GetUniqueTosaMappingID();
85  std::string outputNameSub5 = std::string("intermediate33_") + GetUniqueTosaMappingID();
86  std::string outputNameMul9 = std::string("intermediate34_") + GetUniqueTosaMappingID();
87  std::string outputNameMul10 = std::string("intermediate35_") + GetUniqueTosaMappingID();
88  std::string outputNameAdd7 = std::string("intermediate36_") + GetUniqueTosaMappingID();
89  std::string outputNameMul11 = std::string("intermediate37_") + GetUniqueTosaMappingID();
90  std::string outputNameSub6 = std::string("intermediate38_") + GetUniqueTosaMappingID();
91  std::string outputNameArithmeticR3 = std::string("intermediate39_") + GetUniqueTosaMappingID();
92 
93  // If a layer is present then the block will be used for execution, so input and output names need to be determined
94  // using the previous and following layers so the graph is connected correctly. For validation this doesn't matter.
95  if (layer != nullptr)
96  {
97  inputName = GenerateUniqueInputName(layer->GetInputSlot(0));
98  outputName = GenerateUniqueOutputName(*layer);
99  }
100 
101  const TensorInfo& inputInfo = *inputs[0];
102  const TensorInfo& outputInfo = *outputs[0];
103 
104  std::vector<TosaSerializationTensor *> tensors;
105  std::vector<TosaSerializationOperator *> operators;
106 
107  std::vector<int32_t> inputShape0 = GetTosaTensorShape(inputInfo.GetShape());
108  std::vector<int32_t> outputShape0 = GetTosaTensorShape(outputInfo.GetShape());
109 
110  DType inputDType0 = ArmNNToDType(inputInfo.GetDataType());
111  DType outputDType0 = ArmNNToDType(outputInfo.GetDataType());
112 
113  // Only add input tensors if connected layer is an input layer.
114  // As intermediate or constant tensors will be created separately.
115  // There also can't be duplicate tensor.
116  if (inputName.find("input_") != std::string::npos)
117  {
118  tensors.push_back(new TosaSerializationTensor(inputName, inputShape0, inputDType0, {}));
119  }
120 
121  float inScale = inputInfo.GetQuantizationScale();
122 
123  int32_t input_zp = inputInfo.GetQuantizationOffset();
124  int32_t output_zp = outputInfo.GetQuantizationOffset();
125 
126  std::vector<uint8_t> uint8Data;
127 
128  unsigned int rank = inputInfo.GetNumDimensions();
129  const std::vector<int32_t> singleValueShape(rank,1);
130  auto axis = static_cast<int32_t>(rank - 1);
131  TosaAxisAttribute tosaAxisAttribute(axis);
132 
133  // softmax calculations done using only the last tensor dimension
134  std::vector<int32_t> reduceShape = inputShape0;
135  reduceShape[static_cast<unsigned long>(axis)] = 1;
136 
137  TosaSerializationOperator *rescaleOp1 = nullptr;
138  CreateRescaleTosaOperator(inputName, outputNameRescale1, 1.0f, input_zp, 0,
139  false, false, false, true, &rescaleOp1);
140 
141  tensors.push_back(new TosaSerializationTensor(outputNameRescale1, inputShape0, DType_INT32, {}));
142  operators.push_back(rescaleOp1);
143 
144  auto *reduceMaxOp1 = new TosaSerializationOperator(Op_REDUCE_MAX,
145  Attribute_AxisAttribute,
146  &tosaAxisAttribute,
147  {outputNameRescale1},
148  {outputNameReduceMax1});
149  tensors.push_back(new TosaSerializationTensor(outputNameReduceMax1, reduceShape, DType_INT32, {}));
150  operators.push_back(reduceMaxOp1);
151 
152  auto *subOp1 = new TosaSerializationOperator(Op_SUB,
153  Attribute_NONE,
154  nullptr,
155  {outputNameRescale1, outputNameReduceMax1},
156  {outputNameSub1});
157  tensors.push_back(new TosaSerializationTensor(outputNameSub1, inputShape0, DType_INT32, {}));
158  operators.push_back(subOp1);
159 
160  TosaSerializationOperator *rescaleOp2 = nullptr;
161  CreateRescaleTosaOperator(outputNameSub1, outputNameRescale2, 128.0f, 0, 0, false, false, false, true, &rescaleOp2);
162  tensors.push_back(new TosaSerializationTensor(outputNameRescale2, inputShape0, DType_INT16, {}));
163  operators.push_back(rescaleOp2);
164 
165  std::array<std::vector <int16_t>, 4> lookupTables;
166  CalculateSoftmaxTableValues(softmaxDescriptor->m_Beta, inScale, lookupTables);
167 
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);
176 
177  TosaTableAttribute tosaTableAttribute1(table1);
178  TosaTableAttribute tosaTableAttribute2(table2);
179  TosaTableAttribute tosaTableAttribute3(table3);
180  TosaTableAttribute tosaTableAttribute4(table4);
181 
182  auto* tableOp1 = new TosaSerializationOperator(Op_TABLE,
183  Attribute_TableAttribute,
184  &tosaTableAttribute1,
185  {outputNameRescale2},
186  {outputNameTable1});
187  tensors.push_back(new TosaSerializationTensor(outputNameTable1, inputShape0, DType_INT32, {}));
188  operators.push_back(tableOp1);
189 
190  auto* tableOp2 = new TosaSerializationOperator(Op_TABLE,
191  Attribute_TableAttribute,
192  &tosaTableAttribute2,
193  {outputNameRescale2},
194  {outputNameTable2});
195  tensors.push_back(new TosaSerializationTensor(outputNameTable2, inputShape0, DType_INT32, {}));
196  operators.push_back(tableOp2);
197 
198  auto* tableOp3 = new TosaSerializationOperator(Op_TABLE,
199  Attribute_TableAttribute,
200  &tosaTableAttribute3,
201  {outputNameRescale2},
202  {outputNameTable3});
203  tensors.push_back(new TosaSerializationTensor(outputNameTable3, inputShape0, DType_INT32, {}));
204  operators.push_back(tableOp3);
205 
206  auto* tableOp4 = new TosaSerializationOperator(Op_TABLE,
207  Attribute_TableAttribute,
208  &tosaTableAttribute4,
209  {outputNameRescale2},
210  {outputNameTable4});
211  tensors.push_back(new TosaSerializationTensor(outputNameTable4, inputShape0, DType_INT32, {}));
212  operators.push_back(tableOp4);
213 
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}));
217 
218  auto* logicalLOp1 = new TosaSerializationOperator(Op_LOGICAL_LEFT_SHIFT,
219  Attribute_NONE,
220  nullptr,
221  {outputNameTable1, inputNameConst1},
222  {outputNameLogicalL1});
223  tensors.push_back(new TosaSerializationTensor(outputNameLogicalL1, inputShape0, DType_INT32, {}));
224  operators.push_back(logicalLOp1);
225 
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}));
229 
230  auto* logicalLOp2 = new TosaSerializationOperator(Op_LOGICAL_LEFT_SHIFT,
231  Attribute_NONE,
232  nullptr,
233  {outputNameTable2, inputNameConst2},
234  {outputNameLogicalL2});
235  tensors.push_back(new TosaSerializationTensor(outputNameLogicalL2, inputShape0, DType_INT32, {}));
236  operators.push_back(logicalLOp2);
237 
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}));
241 
242  auto* logicalLOp3 = new TosaSerializationOperator(Op_LOGICAL_LEFT_SHIFT,
243  Attribute_NONE,
244  nullptr,
245  {outputNameTable3, inputNameConst3},
246  {outputNameLogicalL3});
247  tensors.push_back(new TosaSerializationTensor(outputNameLogicalL3, inputShape0, DType_INT32, {}));
248  operators.push_back(logicalLOp3);
249 
250  bool rounding = true;
251  TosaArithmeticRightShiftAttribute shiftRAttribute(rounding);
252 
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}));
256 
257  auto* arithmeticROp1 = new TosaSerializationOperator(Op_ARITHMETIC_RIGHT_SHIFT,
258  Attribute_ArithmeticRightShiftAttribute,
259  &shiftRAttribute,
260  {outputNameTable4, inputNameConst4},
261  {outputNameArithmeticR1});
262  tensors.push_back(new TosaSerializationTensor(outputNameArithmeticR1, inputShape0, DType_INT32, {}));
263  operators.push_back(arithmeticROp1);
264 
265  auto* addOp1 = new TosaSerializationOperator(Op_ADD,
266  Attribute_NONE,
267  nullptr,
268  {outputNameLogicalL1, outputNameLogicalL2},
269  {outputNameAdd1});
270  tensors.push_back(new TosaSerializationTensor(outputNameAdd1, inputShape0, DType_INT32, {}));
271  operators.push_back(addOp1);
272 
273  auto* addOp2 = new TosaSerializationOperator(Op_ADD,
274  Attribute_NONE,
275  nullptr,
276  {outputNameAdd1, outputNameLogicalL3},
277  {outputNameAdd2});
278  tensors.push_back(new TosaSerializationTensor(outputNameAdd2, inputShape0, DType_INT32, {}));
279  operators.push_back(addOp2);
280 
281  auto* addOp3 = new TosaSerializationOperator(Op_ADD,
282  Attribute_NONE,
283  nullptr,
284  {outputNameAdd2, outputNameArithmeticR1},
285  {outputNameAdd3});
286  tensors.push_back(new TosaSerializationTensor(outputNameAdd3, inputShape0, DType_INT32, {}));
287  operators.push_back(addOp3);
288 
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}));
292 
293  auto* arithmeticROp2 = new TosaSerializationOperator(Op_ARITHMETIC_RIGHT_SHIFT,
294  Attribute_ArithmeticRightShiftAttribute,
295  &shiftRAttribute,
296  {outputNameAdd3, inputNameConst5},
297  {outputNameArithmeticR2});
298  tensors.push_back(new TosaSerializationTensor(outputNameArithmeticR2, inputShape0, DType_INT32, {}));
299  operators.push_back(arithmeticROp2);
300 
301  auto* reduceSumOp1 = new TosaSerializationOperator(Op_REDUCE_SUM,
302  Attribute_AxisAttribute,
303  &tosaAxisAttribute,
304  {outputNameArithmeticR2},
305  {outputNameReduceSum1});
306  tensors.push_back(new TosaSerializationTensor(outputNameReduceSum1, reduceShape, DType_INT32, {}));
307  operators.push_back(reduceSumOp1);
308 
309  auto* countLeadingZeroOp1 = new TosaSerializationOperator(Op_CLZ,
310  Attribute_NONE,
311  nullptr,
312  {outputNameReduceSum1},
313  {outputNameCLZ1});
314  tensors.push_back(new TosaSerializationTensor(outputNameCLZ1, reduceShape, DType_INT32, {}));
315  operators.push_back(countLeadingZeroOp1);
316 
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}));
320 
321  auto* subOp2 = new TosaSerializationOperator(Op_SUB,
322  Attribute_NONE,
323  nullptr,
324  {outputNameCLZ1, inputNameConst3a},
325  {outputNameSub2});
326  tensors.push_back(new TosaSerializationTensor(outputNameSub2, reduceShape, DType_INT32, {}));
327  operators.push_back(subOp2);
328 
329  // half_denominator
330  auto* logicalLOp4 = new TosaSerializationOperator(Op_LOGICAL_LEFT_SHIFT,
331  Attribute_NONE,
332  nullptr,
333  {outputNameReduceSum1, outputNameSub2},
334  {outputNameLogicalL4});
335  tensors.push_back(new TosaSerializationTensor(outputNameLogicalL4, reduceShape, DType_INT32, {}));
336  operators.push_back(logicalLOp4);
337 
338  TosaMulAttribute mulAttribute1(31);
339 
340  TosaSerializationHandler::ConvertI32toU8({-1010580540}, uint8Data); // constant_neg_32_over_17
341  tensors.push_back(new TosaSerializationTensor(inputNameConst6, singleValueShape, DType_INT32,uint8Data));
342  operators.push_back(new TosaSerializationOperator(Op_CONST, Attribute_NONE, nullptr, {}, {inputNameConst6}));
343 
344  // mul_half_denominator
345  auto* mulOp1 = new TosaSerializationOperator(Op_MUL,
346  Attribute_MulAttribute,
347  &mulAttribute1,
348  {outputNameLogicalL4, inputNameConst6},
349  {outputNameMul1});
350  tensors.push_back(new TosaSerializationTensor(outputNameMul1, reduceShape, DType_INT32, {}));
351  operators.push_back(mulOp1);
352 
353  TosaSerializationHandler::ConvertI32toU8({1515870810}, uint8Data); // constant_48_over_17
354  tensors.push_back(new TosaSerializationTensor(inputNameConst7, singleValueShape, DType_INT32,uint8Data));
355  operators.push_back(new TosaSerializationOperator(Op_CONST, Attribute_NONE, nullptr, {}, {inputNameConst7}));
356 
357  // nr_x
358  auto* addOp4 = new TosaSerializationOperator(Op_ADD,
359  Attribute_NONE,
360  nullptr,
361  {outputNameMul1, inputNameConst7},
362  {outputNameAdd4});
363  tensors.push_back(new TosaSerializationTensor(outputNameAdd4, reduceShape, DType_INT32, {}));
364  operators.push_back(addOp4);
365 
366  // Newton-Raphson 3 iterations of MUL SUB MUL MUL ADD sequence
367  auto* mulOp2 = new TosaSerializationOperator(Op_MUL,
368  Attribute_MulAttribute,
369  &mulAttribute1,
370  {outputNameAdd4, outputNameLogicalL4},
371  {outputNameMul2});
372  tensors.push_back(new TosaSerializationTensor(outputNameMul2, reduceShape, DType_INT32, {}));
373  operators.push_back(mulOp2);
374 
375  TosaSerializationHandler::ConvertI32toU8({536870912}, uint8Data); // F2_one constant
376  tensors.push_back(new TosaSerializationTensor(inputNameConst8, singleValueShape, DType_INT32,uint8Data));
377  operators.push_back(new TosaSerializationOperator(Op_CONST, Attribute_NONE, nullptr, {}, {inputNameConst8}));
378 
379  auto* subOp3 = new TosaSerializationOperator(Op_SUB,
380  Attribute_NONE,
381  nullptr,
382  {inputNameConst8, outputNameMul2},
383  {outputNameSub3});
384  tensors.push_back(new TosaSerializationTensor(outputNameSub3, reduceShape, DType_INT32, {}));
385  operators.push_back(subOp3);
386 
387  auto* mulOp3 = new TosaSerializationOperator(Op_MUL,
388  Attribute_MulAttribute,
389  &mulAttribute1,
390  {outputNameAdd4, outputNameSub3},
391  {outputNameMul3});
392  tensors.push_back(new TosaSerializationTensor(outputNameMul3, reduceShape, DType_INT32, {}));
393  operators.push_back(mulOp3);
394 
395  TosaMulAttribute mulAttribute2(0);
396 
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}));
400 
401  auto* mulOp4 = new TosaSerializationOperator(Op_MUL,
402  Attribute_MulAttribute,
403  &mulAttribute2,
404  {outputNameMul3, inputNameConst9},
405  {outputNameMul4});
406  tensors.push_back(new TosaSerializationTensor(outputNameMul4, reduceShape, DType_INT32, {}));
407  operators.push_back(mulOp4);
408 
409  auto* addOp5 = new TosaSerializationOperator(Op_ADD,
410  Attribute_NONE,
411  nullptr,
412  {outputNameAdd4, outputNameMul4},
413  {outputNameAdd5});
414  tensors.push_back(new TosaSerializationTensor(outputNameAdd5, reduceShape, DType_INT32, {}));
415  operators.push_back(addOp5);
416 
417  // Newton-Raphson 2nd iteration... nr_x = op25_add_x_op24.getResult();
418  auto* mulOp5 = new TosaSerializationOperator(Op_MUL,
419  Attribute_MulAttribute,
420  &mulAttribute1,
421  {outputNameAdd5, outputNameLogicalL4},
422  {outputNameMul5});
423  tensors.push_back(new TosaSerializationTensor(outputNameMul5, reduceShape, DType_INT32, {}));
424  operators.push_back(mulOp5);
425 
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}));
429 
430  auto* subOp4 = new TosaSerializationOperator(Op_SUB,
431  Attribute_NONE,
432  nullptr,
433  {inputNameConst8a, outputNameMul5},
434  {outputNameSub4});
435  tensors.push_back(new TosaSerializationTensor(outputNameSub4, reduceShape, DType_INT32, {}));
436  operators.push_back(subOp4);
437 
438  auto* mulOp6 = new TosaSerializationOperator(Op_MUL,
439  Attribute_MulAttribute,
440  &mulAttribute1,
441  {outputNameAdd5, outputNameSub4},
442  {outputNameMul6});
443  tensors.push_back(new TosaSerializationTensor(outputNameMul6, reduceShape, DType_INT32, {}));
444  operators.push_back(mulOp6);
445 
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}));
449 
450  auto* mulOp7 = new TosaSerializationOperator(Op_MUL,
451  Attribute_MulAttribute,
452  &mulAttribute2,
453  {outputNameMul6, inputNameConst9a},
454  {outputNameMul7});
455  tensors.push_back(new TosaSerializationTensor(outputNameMul7, reduceShape, DType_INT32, {}));
456  operators.push_back(mulOp7);
457 
458  auto* addOp6 = new TosaSerializationOperator(Op_ADD,
459  Attribute_NONE,
460  nullptr,
461  {outputNameAdd5, outputNameMul7},
462  {outputNameAdd6});
463  tensors.push_back(new TosaSerializationTensor(outputNameAdd6, reduceShape, DType_INT32, {}));
464  operators.push_back(addOp6);
465 
466  // Newton-Raphson 3rd iteration... nr_x = op25_add_x_op24.getResult();
467  auto* mulOp8 = new TosaSerializationOperator(Op_MUL,
468  Attribute_MulAttribute,
469  &mulAttribute1,
470  {outputNameAdd6, outputNameLogicalL4},
471  {outputNameMul8});
472  tensors.push_back(new TosaSerializationTensor(outputNameMul8, reduceShape, DType_INT32, {}));
473  operators.push_back(mulOp8);
474 
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}));
478 
479  auto* subOp5 = new TosaSerializationOperator(Op_SUB,
480  Attribute_NONE,
481  nullptr,
482  {inputNameConst8b, outputNameMul8},
483  {outputNameSub5});
484  tensors.push_back(new TosaSerializationTensor(outputNameSub5, reduceShape, DType_INT32, {}));
485  operators.push_back(subOp5);
486 
487  auto* mulOp9 = new TosaSerializationOperator(Op_MUL,
488  Attribute_MulAttribute,
489  &mulAttribute1,
490  {outputNameAdd6, outputNameSub5},
491  {outputNameMul9});
492  tensors.push_back(new TosaSerializationTensor(outputNameMul9, reduceShape, DType_INT32, {}));
493  operators.push_back(mulOp9);
494 
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}));
498 
499  auto* mulOp10 = new TosaSerializationOperator(Op_MUL,
500  Attribute_MulAttribute,
501  &mulAttribute2,
502  {outputNameMul9, inputNameConst9b},
503  {outputNameMul10});
504  tensors.push_back(new TosaSerializationTensor(outputNameMul10, reduceShape, DType_INT32, {}));
505  operators.push_back(mulOp10);
506 
507  auto* addOp7 = new TosaSerializationOperator(Op_ADD,
508  Attribute_NONE,
509  nullptr,
510  {outputNameAdd6, outputNameMul10},
511  {outputNameAdd7});
512  tensors.push_back(new TosaSerializationTensor(outputNameAdd7, reduceShape, DType_INT32, {}));
513  operators.push_back(addOp7);
514 
515  TosaMulAttribute mulAttribute3(30);
516 
517  auto* mulOp11 = new TosaSerializationOperator(Op_MUL,
518  Attribute_MulAttribute,
519  &mulAttribute3,
520  {outputNameAdd3, outputNameAdd7},
521  {outputNameMul11});
522  tensors.push_back(new TosaSerializationTensor(outputNameMul11, outputShape0, DType_INT32, {}));
523  operators.push_back(mulOp11);
524 
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}));
528 
529  auto* subOp6 = new TosaSerializationOperator(Op_SUB,
530  Attribute_NONE,
531  nullptr,
532  {inputNameConst10, outputNameCLZ1},
533  {outputNameSub6});
534  tensors.push_back(new TosaSerializationTensor(outputNameSub6, reduceShape, DType_INT32, {}));
535  operators.push_back(subOp6);
536 
537  auto* arithmeticROp3 = new TosaSerializationOperator(Op_ARITHMETIC_RIGHT_SHIFT,
538  Attribute_ArithmeticRightShiftAttribute,
539  &shiftRAttribute,
540  {outputNameMul11, outputNameSub6},
541  {outputNameArithmeticR3});
542  tensors.push_back(new TosaSerializationTensor(outputNameArithmeticR3, outputShape0, DType_INT32, {}));
543  operators.push_back(arithmeticROp3);
544 
545  TosaSerializationOperator* rescaleOp3 = nullptr;
546  CreateRescaleTosaOperator(outputNameArithmeticR3, outputName, 1.0f, 0, output_zp, false, false,
547  false, true, &rescaleOp3);
548 
549  tensors.push_back(new TosaSerializationTensor(outputName, outputShape0, outputDType0, {}));
550  operators.push_back(rescaleOp3);
551 
552  return new TosaSerializationBasicBlock(blockName,
553  mainName,
554  {operators},
555  tensors,
556  {inputName},
557  {outputName});
558 }
#define ARMNN_THROW_INVALIDARG_MSG_IF_FALSE(_cond, _str)
Definition: Exceptions.hpp:210
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.
Definition: Layer.hpp:337
float GetQuantizationScale() const
Definition: Tensor.cpp:461
unsigned int GetNumDimensions() const
Definition: Tensor.hpp:197
int32_t GetQuantizationOffset() const
Definition: Tensor.cpp:482
const TensorShape & GetShape() const
Definition: Tensor.hpp:193
DataType GetDataType() const
Definition: Tensor.hpp:200
constexpr bool IsQuantized8BitType(DataType dataType)
Definition: TypesUtils.hpp:317
float m_Beta
Exponentiation value.

References ARMNN_THROW_INVALIDARG_MSG_IF_FALSE, ArmNNToDType(), CalculateSoftmaxTableValues(), CreateRescaleTosaOperator(), GenerateUniqueInputName(), GenerateUniqueOutputName(), TensorInfo::GetDataType(), Layer::GetInputSlot(), TensorInfo::GetNumDimensions(), TensorInfo::GetQuantizationOffset(), TensorInfo::GetQuantizationScale(), TensorInfo::GetShape(), GetTosaTensorShape(), GetUniqueTosaMappingID(), armnn::IsQuantized8BitType(), SoftmaxDescriptor::m_Beta, and mainName.

Referenced by GetTosaMapping().