ONE - On-device Neural Engine
Loading...
Searching...
No Matches
helpers_asymm.h File Reference
#include "helpers.h"

Go to the source code of this file.

Macros

#define CONVERT_DOWN_RTE_STR(x, type)   (convert_##type##_rte((x)))
 
#define CONVERT_DOWN_RTE(x, type)   CONVERT_DOWN_RTE_STR(x, type)
 
#define QUANTIZE_IMPL(type, size)
 
#define DEQUANTIZE_IMPL(type, size)
 
#define ASYMM_ROUNDING_DIVIDE_BY_POW2_IMPL(size)
 
#define ASYMM_MULT_IMPL(size)
 
#define ASYMM_EXP_ON_INTERVAL_BETWEEN_NEGATIVE_ONE_QUARTER_AND_0_EXCL_IMPL(size)
 
#define ASYMM_SELECT_USING_MASK_IMPL(size)
 
#define ASYMM_MASK_IF_ZERO_IMPL(size)
 
#define ASYMM_MASK_IF_NON_ZERO_IMPL(size)
 
#define EXP_BARREL_SHIFTER_IMPL(size)
 
#define ASYMM_EXP_ON_NEGATIVE_VALUES_IMPL(size)
 
#define ASYMM_SATURATING_ROUNDING_MULT_BY_POW2_IMPL(size)
 
#define ASYMM_ROUNDING_HALF_SUM_IMPL(size)
 
#define ASYMM_ONE_OVER_ONE_PLUS_X_FOR_X_IN_0_1_IMPL(size)
 
#define ASYMM_RESCALE_IMPL(size)
 
#define QUANTIZE_STR(input, offset, scale, type, size)   quantize_##type##size(input, offset, scale)
 
#define QUANTIZE(input, offset, scale, type, size)   QUANTIZE_STR(input, offset, scale, type, size)
 
#define DEQUANTIZE_STR(input, offset, scale, type, size)    dequantize_##type##size(input, offset, scale)
 
#define DEQUANTIZE(input, offset, scale, type, size)    DEQUANTIZE_STR(input, offset, scale, type, size)
 
#define ASYMM_ROUNDING_DIVIDE_BY_POW2(x, exponent, size)    asymm_rounding_divide_by_POW2_##size(x, exponent)
 
#define ASYMM_MULT(a, b, size)   asymm_mult##size(a, b)
 
#define ASYMM_MULT_BY_QUANT_MULTIPLIER_GREATER_THAN_ONE(x, quantized_multiplier, left_shift, size)    ASYMM_MULT(x *((VEC_DATA_TYPE(int, size))(1) << (-left_shift)), quantized_multiplier, size)
 
#define ASYMM_MULT_BY_QUANT_MULTIPLIER_LESS_THAN_ONE(x, quantized_multiplier, right_shift, size)    ASYMM_ROUNDING_DIVIDE_BY_POW2(ASYMM_MULT(x, quantized_multiplier, size), right_shift, size)
 
#define ASYMM_EXP_ON_INTERVAL_BETWEEN_NEGATIVE_ONE_QUARTER_AND_0_EXCL(a, size)    asymm_exp_on_interval_between_negative_one_quarter_and_0_excl##size(a)
 
#define ASYMM_SELECT_USING_MASK(if_mask, then_val, else_val, size)    asymm_select_using_mask##size(if_mask, then_val, else_val)
 
#define ASYMM_MASK_IF_ZERO(a, size)   asymm_mask_if_zero##size(a)
 
#define ASYMM_MASK_IF_NON_ZERO(a, size)   asymm_mask_if_non_zero##size(a)
 
#define EXP_BARREL_SHIFTER(result, exponent, fp_multiplier, k_integer_bits, k_fractional_bits, remainder, size)
 
#define ASYMM_EXP_ON_NEGATIVE_VALUES(a, k_integer_bits, size)    asymm_exp_on_negative_values##size(a, k_integer_bits)
 
#define ASYMM_ONE_OVER_ONE_PLUS_X_FOR_X_IN_0_1(a, size)    asymm_one_over_one_plus_x_for_x_in_0_1##size(a)
 
#define ASYMM_SATURATING_ROUNDING_MULT_BY_POW2(x, exponent, size)    asymm_saturating_rounding_mult_by_pow2##size(x, exponent)
 
#define ASYMM_ROUNDING_HALF_SUM(a, b, size)   asymm_rounding_half_sum##size(a, b)
 
#define ASYMM_RESCALE(value, src_integer_bits, dst_integer_bits, size)    asymm_rescale##size(value, src_integer_bits, dst_integer_bits)
 
#define MULTIPLY_BY_QUANTIZED_MULTIPLIER_IMPL(size)
 
#define MULTIPLY_BY_QUANTIZED_MULTIPLIER(input, qmul, shift, size)    multiply_by_quantized_multiplier##size(input, qmul, shift)
 

Functions

uchar quantize_qasymm8 (float input, float offset, float scale)
 
float dequantize_qasymm8 (uchar input, float offset, float scale)
 
float dequantize_qasymm8_signed (char input, float offset, float scale)
 

Macro Definition Documentation

◆ ASYMM_EXP_ON_INTERVAL_BETWEEN_NEGATIVE_ONE_QUARTER_AND_0_EXCL

#define ASYMM_EXP_ON_INTERVAL_BETWEEN_NEGATIVE_ONE_QUARTER_AND_0_EXCL (   a,
  size 
)     asymm_exp_on_interval_between_negative_one_quarter_and_0_excl##size(a)

Definition at line 445 of file helpers_asymm.h.

