11 const std::string& outputName,
12 const std::vector<int32_t>& multipliers,
13 const std::vector<int32_t>& shifts,
19 TosaSerializationOperator** op)
26 TosaRescaleAttribute attribute(input_zp,
37 *op =
new TosaSerializationOperator(Op_RESCALE, Attribute_RescaleAttribute, &attribute, {inputName}, {outputName});
40 throw armnn::Exception(
"CreateRescaleTosaOperator: failed to created operator");
45 const std::string& outputName,
46 int32_t scale_multiplier,
53 TosaSerializationOperator** op)
55 const std::vector<int32_t> multipliers{scale_multiplier};
56 const std::vector<int32_t> shifts{scale_shift};
58 input_zp, output_zp, double_round, scale32, per_channel, op);
65 static void ComputeMultiplierAndShiftTosaScale32(
double scale,
69 const double mantissa = std::frexp(scale, &shift);
70 auto shiftedM = std::round(mantissa * (int64_t(1) << 31));
73 if (!(shiftedM <= (int64_t(1) << 31)))
78 if (shiftedM == (int64_t(1) << 31))
86 shift = (-shift) + 31;
88 if (!(shiftedM <= std::numeric_limits<int32_t>::max()))
90 throw armnn::Exception(
"Shifted mantissa exceeds 32-bit signed output type");
93 multiplier =
static_cast<int32_t
>(shiftedM);
101 multiplier = multiplier >> std::min<int32_t>(31, shift - 62);
110 static void ComputeMultiplierAndShiftTosaScale16(
double scale,
114 const double mantissa = std::frexp(scale, &shift);
115 auto shiftedM = std::round(mantissa * (int64_t(1) << 15));
118 if (!(shiftedM <= (int64_t(1) << 15)))
123 if (shiftedM == (int64_t(1) << 15))
131 shift = (-shift) + 15;
133 if (!(shiftedM <= std::numeric_limits<int32_t>::max()))
135 throw armnn::Exception(
"Shifted mantissa exceeds 32-bit signed output type");
138 multiplier =
static_cast<int32_t
>(shiftedM);
146 multiplier = multiplier >> std::min<int32_t>(31, shift - 62);
152 const std::string& outputName,
158 TosaSerializationOperator** op)
165 ComputeMultiplierAndShiftTosaScale32(scale, multiplier, shift);
169 ComputeMultiplierAndShiftTosaScale16(scale, multiplier, shift);
173 input_zp, output_zp, double_round, scale32,
false, op);
177 const std::string& outputName,
184 const std::vector<float>& weight_scales,
185 TosaSerializationOperator** op)
187 std::vector<int32_t> op_tensor_multipliers;
188 std::vector<int32_t> op_tensor_shifts;
189 op_tensor_multipliers.reserve(weight_scales.size());
190 op_tensor_shifts.reserve(weight_scales.size());
192 for (
const float& weight_scale : weight_scales)
194 double op_tensor_scale = (input_scale * weight_scale) / output_scale;
200 ComputeMultiplierAndShiftTosaScale32(op_tensor_scale, multiplier, shift);
204 ComputeMultiplierAndShiftTosaScale16(op_tensor_scale, multiplier, shift);
207 op_tensor_multipliers.push_back(multiplier);
208 op_tensor_shifts.push_back(shift);
211 bool per_channel = weight_scales.size() == 1 ? false :
true;
213 input_zp, output_zp, double_round, scale32, per_channel, op);
217 const std::string& outputName,
220 TosaSerializationOperator** op)
223 0, output_zp,
true,
true, op);