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