468 { \
469 const int left_shift = shift > 0 ? shift : 0; \
470 const int right_shift = shift > 0 ? 0 : -shift; \
471 return ASYMM_ROUNDING_DIVIDE_BY_POW2(ASYMM_MULT(input * (1 << left_shift), qmul, size), \
472 right_shift, size); \
473 }
474#define MULTIPLY_BY_QUANTIZED_MULTIPLIER(input, qmul, shift, size) \
475 multiply_by_quantized_multiplier##size(input, qmul, shift)
476
477QUANTIZE_IMPL(uchar, 1)
478QUANTIZE_IMPL(char, 1)
479QUANTIZE_IMPL(uint, 1)
480QUANTIZE_IMPL(int, 1)
481QUANTIZE_IMPL(uchar, 4)
482QUANTIZE_IMPL(ushort, 4)
483QUANTIZE_IMPL(short, 4)
484QUANTIZE_IMPL(uchar, 16)
485QUANTIZE_IMPL(char, 16)
486QUANTIZE_IMPL(ushort, 16)
487QUANTIZE_IMPL(short, 16)
488QUANTIZE_IMPL(uint, 16)
489QUANTIZE_IMPL(int, 16)
490
491DEQUANTIZE_IMPL(uchar, 1)
492DEQUANTIZE_IMPL(char, 1)
493DEQUANTIZE_IMPL(uint, 1)
494DEQUANTIZE_IMPL(int, 1)
495DEQUANTIZE_IMPL(uchar, 4)
496DEQUANTIZE_IMPL(ushort, 4)
497DEQUANTIZE_IMPL(short, 4)
498DEQUANTIZE_IMPL(uchar, 16)
499DEQUANTIZE_IMPL(char, 16)
500DEQUANTIZE_IMPL(ushort, 16)
501DEQUANTIZE_IMPL(short, 16)
502DEQUANTIZE_IMPL(uint, 16)
503DEQUANTIZE_IMPL(int, 16)
504
510
516
521
527
533
539
544
549
555
560
565
571
577
578#endif // ARM_COMPUTE_HELPERS_ASYMM_H
#define ASYMM_ONE_OVER_ONE_PLUS_X_FOR_X_IN_0_1_IMPL(size)
#define QUANTIZE_IMPL(type, size)
#define ASYMM_EXP_ON_INTERVAL_BETWEEN_NEGATIVE_ONE_QUARTER_AND_0_EXCL_IMPL(size)
#define ASYMM_EXP_ON_NEGATIVE_VALUES_IMPL(size)
#define ASYMM_MULT(a, b, size)
#define ASYMM_MASK_IF_NON_ZERO_IMPL(size)
#define ASYMM_SATURATING_ROUNDING_MULT_BY_POW2_IMPL(size)
#define ASYMM_MASK_IF_ZERO_IMPL(size)
#define ASYMM_ROUNDING_HALF_SUM_IMPL(size)
#define MULTIPLY_BY_QUANTIZED_MULTIPLIER_IMPL(size)
#define EXP_BARREL_SHIFTER_IMPL(size)
#define ASYMM_ROUNDING_DIVIDE_BY_POW2(x, exponent, size)
#define ASYMM_RESCALE_IMPL(size)
#define ASYMM_SELECT_USING_MASK_IMPL(size)
#define ASYMM_ROUNDING_DIVIDE_BY_POW2_IMPL(size)
#define DEQUANTIZE_IMPL(type, size)
#define ASYMM_MULT_IMPL(size)
Index shift(const Index &in_index, const Shape &shift_from)
Definition Common.cpp:26
int32_t size[5]
Definition Slice.cpp:35

◆ ASYMM_EXP_ON_INTERVAL_BETWEEN_NEGATIVE_ONE_QUARTER_AND_0_EXCL_IMPL

#define ASYMM_EXP_ON_INTERVAL_BETWEEN_NEGATIVE_ONE_QUARTER_AND_0_EXCL_IMPL (   size)
Value:
inline VEC_DATA_TYPE(int, size) \
asymm_exp_on_interval_between_negative_one_quarter_and_0_excl##size(VEC_DATA_TYPE(int, size) \
a) \
{ \
const VEC_DATA_TYPE(int, size) constant_term = 1895147668; \
const VEC_DATA_TYPE(int, size) constant_1_over_3 = 715827883; \
const int k_fractional_bits = 31; \
VEC_DATA_TYPE(int, size) \
x = a + (1 << (k_fractional_bits - 3)); \
VEC_DATA_TYPE(int, size) \
x2 = ASYMM_MULT(x, x, size); \
VEC_DATA_TYPE(int, size) \
x3 = ASYMM_MULT(x2, x, size); \
VEC_DATA_TYPE(int, size) \
x4 = ASYMM_MULT(x2, x2, size); \
VEC_DATA_TYPE(int, size) \
x4_over_4 = ASYMM_ROUNDING_DIVIDE_BY_POW2(x4, 2, size); \
VEC_DATA_TYPE(int, size) \
x4_over_24_plus_x3_over_6_plus_x2 = \
ASYMM_MULT((x4_over_4 + x3), constant_1_over_3, size) + x2; \
VEC_DATA_TYPE(int, size) \
x4_over_24_plus_x3_over_6_plus_x2_over_2 = \
ASYMM_ROUNDING_DIVIDE_BY_POW2(x4_over_24_plus_x3_over_6_plus_x2, 1, size); \
return constant_term + \
ASYMM_MULT(constant_term, x + x4_over_24_plus_x3_over_6_plus_x2_over_2, size); \
}
#define VEC_DATA_TYPE(type, size)
Definition helpers.h:275

