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_");
31
32
33
34 if (layer != nullptr)
35 {
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();
47
48
49
50
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 {
73
74 float zeroPoint = static_cast<float>(inputs[0]->GetQuantizationOffset());
75 float scale = inputs[0]->GetQuantizationScale();
76
77
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
87 TosaSerializationOperator* zeroPointOp = nullptr;
88 TosaSerializationTensor* zeroPointTensor = nullptr;
90 zeroPoint,
92 inputShape,
93 zeroPointOp,
94 zeroPointTensor);
95 operators.push_back(zeroPointOp);
96 tensors.push_back(zeroPointTensor);
97
98
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
108 TosaSerializationOperator *scaleOp = nullptr;
109 TosaSerializationTensor* scaleTensor = nullptr;
111 scale,
113 inputShape,
114 scaleOp,
115 scaleTensor);
116 operators.push_back(scaleOp);
117 tensors.push_back(scaleTensor);
118
119
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
138
139 return new TosaSerializationBasicBlock(blockName,
141 operators,
142 tensors,
143 {inputName},
144 {outputName});
145}
std::string GenerateUniqueOutputName(const Layer &layer, uint32_t layerSlot=0)
const std::string mainName
DType ArmNNToDType(const DataType &type)
std::string GenerateUniqueInputName(const armnn::InputSlot &slot)
std::string GetUniqueTosaMappingID()
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)
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.