ArmNN
 24.11
TosaRescaleOperatorUtils.hpp File Reference
Include dependency graph for TosaRescaleOperatorUtils.hpp:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

void CreateRescaleTosaOperator (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 double_round, bool scale32, bool per_channel, TosaSerializationOperator **op)
 
void CreateRescaleTosaOperator (const std::string &inputName, const std::string &outputName, int32_t scale_multiplier, int32_t scale_shift, int32_t input_zp, int32_t output_zp, bool double_round, bool scale32, bool per_channel, TosaSerializationOperator **op)
 
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 scale value, generates multiplier and shift values where mantissa is in [-1.0,-0.5] or [0.5, 1.0] such that multiplier = mantissa*2^shift for 32-bit scaling. More...
 
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 scale value, generates multiplier and shift values where mantissa is in [-1.0,-0.5] or [0.5, 1.0] such that multiplier = mantissa*2^shift for 16-bit scaling. More...
 
void CreateRescaleTosaOperator (const std::string &inputName, const std::string &outputName, double scale, int32_t input_zp, int32_t output_zp, bool double_round, bool scale32, TosaSerializationOperator **op)
 
void CreateRescaleTosaOperatorPerChannel (const std::string &inputName, const std::string &outputName, int32_t input_zp, int32_t output_zp, bool double_round, bool scale32, double input_scale, double output_scale, const std::vector< float > &weight_scales, TosaSerializationOperator **op)
 
void CreateFromInt32RescaleTosaOperator (const std::string &inputName, const std::string &outputName, double output_scale, int32_t output_zp, TosaSerializationOperator **op)
 

Function Documentation

◆ ComputeMultiplierAndShiftTosaScale16()

void ComputeMultiplierAndShiftTosaScale16 ( double  scale,
int32_t &  multiplier,
int32_t &  shift 
)
inline

The following is taken from mlir/lib/Dialect/Tosa/Utils/QuantUtils.cpp in the LLVM project From a scale value, generates multiplier and shift values where mantissa is in [-1.0,-0.5] or [0.5, 1.0] such that multiplier = mantissa*2^shift for 16-bit scaling.

Definition at line 110 of file TosaRescaleOperatorUtils.hpp.

113 {
114  const double mantissa = std::frexp(scale, &shift);
115  auto shiftedM = std::round(mantissa * (int64_t(1) << 15));
116 
117  // Can't be greater than 1.0.
118  if (!(shiftedM <= (int64_t(1) << 15)))
119  {
120  throw armnn::Exception("Shifted mantissa exceeds 16 signed bits");
121  }
122 
123  if (shiftedM == (int64_t(1) << 15))
124  {
125  shiftedM /= 2;
126  shift++;
127  }
128 
129  // TOSA expects right shift to be positive and embed (1 << 15) into right
130  // shift bits.
131  shift = (-shift) + 15;
132 
133  if (!(shiftedM <= std::numeric_limits<int32_t>::max()))
134  {
135  throw armnn::Exception("Shifted mantissa exceeds 32-bit signed output type");
136  }
137 
138  multiplier = static_cast<int32_t>(shiftedM);
139 
140  // Shifting tops out at 62 bits. Right shift to make 62 bits the max.
141  // The limit of 62 on shift allows the shift to be decomposed as
142  // two right shifts of 31.
143  if (shift > 62)
144  {
145  // Shifting the multiplier by more than 31-bits is unnecessary.
146  multiplier = multiplier >> std::min<int32_t>(31, shift - 62);
147  shift = 62;
148  }
149 }

Referenced by CreateRescaleTosaOperator(), and CreateRescaleTosaOperatorPerChannel().

◆ ComputeMultiplierAndShiftTosaScale32()

void ComputeMultiplierAndShiftTosaScale32 ( double  scale,
int32_t &  multiplier,
int32_t &  shift 
)
inline

The following is taken from mlir/lib/Dialect/Tosa/Utils/QuantUtils.cpp in the LLVM project From a scale value, generates multiplier and shift values where mantissa is in [-1.0,-0.5] or [0.5, 1.0] such that multiplier = mantissa*2^shift for 32-bit scaling.

Definition at line 65 of file TosaRescaleOperatorUtils.hpp.

68 {
69  const double mantissa = std::frexp(scale, &shift);
70  auto shiftedM = std::round(mantissa * (int64_t(1) << 31));
71 
72  // Can't be greater than 1.0.
73  if (!(shiftedM <= (int64_t(1) << 31)))
74  {
75  throw armnn::Exception("Shifted mantissa exceeds 32 signed bits");
76  }
77 
78  if (shiftedM == (int64_t(1) << 31))
79  {
80  shiftedM /= 2;
81  shift++;
82  }
83 
84  // TOSA expects right shift to be positive, and embed (1 << 31) into right
85  // shift bits.
86  shift = (-shift) + 31;
87 
88  if (!(shiftedM <= std::numeric_limits<int32_t>::max()))
89  {
90  throw armnn::Exception("Shifted mantissa exceeds 32-bit signed output type");
91  }
92 
93  multiplier = static_cast<int32_t>(shiftedM);
94 
95  // Shifting tops out at 62 bits. Right shift to make 62 bits the max.
96  // The limit of 62 on shift allows the shift to be decomposed as
97  // two right shifts of 31.
98  if (shift > 62)
99  {
100  // Shifting the multiplier by more than 32-bits is unnecessary.
101  multiplier = multiplier >> std::min<int32_t>(31, shift - 62);
102  shift = 62;
103  }
104 }

Referenced by CreateRescaleTosaOperator(), and CreateRescaleTosaOperatorPerChannel().

◆ CreateFromInt32RescaleTosaOperator()