Calculates $ exp(x) $ for x in [-1/4, 0).

Parameters
[in]sizeSize of vector.
Returns
Result in fixed-point format Q0.

Definition at line 189 of file helpers_asymm.h.

193 { \
194 const VEC_DATA_TYPE(int, size) constant_term = 1895147668; \
195 const VEC_DATA_TYPE(int, size) constant_1_over_3 = 715827883; \
196 const int k_fractional_bits = 31; \
197 VEC_DATA_TYPE(int, size) \
198 x = a + (1 << (k_fractional_bits - 3)); \
199 VEC_DATA_TYPE(int, size) \
200 x2 = ASYMM_MULT(x, x, size); \
201 VEC_DATA_TYPE(int, size) \
202 x3 = ASYMM_MULT(x2, x, size); \
203 VEC_DATA_TYPE(int, size) \
204 x4 = ASYMM_MULT(x2, x2, size); \
205 VEC_DATA_TYPE(int, size) \
206 x4_over_4 = ASYMM_ROUNDING_DIVIDE_BY_POW2(x4, 2, size); \
207 VEC_DATA_TYPE(int, size) \
208 x4_over_24_plus_x3_over_6_plus_x2 = \
209 ASYMM_MULT((x4_over_4 + x3), constant_1_over_3, size) + x2; \
210 VEC_DATA_TYPE(int, size) \
211 x4_over_24_plus_x3_over_6_plus_x2_over_2 = \
212 ASYMM_ROUNDING_DIVIDE_BY_POW2(x4_over_24_plus_x3_over_6_plus_x2, 1, size); \
213 return constant_term + \
214 ASYMM_MULT(constant_term, x + x4_over_24_plus_x3_over_6_plus_x2_over_2, size); \
215 }

◆ ASYMM_EXP_ON_NEGATIVE_VALUES

#define ASYMM_EXP_ON_NEGATIVE_VALUES (   a,
  k_integer_bits,
  size 
)     asymm_exp_on_negative_values##size(a, k_integer_bits)

Definition at line 455 of file helpers_asymm.h.

◆ ASYMM_EXP_ON_NEGATIVE_VALUES_IMPL

#define ASYMM_EXP_ON_NEGATIVE_VALUES_IMPL (   size)

Calculates $ exp(x) $ for x < 0.

Parameters
[in]sizeSize of vector.
Returns
Result in fixed-point format Q0.

Definition at line 286 of file helpers_asymm.h.

289 { \
290 const int k_fractional_bits = 31 - k_integer_bits; \
291 VEC_DATA_TYPE(int, size) \
292 k_one_quarter = 1 << (k_fractional_bits - 2); \
293 VEC_DATA_TYPE(int, size) \
294 mask = k_one_quarter - 1; \
295 VEC_DATA_TYPE(int, size) \
296 a_mod_quarter_minus_one_quarter = (a & mask) - k_one_quarter; \
297 VEC_DATA_TYPE(int, size) \
298 a_mod_quarter_minus_one_quarter_scaled = a_mod_quarter_minus_one_quarter << k_integer_bits; \
299 VEC_DATA_TYPE(int, size) \
301 a_mod_quarter_minus_one_quarter_scaled, size); \
302 VEC_DATA_TYPE(int, size) \
303 remainder = a_mod_quarter_minus_one_quarter - a; \
304 \
305 result = EXP_BARREL_SHIFTER(result, -2, 1672461947, k_integer_bits, k_fractional_bits, \
306 remainder, size); \
307 result = EXP_BARREL_SHIFTER(result, -1, 1302514674, k_integer_bits, k_fractional_bits, \
308 remainder, size); \
309 result = EXP_BARREL_SHIFTER(result, +0, 790015084, k_integer_bits, k_fractional_bits, \
310 remainder, size); \
311 result = EXP_BARREL_SHIFTER(result, +1, 290630308, k_integer_bits, k_fractional_bits, \
312 remainder, size); \
313 result = EXP_BARREL_SHIFTER(result, +2, 39332535, k_integer_bits, k_fractional_bits, \
314 remainder, size); \
315 result = \
316 EXP_BARREL_SHIFTER(result, +3, 720401, k_integer_bits, k_fractional_bits, remainder, size); \
317 result = \
318 EXP_BARREL_SHIFTER(result, +4, 242, k_integer_bits, k_fractional_bits, remainder, size); \
319 \
320 if (k_integer_bits > 5) \
321 { \
322 const VEC_DATA_TYPE(int, size) clamp = -(1 << (k_fractional_bits + 5)); \
324 } \
325 \
326 const VEC_DATA_TYPE(int, size) Q0_one = INT_MAX; \
327 return ASYMM_SELECT_USING_MASK(ASYMM_MASK_IF_ZERO(a, size), Q0_one, result, size); \
328 }
#define ASYMM_SELECT_USING_MASK(if_mask, then_val, else_val, size)
#define EXP_BARREL_SHIFTER(result, exponent, fp_multiplier, k_integer_bits, k_fractional_bits, remainder, size)
#define ASYMM_EXP_ON_INTERVAL_BETWEEN_NEGATIVE_ONE_QUARTER_AND_0_EXCL(a, size)
#define ASYMM_MASK_IF_NON_ZERO(a, size)
#define ASYMM_MASK_IF_ZERO(a, size)
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE std::enable_if< unpacket_traits< Packet >::masked_load_available, typenameunpacket_traits< Packet >::mask_t >::type mask(int from, int to)
result
Definition infer.py:103

