ArmNN
 25.02
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
DequantizeOperator.hpp File Reference
Include dependency graph for DequantizeOperator.hpp:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

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

Function Documentation

◆ ConvertDequantizeToTosaOperator()

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

Definition at line 8 of file DequantizeOperator.cpp.

12 {
13  if (inputs.size() != 1)
14  {
15  throw Exception("ConvertDequantizeToTosaOperator: 1 input tensors required.");
16  }
17 
18  if (outputs.size() != 1)
19  {
20  throw Exception("ConvertDequantizeToTosaOperator: 1 output tensor required.");
21  }
22 
23  if (inputs[0]->HasPerAxisQuantization())
24  {
25  throw Exception("ConvertDequantizeToTosaOperator: Per axis quantization not currently supported.");
26  }
27 
28  std::string inputName = std::string("input_");
29  std::string outputName = std::string("output_");
30  std::string blockName = std::string("Op_DEQUANTIZE_block_") + GetUniqueTosaMappingID();
31 
32  // If a layer is present then the block will be used for execution, so input and output names need to be determined
33  // using the previous and following layers so the graph is connected correctly. For validation this doesn't matter.
34  if (layer != nullptr)
35  {
36  inputName = GenerateUniqueInputName(layer->GetInputSlot(0));
37  outputName = GenerateUniqueOutputName(*layer);
38  }
39 
40  std::vector<TosaSerializationTensor*> tensors;
41  std::vector<TosaSerializationOperator*> operators;
42 
43  DataType inputDType = inputs[0]->GetDataType();
44  DataType outputDType = outputs[0]->GetDataType();
45  std::vector<int32_t> inputShape = GetTosaTensorShape(inputs[0]->GetShape());
46  std::vector<int32_t> outputShape = GetTosaTensorShape(outputs[0]->GetShape());
47 
48  // Only add input tensors if connected layer is an input layer.
49  // As intermediate or constant tensors will be created separately.
50  // There also can't be duplicate tensor.
51  if(inputName.find("input_") != std::string::npos)
52  {
53  tensors.push_back(new TosaSerializationTensor(inputName, inputShape, ArmNNToDType(inputDType), {}));
54  }
55 
56  if (inputDType == DataType::Float16 ||
57  inputDType == DataType::Float32)
58  {
59  operators.push_back(new TosaSerializationOperator(tosa::Op_CAST,
60  Attribute_NONE,
61  nullptr,
62  {inputName},
63  {outputName}));
64  }
65  else if (inputDType == DataType::QAsymmS8 ||
66  inputDType == DataType::QSymmS16 ||
67  inputDType == DataType::QSymmS8)
68  {
69  std::string outputNameCast = std::string("intermediate0_") + GetUniqueTosaMappingID();
70  std::string outputNameZeroPoint = std::string("constant0_") + GetUniqueTosaMappingID();
71  std::string outputNameSub = std::string("intermediate2_") + GetUniqueTosaMappingID();
72  std::string outputNameScale = std::string("constant1_") + GetUniqueTosaMappingID();
73 
74  float zeroPoint = static_cast<float>(inputs[0]->GetQuantizationOffset());
75  float scale = inputs[0]->GetQuantizationScale();
76 
77  // cast
78  TosaSerializationOperator* castOp = new TosaSerializationOperator(Op_CAST,
79  Attribute_NONE,
80  nullptr,
81  {inputName},
82  {outputNameCast});
83  operators.push_back(castOp);
84  tensors.push_back(new TosaSerializationTensor(outputNameCast, outputShape, ArmNNToDType(outputDType), {}));
85 
86  // const_zeroPoint
87  TosaSerializationOperator* zeroPointOp = nullptr;
88  TosaSerializationTensor* zeroPointTensor = nullptr;
89  CreateConstTosaOperator<float>(outputNameZeroPoint,
90  zeroPoint,
91  ArmNNToDType(outputDType),
92  inputShape,
93  zeroPointOp,
94  zeroPointTensor);
95  operators.push_back(zeroPointOp);
96  tensors.push_back(zeroPointTensor);
97 
98  // sub
99  TosaSerializationOperator* subOp = new TosaSerializationOperator(Op_SUB,
100  Attribute_NONE,
101  nullptr,
102  {outputNameCast, outputNameZeroPoint},
103  {outputNameSub});
104  operators.push_back(subOp);
105  tensors.push_back(new TosaSerializationTensor(outputNameSub, outputShape, ArmNNToDType(outputDType), {}));
106 
107  // const_scale
108  TosaSerializationOperator *scaleOp = nullptr;
109  TosaSerializationTensor* scaleTensor = nullptr;
110  CreateConstTosaOperator<float>(outputNameScale,
111  scale,
112  ArmNNToDType(outputDType),
113  inputShape,
114  scaleOp,
115  scaleTensor);
116  operators.push_back(scaleOp);
117  tensors.push_back(scaleTensor);
118 
119  // mul
120  int32_t shift = 0;
121  TosaMulAttribute mulAttribute(shift);
122  TosaSerializationOperator* mulOp = new TosaSerializationOperator(Op_MUL,
123  Attribute_MulAttribute,
124  &mulAttribute,
125  {outputNameSub, outputNameScale},
126  {outputName});
127  operators.push_back(mulOp);
128  }
129  else
130  {
131  throw armnn::Exception("ConvertDequantizeToTosaOperator: Unsupported datatype."
132  " Only floating-point and signed quantized datatypes are supported.");
133  }
134 
135  tensors.push_back(new TosaSerializationTensor(outputName, outputShape, ArmNNToDType(outputDType), {}));
136 
137  // operatorInputNames/operatorOutputNames ends up being the same as
138  // blockInputNames/blockOutputNames for one-to-one ArmNN to Tosa mappings
139  return new TosaSerializationBasicBlock(blockName, // name
140  mainName, // region name
141  operators, // operators
142  tensors, // tensors
143  {inputName}, // inputs
144  {outputName}); // outputs
145 }
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()
Base class for all ArmNN exceptions so that users can filter to just those.
Definition: Exceptions.hpp:47
const InputSlot & GetInputSlot(unsigned int index) const override
Get a const input slot handle by slot index.
Definition: Layer.hpp:337
DataType
Definition: Types.hpp:49

References GenerateUniqueInputName(), GenerateUniqueOutputName(), Layer::GetInputSlot(), GetTosaTensorShape(), and GetUniqueTosaMappingID().

Referenced by GetTosaMapping().