xref: /aosp_15_r20/external/armnn/include/armnnUtils/QuantizeHelper.hpp (revision 89c4ff92f2867872bb9e2354d150bf0c8c502810)
1*89c4ff92SAndroid Build Coastguard Worker //
2*89c4ff92SAndroid Build Coastguard Worker // Copyright © 2017 Arm Ltd. All rights reserved.
3*89c4ff92SAndroid Build Coastguard Worker // SPDX-License-Identifier: MIT
4*89c4ff92SAndroid Build Coastguard Worker //
5*89c4ff92SAndroid Build Coastguard Worker 
6*89c4ff92SAndroid Build Coastguard Worker #pragma once
7*89c4ff92SAndroid Build Coastguard Worker 
8*89c4ff92SAndroid Build Coastguard Worker #include <armnn/utility/IgnoreUnused.hpp>
9*89c4ff92SAndroid Build Coastguard Worker #include <armnn/utility/NumericCast.hpp>
10*89c4ff92SAndroid Build Coastguard Worker #include <armnn/TypesUtils.hpp>
11*89c4ff92SAndroid Build Coastguard Worker 
12*89c4ff92SAndroid Build Coastguard Worker #include <BFloat16.hpp>
13*89c4ff92SAndroid Build Coastguard Worker #include <Half.hpp>
14*89c4ff92SAndroid Build Coastguard Worker 
15*89c4ff92SAndroid Build Coastguard Worker #include <initializer_list>
16*89c4ff92SAndroid Build Coastguard Worker #include <iterator>
17*89c4ff92SAndroid Build Coastguard Worker #include <vector>
18*89c4ff92SAndroid Build Coastguard Worker 
19*89c4ff92SAndroid Build Coastguard Worker namespace armnnUtils
20*89c4ff92SAndroid Build Coastguard Worker {
21*89c4ff92SAndroid Build Coastguard Worker 
22*89c4ff92SAndroid Build Coastguard Worker template<typename T, bool DoQuantize=true>
23*89c4ff92SAndroid Build Coastguard Worker struct SelectiveQuantizer
24*89c4ff92SAndroid Build Coastguard Worker {
QuantizearmnnUtils::SelectiveQuantizer25*89c4ff92SAndroid Build Coastguard Worker     static T Quantize(float value, float scale, int32_t offset)
26*89c4ff92SAndroid Build Coastguard Worker     {
27*89c4ff92SAndroid Build Coastguard Worker         return armnn::Quantize<T>(value, scale, offset);
28*89c4ff92SAndroid Build Coastguard Worker     }
29*89c4ff92SAndroid Build Coastguard Worker 
DequantizearmnnUtils::SelectiveQuantizer30*89c4ff92SAndroid Build Coastguard Worker     static float Dequantize(T value, float scale, int32_t offset)
31*89c4ff92SAndroid Build Coastguard Worker     {
32*89c4ff92SAndroid Build Coastguard Worker         return armnn::Dequantize(value, scale, offset);
33*89c4ff92SAndroid Build Coastguard Worker     }
34*89c4ff92SAndroid Build Coastguard Worker };
35*89c4ff92SAndroid Build Coastguard Worker 
36*89c4ff92SAndroid Build Coastguard Worker template<typename T>
37*89c4ff92SAndroid Build Coastguard Worker struct SelectiveQuantizer<T, false>
38*89c4ff92SAndroid Build Coastguard Worker {
QuantizearmnnUtils::SelectiveQuantizer39*89c4ff92SAndroid Build Coastguard Worker     static T Quantize(float value, float scale, int32_t offset)
40*89c4ff92SAndroid Build Coastguard Worker     {
41*89c4ff92SAndroid Build Coastguard Worker         armnn::IgnoreUnused(scale, offset);
42*89c4ff92SAndroid Build Coastguard Worker         return value;
43*89c4ff92SAndroid Build Coastguard Worker     }
44*89c4ff92SAndroid Build Coastguard Worker 
DequantizearmnnUtils::SelectiveQuantizer45*89c4ff92SAndroid Build Coastguard Worker     static float Dequantize(T value, float scale, int32_t offset)
46*89c4ff92SAndroid Build Coastguard Worker     {
47*89c4ff92SAndroid Build Coastguard Worker         armnn::IgnoreUnused(scale, offset);
48*89c4ff92SAndroid Build Coastguard Worker         return value;
49*89c4ff92SAndroid Build Coastguard Worker     }
50*89c4ff92SAndroid Build Coastguard Worker };
51*89c4ff92SAndroid Build Coastguard Worker 
52*89c4ff92SAndroid Build Coastguard Worker template<>
53*89c4ff92SAndroid Build Coastguard Worker struct SelectiveQuantizer<armnn::Half, false>
54*89c4ff92SAndroid Build Coastguard Worker {
QuantizearmnnUtils::SelectiveQuantizer55*89c4ff92SAndroid Build Coastguard Worker     static armnn::Half Quantize(float value, float scale, int32_t offset)
56*89c4ff92SAndroid Build Coastguard Worker     {
57*89c4ff92SAndroid Build Coastguard Worker         armnn::IgnoreUnused(scale, offset);
58*89c4ff92SAndroid Build Coastguard Worker         return armnn::Half(value);
59*89c4ff92SAndroid Build Coastguard Worker     }
60*89c4ff92SAndroid Build Coastguard Worker 
DequantizearmnnUtils::SelectiveQuantizer61*89c4ff92SAndroid Build Coastguard Worker     static float Dequantize(armnn::Half value, float scale, int32_t offset)
62*89c4ff92SAndroid Build Coastguard Worker     {
63*89c4ff92SAndroid Build Coastguard Worker         armnn::IgnoreUnused(scale, offset);
64*89c4ff92SAndroid Build Coastguard Worker         return value;
65*89c4ff92SAndroid Build Coastguard Worker     }
66*89c4ff92SAndroid Build Coastguard Worker };
67*89c4ff92SAndroid Build Coastguard Worker 
68*89c4ff92SAndroid Build Coastguard Worker template<>
69*89c4ff92SAndroid Build Coastguard Worker struct SelectiveQuantizer<armnn::BFloat16, false>
70*89c4ff92SAndroid Build Coastguard Worker {
QuantizearmnnUtils::SelectiveQuantizer71*89c4ff92SAndroid Build Coastguard Worker     static armnn::BFloat16 Quantize(float value, float scale, int32_t offset)
72*89c4ff92SAndroid Build Coastguard Worker     {
73*89c4ff92SAndroid Build Coastguard Worker         armnn::IgnoreUnused(scale, offset);
74*89c4ff92SAndroid Build Coastguard Worker         return armnn::BFloat16(value);
75*89c4ff92SAndroid Build Coastguard Worker     }
76*89c4ff92SAndroid Build Coastguard Worker 
DequantizearmnnUtils::SelectiveQuantizer77*89c4ff92SAndroid Build Coastguard Worker     static float Dequantize(armnn::BFloat16 value, float scale, int32_t offset)
78*89c4ff92SAndroid Build Coastguard Worker     {
79*89c4ff92SAndroid Build Coastguard Worker         armnn::IgnoreUnused(scale, offset);
80*89c4ff92SAndroid Build Coastguard Worker         return value;
81*89c4ff92SAndroid Build Coastguard Worker     }
82*89c4ff92SAndroid Build Coastguard Worker };
83*89c4ff92SAndroid Build Coastguard Worker 
84*89c4ff92SAndroid Build Coastguard Worker template<typename T>
SelectiveQuantize(float value,float scale,int32_t offset)85*89c4ff92SAndroid Build Coastguard Worker T SelectiveQuantize(float value, float scale, int32_t offset)
86*89c4ff92SAndroid Build Coastguard Worker {
87*89c4ff92SAndroid Build Coastguard Worker     return SelectiveQuantizer<T, armnn::IsQuantizedType<T>()>::Quantize(value, scale, offset);
88*89c4ff92SAndroid Build Coastguard Worker };
89*89c4ff92SAndroid Build Coastguard Worker 
90*89c4ff92SAndroid Build Coastguard Worker template<typename T>
SelectiveDequantize(T value,float scale,int32_t offset)91*89c4ff92SAndroid Build Coastguard Worker float SelectiveDequantize(T value, float scale, int32_t offset)
92*89c4ff92SAndroid Build Coastguard Worker {
93*89c4ff92SAndroid Build Coastguard Worker     return SelectiveQuantizer<T, armnn::IsQuantizedType<T>()>::Dequantize(value, scale, offset);
94*89c4ff92SAndroid Build Coastguard Worker };
95*89c4ff92SAndroid Build Coastguard Worker 
96*89c4ff92SAndroid Build Coastguard Worker template<typename ItType>
97*89c4ff92SAndroid Build Coastguard Worker struct IsFloatingPointIterator
98*89c4ff92SAndroid Build Coastguard Worker {
99*89c4ff92SAndroid Build Coastguard Worker     static constexpr bool value=std::is_floating_point<typename std::iterator_traits<ItType>::value_type>::value;
100*89c4ff92SAndroid Build Coastguard Worker };
101*89c4ff92SAndroid Build Coastguard Worker 
102*89c4ff92SAndroid Build Coastguard Worker template <typename T, typename FloatIt,
103*89c4ff92SAndroid Build Coastguard Worker typename std::enable_if<IsFloatingPointIterator<FloatIt>::value, int>::type=0 // Makes sure fp iterator is valid.
104*89c4ff92SAndroid Build Coastguard Worker >
QuantizedVector(FloatIt first,FloatIt last,float qScale,int32_t qOffset)105*89c4ff92SAndroid Build Coastguard Worker std::vector<T> QuantizedVector(FloatIt first, FloatIt last, float qScale, int32_t qOffset)
106*89c4ff92SAndroid Build Coastguard Worker {
107*89c4ff92SAndroid Build Coastguard Worker     std::vector<T> quantized;
108*89c4ff92SAndroid Build Coastguard Worker     quantized.reserve(armnn::numeric_cast<size_t>(std::distance(first, last)));
109*89c4ff92SAndroid Build Coastguard Worker 
110*89c4ff92SAndroid Build Coastguard Worker     for (auto it = first; it != last; ++it)
111*89c4ff92SAndroid Build Coastguard Worker     {
112*89c4ff92SAndroid Build Coastguard Worker         auto f = *it;
113*89c4ff92SAndroid Build Coastguard Worker         T q = SelectiveQuantize<T>(f, qScale, qOffset);
114*89c4ff92SAndroid Build Coastguard Worker         quantized.push_back(q);
115*89c4ff92SAndroid Build Coastguard Worker     }
116*89c4ff92SAndroid Build Coastguard Worker 
117*89c4ff92SAndroid Build Coastguard Worker     return quantized;
118*89c4ff92SAndroid Build Coastguard Worker }
119*89c4ff92SAndroid Build Coastguard Worker 
120*89c4ff92SAndroid Build Coastguard Worker template<typename T>
QuantizedVector(const std::vector<float> & array,float qScale=1.f,int32_t qOffset=0)121*89c4ff92SAndroid Build Coastguard Worker std::vector<T> QuantizedVector(const std::vector<float>& array, float qScale = 1.f, int32_t qOffset = 0)
122*89c4ff92SAndroid Build Coastguard Worker {
123*89c4ff92SAndroid Build Coastguard Worker     return QuantizedVector<T>(array.begin(), array.end(), qScale, qOffset);
124*89c4ff92SAndroid Build Coastguard Worker }
125*89c4ff92SAndroid Build Coastguard Worker 
126*89c4ff92SAndroid Build Coastguard Worker template<typename T>
QuantizedVector(std::initializer_list<float> array,float qScale=1.f,int32_t qOffset=0)127*89c4ff92SAndroid Build Coastguard Worker std::vector<T> QuantizedVector(std::initializer_list<float> array, float qScale = 1.f, int32_t qOffset = 0)
128*89c4ff92SAndroid Build Coastguard Worker {
129*89c4ff92SAndroid Build Coastguard Worker     return QuantizedVector<T>(array.begin(), array.end(), qScale, qOffset);
130*89c4ff92SAndroid Build Coastguard Worker }
131*89c4ff92SAndroid Build Coastguard Worker 
132*89c4ff92SAndroid Build Coastguard Worker } // namespace armnnUtils
133