◆ ASYMM_MASK_IF_NON_ZERO

#define ASYMM_MASK_IF_NON_ZERO (   a,
  size 
)    asymm_mask_if_non_zero##size(a)

Definition at line 450 of file helpers_asymm.h.

◆ ASYMM_MASK_IF_NON_ZERO_IMPL

#define ASYMM_MASK_IF_NON_ZERO_IMPL (   size)
Value:
inline VEC_DATA_TYPE(int, size) asymm_mask_if_non_zero##size(VEC_DATA_TYPE(int, size) a) \
{ \
const VEC_DATA_TYPE(int, size) all_zeros = 0; \
const VEC_DATA_TYPE(int, size) all_ones = ~0; \
return select(all_zeros, all_ones, a != 0); \
}

For each element of input vector, the corresponding bits of the result item are set if the input item is non-zero.

Parameters
[in]sizeSize of vector.
Returns
Output vector with bits set when corresponding bit in a is non zero.

Definition at line 256 of file helpers_asymm.h.

258 { \
259 const VEC_DATA_TYPE(int, size) all_zeros = 0; \
260 const VEC_DATA_TYPE(int, size) all_ones = ~0; \
261 return select(all_zeros, all_ones, a != 0); \
262 }

◆ ASYMM_MASK_IF_ZERO

#define ASYMM_MASK_IF_ZERO (   a,
  size 
)    asymm_mask_if_zero##size(a)

Definition at line 449 of file helpers_asymm.h.

◆ ASYMM_MASK_IF_ZERO_IMPL

#define ASYMM_MASK_IF_ZERO_IMPL (   size)
Value:
inline VEC_DATA_TYPE(int, size) asymm_mask_if_zero##size(VEC_DATA_TYPE(int, size) a) \
{ \
const VEC_DATA_TYPE(int, size) all_zeros = 0; \
const VEC_DATA_TYPE(int, size) all_ones = ~0; \
return select(all_zeros, all_ones, a == 0); \
}

For each element of input vector, the corresponding bits of the result item are set if the input item is zero.

Parameters
[in]sizeSize of vector.
Returns
Output vector with bits set when corresponding bit in a is zero.

Definition at line 241 of file helpers_asymm.h.

243 { \
244 const VEC_DATA_TYPE(int, size) all_zeros = 0; \
245 const VEC_DATA_TYPE(int, size) all_ones = ~0; \
246 return select(all_zeros, all_ones, a == 0); \
247 }

◆ ASYMM_MULT

#define ASYMM_MULT (   a,
  b,
  size 
)    asymm_mult##size(a, b)

Definition at line 440 of file helpers_asymm.h.

◆ ASYMM_MULT_BY_QUANT_MULTIPLIER_GREATER_THAN_ONE

#define ASYMM_MULT_BY_QUANT_MULTIPLIER_GREATER_THAN_ONE (   x,
  quantized_multiplier,
  left_shift,
  size 
)     ASYMM_MULT(x *((VEC_DATA_TYPE(int, size))(1) << (-left_shift)), quantized_multiplier, size)

Definition at line 441 of file helpers_asymm.h.

◆ ASYMM_MULT_BY_QUANT_MULTIPLIER_LESS_THAN_ONE

#define ASYMM_MULT_BY_QUANT_MULTIPLIER_LESS_THAN_ONE (   x,
  quantized_multiplier,
  right_shift,
  size 
)     ASYMM_ROUNDING_DIVIDE_BY_POW2(ASYMM_MULT(x, quantized_multiplier, size), right_shift, size)

Definition at line 443 of file helpers_asymm.h.

◆ ASYMM_MULT_IMPL

#define ASYMM_MULT_IMPL (   size)
Value:
inline VEC_DATA_TYPE(int, size) \
asymm_mult##size(VEC_DATA_TYPE(int, size) a, VEC_DATA_TYPE(int, size) b) \
{ \
VEC_DATA_TYPE(int, size) \
overflow = a == b && a == INT_MIN; \
VEC_DATA_TYPE(long, size) \
a_64 = convert_long##size(a); \
VEC_DATA_TYPE(long, size) \
b_64 = convert_long##size(b); \
VEC_DATA_TYPE(long, size) \
ab_64 = a_64 * b_64; \
/* Revert COMPMID-907 */ \
VEC_DATA_TYPE(long, size) \
mask1 = 1 << 30; \
VEC_DATA_TYPE(long, size) \
mask2 = 1 - (1 << 30); \
VEC_DATA_TYPE(long, size) \
is_positive_or_zero = ab_64 >= 0; \
VEC_DATA_TYPE(long, size) \
nudge = select(mask2, mask1, is_positive_or_zero); \
VEC_DATA_TYPE(long, size) \
mask = 1ll << 31; \
VEC_DATA_TYPE(int, size) \
ab_x2_high32 = convert_int##size((ab_64 + nudge) / mask); \
return select(ab_x2_high32, INT_MAX, overflow); \
}

Product of two numbers, interpreting them as fixed-point values in the interval [-1, 1), rounding to the nearest value, and saturating -1 * -1 to the maximum value.

Parameters
[in]sizeSize of vector.
Returns
Product of two fixed-point numbers.

Definition at line 155 of file helpers_asymm.h.

