aboutsummaryrefslogtreecommitdiff
path: root/src/core/utils/quantization/AsymmHelpers.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/utils/quantization/AsymmHelpers.cpp')
-rw-r--r--src/core/utils/quantization/AsymmHelpers.cpp22
1 files changed, 22 insertions, 0 deletions
diff --git a/src/core/utils/quantization/AsymmHelpers.cpp b/src/core/utils/quantization/AsymmHelpers.cpp
index 42bd84db47..cdd48972eb 100644
--- a/src/core/utils/quantization/AsymmHelpers.cpp
+++ b/src/core/utils/quantization/AsymmHelpers.cpp
@@ -22,6 +22,7 @@
* SOFTWARE.
*/
#include "arm_compute/core/utils/quantization/AsymmHelpers.h"
+#include "arm_compute/core/Helpers.h"
#include <cmath>
#include <limits>
@@ -134,5 +135,26 @@ std::pair<int, int> get_min_max_values_from_quantized_data_type(DataType data_ty
}
return std::make_pair(min_quant_val, max_quant_val);
}
+void compute_quantized_multipliers_and_shifts(const ITensor *input, const ITensor *weights, const ITensor *output, int32_t *output_multipliers_ptr, int32_t *output_shifts_ptr)
+{
+ const unsigned int idx_c = get_data_layout_dimension_index(weights->info()->data_layout(), DataLayoutDimension::CHANNEL);
+ const unsigned int num_filters = is_data_type_quantized_per_channel(weights->info()->data_type()) ? weights->info()->dimension(idx_c) : 1;
+
+ const UniformQuantizationInfo iq_info = input->info()->quantization_info().uniform();
+ const QuantizationInfo wq_info = weights->info()->quantization_info();
+ const UniformQuantizationInfo oq_info = output->info()->quantization_info().uniform();
+
+ for(unsigned int i = 0; i < num_filters; ++i)
+ {
+ int output_multiplier = 0;
+ int output_shift = 0;
+ const float multiplier = iq_info.scale * wq_info.scale()[i] / oq_info.scale;
+ ARM_COMPUTE_ERROR_ON(multiplier > 1.0f);
+ calculate_quantized_multiplier_less_than_one(multiplier, &output_multiplier, &output_shift);
+
+ output_multipliers_ptr[i] = output_multiplier;
+ output_shifts_ptr[i] = output_shift;
+ }
+}
} // quantization
} // arm_compute