1 /* 2 * Copyright (c) 2017-2021 Arm Limited. 3 * 4 * SPDX-License-Identifier: MIT 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a copy 7 * of this software and associated documentation files (the "Software"), to 8 * deal in the Software without restriction, including without limitation the 9 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 10 * sell copies of the Software, and to permit persons to whom the Software is 11 * furnished to do so, subject to the following conditions: 12 * 13 * The above copyright notice and this permission notice shall be included in all 14 * copies or substantial portions of the Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 * SOFTWARE. 23 */ 24 #ifndef ARM_COMPUTE_QUANTIZATION_ASYMM_HELPERS_H 25 #define ARM_COMPUTE_QUANTIZATION_ASYMM_HELPERS_H 26 27 #include "arm_compute/core/Error.h" 28 #include "arm_compute/core/ITensor.h" 29 #include "arm_compute/core/Types.h" 30 31 namespace arm_compute 32 { 33 namespace quantization 34 { 35 /** Calculate quantized representation of multiplier. 36 * 37 * @param[in] multiplier Real multiplier. 38 * @param[out] quant_multiplier Integer multiplier. 39 * @param[out] shift bit shift. A negative value indicates a left shift, while a positive value indicates a right shift 40 * @param[in] ignore_epsilon When true, ignore pre-defined epsilon value. Defaults to false 41 * 42 * @return a status 43 */ 44 Status calculate_quantized_multiplier(float multiplier, int32_t *quant_multiplier, int32_t *shift, bool ignore_epsilon = false); 45 /** Calculate quantized representation of multiplier with value less than one. 46 * 47 * @param[in] multiplier Real multiplier. 48 * @param[out] quant_multiplier Integer multiplier. 49 * @param[out] right_shift Right bit shift. 50 * @param[in] ignore_epsilon When true, ignore pre-defined epsilon value. Defaults to false 51 * 52 * @return a status 53 */ 54 Status calculate_quantized_multiplier_less_than_one(float multiplier, int32_t *quant_multiplier, int32_t *right_shift, bool ignore_epsilon = false); 55 /** Calculate quantized representation of multiplier having value greater than one. 56 * 57 * @param[in] multiplier Real multiplier. 58 * @param[out] quantized_multiplier Integer multiplier. 59 * @param[out] left_shift Left bit shift. 60 * 61 * @return a status 62 */ 63 Status calculate_quantized_multiplier_greater_than_one(float multiplier, int32_t *quantized_multiplier, int32_t *left_shift); 64 65 /** Calculate quantized representation of per-channel multipliers 66 * 67 * @param[in] iq_info Input quantization info. 68 * @param[in] wq_info Weights quantization info. 69 * @param[in] oq_info Output quantization info. 70 * @param[in, out] stage_info GemmLowp output stage info 71 * 72 * @return a status 73 */ 74 Status calculate_quantized_multipliers(const QuantizationInfo &iq_info, 75 const QuantizationInfo &wq_info, 76 const QuantizationInfo &oq_info, 77 GEMMLowpOutputStageInfo &stage_info); 78 79 /** Get minimum and maximum values for the input quantized data type 80 * 81 * @return min and max values for the quantized data type 82 */ 83 std::pair<int, int> get_min_max_values_from_quantized_data_type(DataType data_type); 84 /** Compute quantized per-channel multipliers and shifts. As many multipliers 85 * and shifts as output channels are computed. If weights are not quantized 86 * per-channel, multipliers and shifts will end up being the same for each 87 * channel. 88 * 89 * @param[in] input Input tensor info. 90 * @param[in] weights Weights tensor info. 91 * @param[in] output Output tensor info. 92 * @param[out] output_multipliers_ptr Pointer to the buffer where to store per-channel multipliers. 93 * @param[out] output_shifts_ptr Pointer to the buffer where to store per-channel shifts. 94 * 95 * @return min and max values for the quantized data type 96 */ 97 void compute_quantized_multipliers_and_shifts(const ITensorInfo *input, 98 const ITensorInfo *weights, 99 const ITensorInfo *output, 100 int32_t *output_multipliers_ptr, 101 int32_t *output_shifts_ptr); 102 103 /** Round to the nearest division by a power-of-two using exponent, copied from NEMath 104 * 105 * @note This function calculates the following expression: (x + 2^n -1 ) / 2^n where n = exponent 106 * 107 * @param[in] x Element to divide. 108 * @param[in] exponent Integer value used to round to nearest division by a power-of-two 109 * 110 * @return the nearest division by a power-of-two using exponent 111 */ 112 int32_t rounding_divide_by_pow2(int32_t x, int exponent); 113 114 /** Compute multiplication of two integers 115 * 116 * @param[in] a One integer to multiply 117 * @param[in] b Another integer to multiply 118 * 119 * @return The multiplied value 120 */ 121 int32_t saturating_rounding_doubling_highmul(int32_t a, int32_t b); 122 123 /** Compute the value multiplied by given quantized multiplier and shift 124 * 125 * @param[in] input Target value to multiply. 126 * @param[in] qmul Quantized multipler 127 * @param[in] shift Left bit shift 128 * 129 * @return The multiplied value 130 */ 131 int32_t multiply_by_quantized_multiplier(int32_t input, int32_t qmul, int32_t shift); 132 133 /** Compute the value multiplied the power-of-two 134 * 135 * @param[in] exponent Exponent used to calculate power-of-two 136 * @param[in] v Target value to multiply 137 * 138 * @return The multiplied value 139 */ 140 int32_t saturating_rounding_multiply_by_pow2(int32_t exponent, int32_t v); 141 142 /** Compute quantized multiplier and shift for the inverse square root of input. 143 * Using 3-bit fixed point and 5 iteration of Newton-Raphson method. 144 * 145 * @param[in] input Input to use 146 * @param[in] reverse_shift -1 to reverse the shift direction 147 * @param[out] output_inv_sqrt Quantized multiplier for inverse square root 148 * @param[out] output_shift Shift for inverse square root 149 * 150 */ 151 void get_invsqrt_quantized_multiplier_exp(int32_t input, int32_t reverse_shift, int32_t &output_inv_sqrt, int32_t &output_shift); 152 153 } // namespace quantization 154 } // namespace arm_compute 155 #endif /* ARM_COMPUTE_IO_FILE_HANDLER_H */ 156