20{
21 bool tosaRefBackend {false};
22
24 "ConvertQuantizeToTosaOperator: Quantize must have only one input" );
26 "ConvertQuantizeToTosaOperator: Quantize must have only one output" );
27
28 std::string inputName = std::string("input_");
29 std::string outputName = std::string("output0_");
31
32
33
34 if(layer != nullptr)
35 {
38
39 tosaRefBackend = (layer->
GetBackendId().Get().find(
"TosaRef") != std::string::npos);
40 }
41
44
45
47
49
50
51
52
53
54 scale = (scale != 0) ? (1 / scale) : scale;
55
56 std::vector<TosaSerializationTensor*> tensors;
57
60 bool isFloatInput = inputDType0 == DType::DType_FP16 || inputDType0 == DType::DType_FP32;
61
62
63
64
65 if(inputName.find("input_") != std::string::npos)
66 {
67 DType tmp = inputDType0;
68
70 {
71
72
74 }
75 tensors.push_back(new TosaSerializationTensor(inputName, inputShape0, tmp, {}));
76 }
77 else
78 {
80 {
81
82 throw armnn::Exception(fmt::format(
"ConvertQuantizeToTosaOperator: {} intermediate input"
83 " layer not supported.",EnumNamesDType()[inputDType0]));
84 }
85 }
86
89
90 if (isFloatInput)
91 {
92
93
94
95
96
97
98
103
104
105 TosaSerializationOperator* zeroPointOp = nullptr;
106 TosaSerializationTensor* zeroPointTensor = nullptr;
108 zeroPoint,
109 inputDType0,
110 inputShape0,
111 zeroPointOp,
112 zeroPointTensor);
113 tensors.push_back(zeroPointTensor);
114
115
116 TosaSerializationOperator* scaleOp = nullptr;
117 TosaSerializationTensor* scaleTensor = nullptr;
119 scale,
120 inputDType0,
121 inputShape0,
122 scaleOp,
123 scaleTensor);
124 tensors.push_back(scaleTensor);
125
126
127 int32_t shift = 0;
128 TosaMulAttribute mulAttribute(shift);
129 TosaSerializationOperator* mulOp = new TosaSerializationOperator(Op_MUL,
130 Attribute_MulAttribute,
131 &mulAttribute,
132 {inputName, outputNameScale},
133 {outputNameMul});
134 tensors.push_back(new TosaSerializationTensor(outputNameMul, inputShape0, inputDType0, {}));
135
136
137 TosaSerializationOperator* addOp = new TosaSerializationOperator(Op_ADD,
138 Attribute_NONE,
139 nullptr,
140 {outputNameMul, outputNameZeroPoint},
141 {outputNameAdd});
142 tensors.push_back(new TosaSerializationTensor(outputNameAdd, inputShape0, inputDType0, {}));
143
144
145 TosaSerializationOperator* castOp = new TosaSerializationOperator(Op_CAST,
146 Attribute_NONE,
147 nullptr,
148 {outputNameAdd},
149 {outputName});
150
151 tensors.push_back(new TosaSerializationTensor(outputName, outputShape0, outputDType0, {}));
152
153
154
155 return new TosaSerializationBasicBlock(blockName,
157 {zeroPointOp, scaleOp, mulOp, addOp, castOp},
158 tensors,
159 {inputName},
160 {outputName});
161 }
162 else
163 {
164 double scale_alpha = inputs[0]->GetQuantizationScale() / outputs[0]->GetQuantizationScale();
165 int32_t input_zp = inputs[0]->GetQuantizationOffset();
166 int32_t output_zp = outputs[0]->GetQuantizationOffset();
167
168 TosaSerializationOperator* rescaleOp = nullptr;
170 outputName,
171 scale_alpha,
172 input_zp,
173 output_zp,
176 true,
177 true,
178 &rescaleOp);
179
181 {
182
183
185 }
186
187 tensors.push_back(new TosaSerializationTensor(outputName,
188 inputShape0,
189 outputDType0, {}));
190
191
192
193 return new TosaSerializationBasicBlock(blockName,
195 {rescaleOp},
196 tensors,
197 {inputName},
198 {outputName});
199 }
200}
#define ARMNN_THROW_INVALIDARG_MSG_IF_FALSE(_cond, _str)
std::string GenerateUniqueOutputName(const Layer &layer, uint32_t layerSlot=0)
const std::string mainName
bool IsUnsignedDataType(DType type)
DType ArmNNToDType(const DataType &type)
std::string GenerateUniqueInputName(const armnn::InputSlot &slot)
std::string GetUniqueTosaMappingID()
void FlipSignage(DType &type)
std::vector< int32_t > GetTosaTensorShape(const TensorShape &shape)
void CreateConstTosaOperator(const std::string &outputName, const T value, DType dtype, const std::vector< int32_t > &shape, TosaSerializationOperator *&op, TosaSerializationTensor *&tensor)
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)
Creates a Tosa rescale operator.
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.
const BackendId & GetBackendId() const
float GetQuantizationScale() const
const TensorShape & GetShape() const
int32_t GetQuantizationOffset() const
DataType GetDataType() const