void CreateFromInt32RescaleTosaOperator ( const std::string &  inputName,
const std::string &  outputName,
double  output_scale,
int32_t  output_zp,
TosaSerializationOperator **  op 
)
inline

Definition at line 216 of file TosaRescaleOperatorUtils.hpp.

221 {
222  CreateRescaleTosaOperator(inputName, outputName, output_scale,
223  0, output_zp, true, true, op);
224 }

References CreateRescaleTosaOperator().

◆ CreateRescaleTosaOperator() [1/3]

void CreateRescaleTosaOperator ( 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  double_round,
bool  scale32,
bool  per_channel,
TosaSerializationOperator **  op 
)
inline

Definition at line 10 of file TosaRescaleOperatorUtils.hpp.

20 {
21  if (!op)
22  {
23  throw armnn::Exception("CreateRescaleTosaOperator: nullptr op");
24  }
25 
26  TosaRescaleAttribute attribute(input_zp,
27  output_zp,
28  multipliers,
29  shifts,
30  scale32,
31  double_round,
32  per_channel,
33  false, // input_unsigned
34  false); // output_unsigned
35 
36  // op
37  *op = new TosaSerializationOperator(Op_RESCALE, Attribute_RescaleAttribute, &attribute, {inputName}, {outputName});
38  if (!(*op))
39  {
40  throw armnn::Exception("CreateRescaleTosaOperator: failed to created operator");
41  }
42 }

Referenced by AddRescaleOp(), ConvertQuantizeToTosaOperator(), ConvertSoftmaxToTosaOperator(), CreateFromInt32RescaleTosaOperator(), CreateRescaleTosaOperator(), and CreateRescaleTosaOperatorPerChannel().

◆ CreateRescaleTosaOperator() [2/3]

void CreateRescaleTosaOperator ( const std::string &  inputName,
const std::string &  outputName,
double  scale,
int32_t  input_zp,
int32_t  output_zp,
bool  double_round,
bool  scale32,
TosaSerializationOperator **  op 
)
inline

Definition at line 151 of file TosaRescaleOperatorUtils.hpp.

159 {
160  int32_t multiplier;
161  int32_t shift;
162 
163  if (scale32)
164  {
165  ComputeMultiplierAndShiftTosaScale32(scale, multiplier, shift);
166  }
167  else
168  {
169  ComputeMultiplierAndShiftTosaScale16(scale, multiplier, shift);
170  }
171 
172  CreateRescaleTosaOperator(inputName, outputName, multiplier, shift,
173  input_zp, output_zp, double_round, scale32, false, op);
174 }

References ComputeMultiplierAndShiftTosaScale16(), ComputeMultiplierAndShiftTosaScale32(), and CreateRescaleTosaOperator().

◆ CreateRescaleTosaOperator() [3/3]

void CreateRescaleTosaOperator ( const std::string &  inputName,
const std::string &  outputName,
int32_t  scale_multiplier,
int32_t  scale_shift,
int32_t  input_zp,
int32_t  output_zp,
bool  double_round,
bool  scale32,
bool  per_channel,
TosaSerializationOperator **  op 
)
inline

Definition at line 44 of file TosaRescaleOperatorUtils.hpp.

54 {
55  const std::vector<int32_t> multipliers{scale_multiplier};
56  const std::vector<int32_t> shifts{scale_shift};
57  CreateRescaleTosaOperator(inputName, outputName, multipliers, shifts,
58  input_zp, output_zp, double_round, scale32, per_channel, op);
59 }

References CreateRescaleTosaOperator().

◆ CreateRescaleTosaOperatorPerChannel()

void CreateRescaleTosaOperatorPerChannel ( const std::string &  inputName,
const std::string &  outputName,
int32_t  input_zp,
int32_t  output_zp,
bool  double_round,
bool  scale32,
double  input_scale,
double  output_scale,
const std::vector< float > &  weight_scales,
TosaSerializationOperator **  op 
)
inline

Definition at line 176 of file TosaRescaleOperatorUtils.hpp.

186 {
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());
191 
192  for (const float& weight_scale : weight_scales)
193  {
194  double op_tensor_scale = (input_scale * weight_scale) / output_scale;
195  int32_t multiplier;
196  int32_t shift;
197 
198  if (scale32)
199  {
200  ComputeMultiplierAndShiftTosaScale32(op_tensor_scale, multiplier, shift);
201  }
202  else
203  {
204  ComputeMultiplierAndShiftTosaScale16(op_tensor_scale, multiplier, shift);
205  }
206 
207  op_tensor_multipliers.push_back(multiplier);
208  op_tensor_shifts.push_back(shift);
209  }
210 
211  bool per_channel = weight_scales.size() == 1 ? false : true;
212  CreateRescaleTosaOperator(inputName, outputName, op_tensor_multipliers, op_tensor_shifts,
213  input_zp, output_zp, double_round, scale32, per_channel, op);
214 }

References ComputeMultiplierAndShiftTosaScale16(), ComputeMultiplierAndShiftTosaScale32(), and CreateRescaleTosaOperator().

ComputeMultiplierAndShiftTosaScale16
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...
Definition: TosaRescaleOperatorUtils.hpp:110
armnn::Exception
Base class for all ArmNN exceptions so that users can filter to just those.
Definition: Exceptions.hpp:46
ComputeMultiplierAndShiftTosaScale32
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...
Definition: TosaRescaleOperatorUtils.hpp:65
CreateRescaleTosaOperator
void CreateRescaleTosaOperator(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 double_round, bool scale32, bool per_channel, TosaSerializationOperator **op)
Definition: TosaRescaleOperatorUtils.hpp:10