158 { \
159 VEC_DATA_TYPE(int, size) \
160 overflow = a == b && a == INT_MIN; \
161 VEC_DATA_TYPE(long, size) \
162 a_64 = convert_long##size(a); \
163 VEC_DATA_TYPE(long, size) \
164 b_64 = convert_long##size(b); \
165 VEC_DATA_TYPE(long, size) \
166 ab_64 = a_64 * b_64; \
167 /* Revert COMPMID-907 */ \
168 VEC_DATA_TYPE(long, size) \
169 mask1 = 1 << 30; \
170 VEC_DATA_TYPE(long, size) \
171 mask2 = 1 - (1 << 30); \
172 VEC_DATA_TYPE(long, size) \
173 is_positive_or_zero = ab_64 >= 0; \
174 VEC_DATA_TYPE(long, size) \
175 nudge = select(mask2, mask1, is_positive_or_zero); \
176 VEC_DATA_TYPE(long, size) \
177 mask = 1ll << 31; \
178 VEC_DATA_TYPE(int, size) \
179 ab_x2_high32 = convert_int##size((ab_64 + nudge) / mask); \
180 return select(ab_x2_high32, INT_MAX, overflow); \
181 }

◆ ASYMM_ONE_OVER_ONE_PLUS_X_FOR_X_IN_0_1

#define ASYMM_ONE_OVER_ONE_PLUS_X_FOR_X_IN_0_1 (   a,
  size 
)     asymm_one_over_one_plus_x_for_x_in_0_1##size(a)

Definition at line 457 of file helpers_asymm.h.

◆ ASYMM_ONE_OVER_ONE_PLUS_X_FOR_X_IN_0_1_IMPL

#define ASYMM_ONE_OVER_ONE_PLUS_X_FOR_X_IN_0_1_IMPL (   size)
Value:
inline VEC_DATA_TYPE(int, size) \
asymm_one_over_one_plus_x_for_x_in_0_1##size(VEC_DATA_TYPE(int, size) a) \
{ \
const VEC_DATA_TYPE(int, size) Q0_one = INT_MAX; \
const VEC_DATA_TYPE(int, size) Q2_one = 1 << (31 - 2); \
VEC_DATA_TYPE(int, size) \
half_denominator = ASYMM_ROUNDING_HALF_SUM(a, Q0_one, size); \
const VEC_DATA_TYPE(int, size) Q2_48_over_17 = 1515870810; \
const VEC_DATA_TYPE(int, size) Q2_neg_32_over_17 = -1010580540; \
VEC_DATA_TYPE(int, size) \
x = Q2_48_over_17 + ASYMM_MULT(half_denominator, Q2_neg_32_over_17, size); \
for (int i = 0; i < 3; i++) \
{ \
VEC_DATA_TYPE(int, size) \
half_denominator_times_x = ASYMM_MULT(half_denominator, x, size); \
VEC_DATA_TYPE(int, size) \
one_minus_half_denominator_times_x = Q2_one - half_denominator_times_x; \
VEC_DATA_TYPE(int, size) \
tmp = ASYMM_MULT(x, one_minus_half_denominator_times_x, size); \
} \
}
#define ASYMM_SATURATING_ROUNDING_MULT_BY_POW2(x, exponent, size)
#define ASYMM_ROUNDING_HALF_SUM(a, b, size)

Calculates $ 1 / (1 + x) $ for x in (0, 1).

Parameters
[in]sizeSize of vector.
Returns
Result in fixed-point format Q0.

Definition at line 391 of file helpers_asymm.h.

394 { \
395 const VEC_DATA_TYPE(int, size) Q0_one = INT_MAX; \
396 const VEC_DATA_TYPE(int, size) Q2_one = 1 << (31 - 2); \
397 VEC_DATA_TYPE(int, size) \
398 half_denominator = ASYMM_ROUNDING_HALF_SUM(a, Q0_one, size); \
399 const VEC_DATA_TYPE(int, size) Q2_48_over_17 = 1515870810; \
400 const VEC_DATA_TYPE(int, size) Q2_neg_32_over_17 = -1010580540; \
401 VEC_DATA_TYPE(int, size) \
402 x = Q2_48_over_17 + ASYMM_MULT(half_denominator, Q2_neg_32_over_17, size); \
403 for (int i = 0; i < 3; i++) \
404 { \
405 VEC_DATA_TYPE(int, size) \
406 half_denominator_times_x = ASYMM_MULT(half_denominator, x, size); \
407 VEC_DATA_TYPE(int, size) \
408 one_minus_half_denominator_times_x = Q2_one - half_denominator_times_x; \
409 VEC_DATA_TYPE(int, size) \
410 tmp = ASYMM_MULT(x, one_minus_half_denominator_times_x, size); \
412 } \
414 }

◆ ASYMM_RESCALE

#define ASYMM_RESCALE (   value,
  src_integer_bits,
  dst_integer_bits,
  size 
)     asymm_rescale##size(value, src_integer_bits, dst_integer_bits)

Definition at line 462 of file helpers_asymm.h.

◆ ASYMM_RESCALE_IMPL

#define ASYMM_RESCALE_IMPL (   size)
Value:
inline VEC_DATA_TYPE(int, size) asymm_rescale##size(VEC_DATA_TYPE(int, size) value, \
int src_integer_bits, int dst_integer_bits) \
{ \
int exponent = src_integer_bits - dst_integer_bits; \
return ASYMM_SATURATING_ROUNDING_MULT_BY_POW2(value, exponent, size); \
}

Considering the integer value as fixed-point, change the number of integer bits and update value accordingly.

Parameters
[in]sizeSize of vector.
Returns
Rescaled value.

Definition at line 423 of file helpers_asymm.h.

426 { \
427 int exponent = src_integer_bits - dst_integer_bits; \
428 return ASYMM_SATURATING_ROUNDING_MULT_BY_POW2(value, exponent, size); \
429 }

