xref: /aosp_15_r20/external/ComputeLibrary/arm_compute/core/utils/quantization/AsymmHelpers.h (revision c217d954acce2dbc11938adb493fc0abd69584f3)
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