33 const std::string& outputName,
34 const std::vector<int32_t>& multipliers,
35 const std::vector<int32_t>& shifts,
43 TosaSerializationOperator** op)
50 if (multipliers.empty())
52 throw armnn::Exception(
"CreateRawRescaleTosaOperator: multipliers is empty.");
55 if (multipliers.size() != shifts.size())
57 throw armnn::Exception(
"CreateRawRescaleTosaOperator: multipliers and shift not same size.");
60 if (multipliers.size() == 1 && per_channel)
63 multipliers must be greater than 1 if per_channel is true.");
66 if (multipliers.size() > 1 && !per_channel)
69 multipliers size must be 1 if per_channel is false.");
72 TosaRescaleAttribute attribute(input_zp,
83 *op =
new TosaSerializationOperator(Op_RESCALE, Attribute_RescaleAttribute, &attribute, {inputName}, {outputName});
86 throw armnn::Exception(
"CreateRescaleTosaOperator: failed to created operator");
98 const double mantissa = std::frexp(scale, &shift);
99 auto shiftedM = std::round(mantissa * (int64_t(1) << 31));
102 if (!(shiftedM <= (int64_t(1) << 31)))
107 if (shiftedM == (int64_t(1) << 31))
115 shift = (-shift) + 31;
117 if (!(shiftedM <= std::numeric_limits<int32_t>::max()))
119 throw armnn::Exception(
"Shifted mantissa exceeds 32-bit signed output type");
122 multiplier =
static_cast<int32_t
>(shiftedM);
125 int32_t maxShiftValue = 47;
126 if (shift > maxShiftValue)
128 multiplier = multiplier >> std::min<int32_t>(31, shift - maxShiftValue);
129 shift = maxShiftValue;
141 const double mantissa = std::frexp(scale, &shift);
142 auto shiftedM = std::round(mantissa * (int64_t(1) << 15));
145 if (!(shiftedM <= (int64_t(1) << 15)))
150 if (shiftedM == (int64_t(1) << 15))
158 shift = (-shift) + 15;
160 if (!(shiftedM <= std::numeric_limits<int32_t>::max()))
162 throw armnn::Exception(
"Shifted mantissa exceeds 32-bit signed output type");
165 multiplier =
static_cast<int32_t
>(shiftedM);
173 multiplier = multiplier >> std::min<int32_t>(31, shift - 62);
198 const std::string& outputName,
203 bool output_unsigned,
206 TosaSerializationOperator** op)
220 const std::vector<int32_t> multipliers{multiplier};
221 const std::vector<int32_t> shifts{shift};
259 const std::string& outputName,
263 bool output_unsigned,
268 const std::vector<float>& weight_scales,
269 TosaSerializationOperator** op)
271 std::vector<int32_t> op_tensor_multipliers;
272 std::vector<int32_t> op_tensor_shifts;
273 op_tensor_multipliers.reserve(weight_scales.size());
274 op_tensor_shifts.reserve(weight_scales.size());
276 for (
const float& weight_scale : weight_scales)
278 double op_tensor_scale = (input_scale * weight_scale) / output_scale;
291 op_tensor_multipliers.push_back(multiplier);
292 op_tensor_shifts.push_back(shift);
295 bool per_channel = weight_scales.size() == 1 ? false :
true;
298 op_tensor_multipliers,
void ComputeMultiplierAndShiftTosaScale16(double scale, int32_t &multiplier, int32_t &shift)
The following is taken from mlir/lib/Dialect/Tosa/Utils/QuantUtils.cpp in the LLVM project From a sca...
void CreateRawRescaleTosaOperator(const std::string &inputName, const std::string &outputName, const std::vector< int32_t > &multipliers, const std::vector< int32_t > &shifts, int32_t input_zp, int32_t output_zp, bool input_unsigned, bool output_unsigned, bool double_round, bool scale32, bool per_channel, TosaSerializationOperator **op)
Creates a raw rescale TOSA operator.
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.
void ComputeMultiplierAndShiftTosaScale32(double scale, int32_t &multiplier, int32_t &shift)
The following is taken from mlir/lib/Dialect/Tosa/Utils/QuantUtils.cpp in the LLVM project From a sca...
void CreateRescaleTosaOperatorForWeights(const std::string &inputName, const std::string &outputName, int32_t input_zp, int32_t output_zp, bool input_unsigned, bool output_unsigned, bool double_round, bool scale32, double input_scale, double output_scale, const std::vector< float > &weight_scales, TosaSerializationOperator **op)
Creates a TOSA rescale operator for weight tensors.
Base class for all ArmNN exceptions so that users can filter to just those.