◆ ASYMM_ROUNDING_DIVIDE_BY_POW2

#define ASYMM_ROUNDING_DIVIDE_BY_POW2 (   x,
  exponent,
  size 
)     asymm_rounding_divide_by_POW2_##size(x, exponent)

Definition at line 438 of file helpers_asymm.h.

◆ ASYMM_ROUNDING_DIVIDE_BY_POW2_IMPL

#define ASYMM_ROUNDING_DIVIDE_BY_POW2_IMPL (   size)
Value:
inline VEC_DATA_TYPE(int, size) asymm_rounding_divide_by_POW2_##size( \
VEC_DATA_TYPE(int, size) x, VEC_DATA_TYPE(int, size) exponent) \
{ \
const VEC_DATA_TYPE(int, size) zero = (VEC_DATA_TYPE(int, size))0; \
const VEC_DATA_TYPE(int, size) one = (VEC_DATA_TYPE(int, size))1; \
VEC_DATA_TYPE(int, size) \
mask = (one << exponent) - one; \
VEC_DATA_TYPE(int, size) \
threshold = (mask >> 1) + select(zero, one, x < 0); \
return (x >> exponent) + select(zero, one, (x & mask) > threshold); \
}

Correctly-rounded-to-nearest division by a power-of-two.

Parameters
[in]sizeSize of vector.
Returns
Correctly-rounded-to-nearest division by a power-of-two.

Definition at line 135 of file helpers_asymm.h.

138 { \
139 const VEC_DATA_TYPE(int, size) zero = (VEC_DATA_TYPE(int, size))0; \
140 const VEC_DATA_TYPE(int, size) one = (VEC_DATA_TYPE(int, size))1; \
141 VEC_DATA_TYPE(int, size) \
142 mask = (one << exponent) - one; \
143 VEC_DATA_TYPE(int, size) \
144 threshold = (mask >> 1) + select(zero, one, x < 0); \
145 return (x >> exponent) + select(zero, one, (x & mask) > threshold); \
146 }

◆ ASYMM_ROUNDING_HALF_SUM

#define ASYMM_ROUNDING_HALF_SUM (   a,
  b,
  size 
)    asymm_rounding_half_sum##size(a, b)

Definition at line 461 of file helpers_asymm.h.

◆ ASYMM_ROUNDING_HALF_SUM_IMPL

#define ASYMM_ROUNDING_HALF_SUM_IMPL (   size)
Value:
inline VEC_DATA_TYPE(int, size) \
asymm_rounding_half_sum##size(VEC_DATA_TYPE(int, size) a, VEC_DATA_TYPE(int, size) b) \
{ \
VEC_DATA_TYPE(long, size) \
a64 = convert_long##size(a); \
VEC_DATA_TYPE(long, size) \
b64 = convert_long##size(b); \
VEC_DATA_TYPE(long, size) \
sum = a64 + b64; \
const VEC_DATA_TYPE(long, size) one = 1; \
const VEC_DATA_TYPE(long, size) minus_one = -1; \
VEC_DATA_TYPE(long, size) \
sign = select(minus_one, one, sum >= 0); \
return convert_int##size((sum + sign) / 2); \
}

Calculates (a+b)/2, rounded to the nearest integer. Equivalent to VRHADD in the ARM NEON instruction set.

Parameters
[in]sizeSize of vector.
Returns
(a+b)/2, rounded to the nearest integer.

Definition at line 368 of file helpers_asymm.h.

371 { \
372 VEC_DATA_TYPE(long, size) \
373 a64 = convert_long##size(a); \
374 VEC_DATA_TYPE(long, size) \
375 b64 = convert_long##size(b); \
376 VEC_DATA_TYPE(long, size) \
377 sum = a64 + b64; \
378 const VEC_DATA_TYPE(long, size) one = 1; \
379 const VEC_DATA_TYPE(long, size) minus_one = -1; \
380 VEC_DATA_TYPE(long, size) \
381 sign = select(minus_one, one, sum >= 0); \
382 return convert_int##size((sum + sign) / 2); \
383 }

◆ ASYMM_SATURATING_ROUNDING_MULT_BY_POW2

#define ASYMM_SATURATING_ROUNDING_MULT_BY_POW2 (   x,
  exponent,
  size 
)     asymm_saturating_rounding_mult_by_pow2##size(x, exponent)

Definition at line 459 of file helpers_asymm.h.

◆ ASYMM_SATURATING_ROUNDING_MULT_BY_POW2_IMPL

#define ASYMM_SATURATING_ROUNDING_MULT_BY_POW2_IMPL (   size)
Value:
inline VEC_DATA_TYPE(int, size) \
asymm_saturating_rounding_mult_by_pow2##size(VEC_DATA_TYPE(int, size) x, int exponent) \
{ \
if (exponent < 0) \
{ \
return ASYMM_ROUNDING_DIVIDE_BY_POW2(x, -exponent, size); \
} \
\
const VEC_DATA_TYPE(int, size) min = INT_MIN; \
const VEC_DATA_TYPE(int, size) max = INT_MAX; \
int threshold = ((1 << (31 - exponent)) - 1); \
VEC_DATA_TYPE(int, size) \
positive_mask = ASYMM_MASK_IF_NON_ZERO(x > threshold, size); \
VEC_DATA_TYPE(int, size) \
negative_mask = ASYMM_MASK_IF_NON_ZERO(x < -threshold, size); \
VEC_DATA_TYPE(int, size) \
result = x << exponent; \
result = ASYMM_SELECT_USING_MASK(positive_mask, max, result, size); \
result = ASYMM_SELECT_USING_MASK(negative_mask, min, result, size); \
return result; \
}

Calculates the product of a integer value by a power of two, with either a positive exponent (equivalent to an arithmetic left shift, saturating) or a negative exponent (equivalent to an arithmetic right shift, rounding to nearest).

Parameters
[in]sizeSize of vector.
Returns
Arithmetic left or right shift.

Definition at line 338 of file helpers_asymm.h.

341 { \
342 if (exponent < 0) \
343 { \
344 return ASYMM_ROUNDING_DIVIDE_BY_POW2(x, -exponent, size); \
345 } \
346 \
347 const VEC_DATA_TYPE(int, size) min = INT_MIN; \
348 const VEC_DATA_TYPE(int, size) max = INT_MAX; \
349 int threshold = ((1 << (31 - exponent)) - 1); \
350 VEC_DATA_TYPE(int, size) \
351 positive_mask = ASYMM_MASK_IF_NON_ZERO(x > threshold, size); \
352 VEC_DATA_TYPE(int, size) \
353 negative_mask = ASYMM_MASK_IF_NON_ZERO(x < -threshold, size); \
354 VEC_DATA_TYPE(int, size) \
355 result = x << exponent; \
356 result = ASYMM_SELECT_USING_MASK(positive_mask, max, result, size); \
357 result = ASYMM_SELECT_USING_MASK(negative_mask, min, result, size); \
358 return result; \
359 }

◆ ASYMM_SELECT_USING_MASK

#define ASYMM_SELECT_USING_MASK (   if_mask,
  then_val,
  else_val,
  size 
)     asymm_select_using_mask##size(if_mask, then_val, else_val)

Definition at line 447 of file helpers_asymm.h.

◆ ASYMM_SELECT_USING_MASK_IMPL

#define ASYMM_SELECT_USING_MASK_IMPL (   size)
Value:
inline VEC_DATA_TYPE(int, size) asymm_select_using_mask##size(VEC_DATA_TYPE(int, size) if_mask, \
VEC_DATA_TYPE(int, size) then_val, \
VEC_DATA_TYPE(int, size) else_val) \
{ \
return (if_mask & then_val) ^ (~if_mask & else_val); \
}

Each bit of the result is set to the corresponding bit of either then_val or else_val depending on whether the corresponding bit of if_mask is set. Equivalent to the VBSL instruction in ARM NEON.

Parameters
[in]sizeSize of vector.
Returns
Result contaning bits from then_val or from else_val depending on corresponding bit in if_mask is set or not.

Definition at line 226 of file helpers_asymm.h.

230 { \
231 return (if_mask & then_val) ^ (~if_mask & else_val); \
232 }

◆ CONVERT_DOWN_RTE

#define CONVERT_DOWN_RTE (   x,
  type 
)    CONVERT_DOWN_RTE_STR(x, type)

Definition at line 53 of file helpers_asymm.h.

◆ CONVERT_DOWN_RTE_STR

#define CONVERT_DOWN_RTE_STR (   x,
  type 
)    (convert_##type##_rte((x)))

Convert the given vector with round to nearest even rounding mode

Parameters
[in]xThe target to be converted
[in]typeThe target type
Returns
The converted vector

Definition at line 52 of file helpers_asymm.h.

◆ DEQUANTIZE

#define DEQUANTIZE (   input,
  offset,
  scale,
  type,
  size 
)     DEQUANTIZE_STR(input, offset, scale, type, size)

Definition at line 435 of file helpers_asymm.h.

◆ DEQUANTIZE_IMPL

#define DEQUANTIZE_IMPL (   type,
  size 
)
Value:
inline VEC_DATA_TYPE(float, size) \
dequantize_##type##size(VEC_DATA_TYPE(type, size) input, float offset, float scale) \
{ \
return (CONVERT(input, VEC_DATA_TYPE(float, size)) - offset) * scale; \
}
__global uchar * offset(const Image *img, int x, int y)
Definition helpers.h:540
#define CONVERT(x, type)
Definition helpers.h:281

Dequantize a vector of values to floating-point

Parameters
[in]typeInput data type.
[in]sizeSize of vector.
Returns
dequantized values in floating point

Definition at line 122 of file helpers_asymm.h.

125 { \
126 return (CONVERT(input, VEC_DATA_TYPE(float, size)) - offset) * scale; \
127 }

◆ DEQUANTIZE_STR

#define DEQUANTIZE_STR (   input,
  offset,
  scale,
  type,
  size 
)     dequantize_##type##size(input, offset, scale)

Definition at line 433 of file helpers_asymm.h.

◆ EXP_BARREL_SHIFTER

#define EXP_BARREL_SHIFTER (   result,
  exponent,
  fp_multiplier,
  k_integer_bits,
  k_fractional_bits,
  remainder,
  size 
)
Value:
exp_barrel_shifter##size(result, exponent, fp_multiplier, k_integer_bits, k_fractional_bits, \
remainder)

Definition at line 451 of file helpers_asymm.h.

◆ EXP_BARREL_SHIFTER_IMPL

#define EXP_BARREL_SHIFTER_IMPL (   size)
Value:
inline VEC_DATA_TYPE(int, size) exp_barrel_shifter##size( \
VEC_DATA_TYPE(int, size) result, int exponent, int fp_multiplier, int k_integer_bits, \
int k_fractional_bits, VEC_DATA_TYPE(int, size) remainder) \
{ \
if (k_integer_bits > exponent) \
{ \
const int k_shift_amount = k_integer_bits > exponent ? k_fractional_bits + exponent : 0; \
ASYMM_MASK_IF_NON_ZERO(remainder & (1 << k_shift_amount), size), \
ASYMM_MULT(result, fp_multiplier, size), result, size); \
} \
\
return result; \
}

Definition at line 264 of file helpers_asymm.h.

268 { \
269 if (k_integer_bits > exponent) \
270 { \
271 const int k_shift_amount = k_integer_bits > exponent ? k_fractional_bits + exponent : 0; \
273 ASYMM_MASK_IF_NON_ZERO(remainder & (1 << k_shift_amount), size), \
274 ASYMM_MULT(result, fp_multiplier, size), result, size); \
275 } \
276 \
277 return result; \
278 }

◆ MULTIPLY_BY_QUANTIZED_MULTIPLIER

#define MULTIPLY_BY_QUANTIZED_MULTIPLIER (   input,
  qmul,
  shift,
  size 
)     multiply_by_quantized_multiplier##size(input, qmul, shift)

Definition at line 474 of file helpers_asymm.h.

◆ MULTIPLY_BY_QUANTIZED_MULTIPLIER_IMPL

#define MULTIPLY_BY_QUANTIZED_MULTIPLIER_IMPL (   size)
Value:
inline VEC_DATA_TYPE(int, size) \
multiply_by_quantized_multiplier##size(VEC_DATA_TYPE(int, size) input, int qmul, int shift) \
{ \
const int left_shift = shift > 0 ? shift : 0; \
const int right_shift = shift > 0 ? 0 : -shift; \
return ASYMM_ROUNDING_DIVIDE_BY_POW2(ASYMM_MULT(input * (1 << left_shift), qmul, size), \
right_shift, size); \
}

Definition at line 465 of file helpers_asymm.h.

468 { \
469 const int left_shift = shift > 0 ? shift : 0; \
470 const int right_shift = shift > 0 ? 0 : -shift; \
471 return ASYMM_ROUNDING_DIVIDE_BY_POW2(ASYMM_MULT(input * (1 << left_shift), qmul, size), \
472 right_shift, size); \
473 }

◆ QUANTIZE

#define QUANTIZE (   input,
  offset,
  scale,
  type,
  size 
)    QUANTIZE_STR(input, offset, scale, type, size)

Definition at line 432 of file helpers_asymm.h.

◆ QUANTIZE_IMPL

#define QUANTIZE_IMPL (   type,
  size 
)
Value:
inline VEC_DATA_TYPE(type, size) \
quantize_##type##size(VEC_DATA_TYPE(float, size) input, float offset, float scale) \
{ \
VEC_DATA_TYPE(float, size) \
out_f32 = input / (VEC_DATA_TYPE(float, size))(scale) + (VEC_DATA_TYPE(float, size))(offset); \
VEC_DATA_TYPE(type, size) \
res = \
CONVERT_SAT(CONVERT_DOWN_RTE(out_f32, VEC_DATA_TYPE(int, size)), VEC_DATA_TYPE(type, size)); \
return res; \
}
#define CONVERT_DOWN_RTE(x, type)

Quantize a vector of values from floating-point

Parameters
[in]typeOutput data type.
[in]sizeSize of vector.
Returns
quantized values

Definition at line 103 of file helpers_asymm.h.

106 { \
107 VEC_DATA_TYPE(float, size) \
108 out_f32 = input / (VEC_DATA_TYPE(float, size))(scale) + (VEC_DATA_TYPE(float, size))(offset); \
109 VEC_DATA_TYPE(type, size) \
110 res = \
111 CONVERT_SAT(CONVERT_DOWN_RTE(out_f32, VEC_DATA_TYPE(int, size)), VEC_DATA_TYPE(type, size)); \
112 return res; \
113 }

◆ QUANTIZE_STR

#define QUANTIZE_STR (   input,
  offset,
  scale,
  type,
  size 
)    quantize_##type##size(input, offset, scale)

Definition at line 431 of file helpers_asymm.h.

Function Documentation

◆ dequantize_qasymm8()

float dequantize_qasymm8 ( uchar  input,
float  offset,
float  scale 
)
inline

Dequantize a scalar value from 8-bit asymmetric to floating-point

Parameters
[in]inputInput value to quantize
[in]offsetQuantization offset
[in]scaleQuantization scale
Returns
quantized value

Definition at line 78 of file helpers_asymm.h.

79{
80 return ((float)input - offset) * scale;
81}

References offset().

◆ dequantize_qasymm8_signed()

float dequantize_qasymm8_signed ( char  input,
float  offset,
float  scale 
)
inline

Dequantize a scalar value from signed 8-bit asymmetric to floating-point

Parameters
[in]inputInput value to quantize
[in]offsetQuantization offset
[in]scaleQuantization scale
Returns
quantized value

Definition at line 91 of file helpers_asymm.h.

92{
93 return ((float)input - offset) * scale;
94}

References offset().

◆ quantize_qasymm8()

uchar quantize_qasymm8 ( float  input,
float  offset,
float  scale 
)
inline

Quantize a floating-point scalar value to 8-bit asymmetric

Parameters
[in]inputInput value to quantize
[in]offsetQuantization offset
[in]scaleQuantization scale
Returns
quantized value

Definition at line 63 of file helpers_asymm.h.

64{
65 float out_f32 = input / scale + offset;
66 uchar res_u8 = CONVERT_SAT(CONVERT_DOWN_RTE(out_f32, int), uchar);
67 return res_u8;
68}
#define CONVERT_SAT(x, type)
Definition helpers.h:284

References CONVERT_DOWN_RTE, CONVERT_SAT, and offset().