blob: 596ec98f6491c1e53731148cc1cc5b6da4a452db [file] [log] [blame]
telsoa014fcda012018-03-09 14:13:49 +00001//
2// Copyright © 2017 Arm Ltd. All rights reserved.
David Beckecb56cd2018-09-05 12:52:57 +01003// SPDX-License-Identifier: MIT
telsoa014fcda012018-03-09 14:13:49 +00004//
Jim Flynne242f2d2019-05-22 14:24:13 +01005
telsoa014fcda012018-03-09 14:13:49 +00006#pragma once
7
Jan Eilers8eb25602020-03-09 12:13:48 +00008#include <armnn/utility/IgnoreUnused.hpp>
telsoa014fcda012018-03-09 14:13:49 +00009#include <armnn/TypesUtils.hpp>
10
Narumol Prangnawarat44179c32020-03-11 14:51:27 +000011#include <BFloat16.hpp>
Matthew Jackson9bff1442019-09-12 09:08:23 +010012#include <Half.hpp>
13
telsoa014fcda012018-03-09 14:13:49 +000014#include <initializer_list>
15#include <iterator>
16#include <vector>
Aron Virginas-Tard4f0fea2019-04-09 14:08:06 +010017
Aron Virginas-Tard4f0fea2019-04-09 14:08:06 +010018#include <boost/numeric/conversion/cast.hpp>
telsoa014fcda012018-03-09 14:13:49 +000019
Aron Virginas-Tar48623a02019-10-22 10:00:28 +010020namespace armnnUtils
21{
22
telsoa014fcda012018-03-09 14:13:49 +000023template<typename T, bool DoQuantize=true>
24struct SelectiveQuantizer
25{
26 static T Quantize(float value, float scale, int32_t offset)
27 {
28 return armnn::Quantize<T>(value, scale, offset);
29 }
30
31 static float Dequantize(T value, float scale, int32_t offset)
32 {
33 return armnn::Dequantize(value, scale, offset);
34 }
35};
36
37template<typename T>
38struct SelectiveQuantizer<T, false>
39{
40 static T Quantize(float value, float scale, int32_t offset)
41 {
Jan Eilers8eb25602020-03-09 12:13:48 +000042 armnn::IgnoreUnused(scale, offset);
telsoa014fcda012018-03-09 14:13:49 +000043 return value;
44 }
45
46 static float Dequantize(T value, float scale, int32_t offset)
47 {
Jan Eilers8eb25602020-03-09 12:13:48 +000048 armnn::IgnoreUnused(scale, offset);
telsoa014fcda012018-03-09 14:13:49 +000049 return value;
50 }
51};
52
Matthew Jackson9bff1442019-09-12 09:08:23 +010053template<>
54struct SelectiveQuantizer<armnn::Half, false>
55{
56 static armnn::Half Quantize(float value, float scale, int32_t offset)
57 {
Jan Eilers8eb25602020-03-09 12:13:48 +000058 armnn::IgnoreUnused(scale, offset);
Matthew Jackson9bff1442019-09-12 09:08:23 +010059 return armnn::Half(value);
60 }
61
62 static float Dequantize(armnn::Half value, float scale, int32_t offset)
63 {
Jan Eilers8eb25602020-03-09 12:13:48 +000064 armnn::IgnoreUnused(scale, offset);
Matthew Jackson9bff1442019-09-12 09:08:23 +010065 return value;
66 }
67};
68
Narumol Prangnawarat44179c32020-03-11 14:51:27 +000069template<>
70struct SelectiveQuantizer<armnn::BFloat16, false>
71{
72 static armnn::BFloat16 Quantize(float value, float scale, int32_t offset)
73 {
74 armnn::IgnoreUnused(scale, offset);
75 return armnn::BFloat16(value);
76 }
77
78 static float Dequantize(armnn::BFloat16 value, float scale, int32_t offset)
79 {
80 armnn::IgnoreUnused(scale, offset);
81 return value;
82 }
83};
84
telsoa014fcda012018-03-09 14:13:49 +000085template<typename T>
86T SelectiveQuantize(float value, float scale, int32_t offset)
87{
88 return SelectiveQuantizer<T, armnn::IsQuantizedType<T>()>::Quantize(value, scale, offset);
89};
90
91template<typename T>
92float SelectiveDequantize(T value, float scale, int32_t offset)
93{
94 return SelectiveQuantizer<T, armnn::IsQuantizedType<T>()>::Dequantize(value, scale, offset);
95};
96
97template<typename ItType>
98struct IsFloatingPointIterator
99{
100 static constexpr bool value=std::is_floating_point<typename std::iterator_traits<ItType>::value_type>::value;
101};
102
103template <typename T, typename FloatIt,
telsoa01c577f2c2018-08-31 09:22:23 +0100104typename std::enable_if<IsFloatingPointIterator<FloatIt>::value, int>::type=0 // Makes sure fp iterator is valid.
telsoa014fcda012018-03-09 14:13:49 +0000105>
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100106std::vector<T> QuantizedVector(FloatIt first, FloatIt last, float qScale, int32_t qOffset)
telsoa014fcda012018-03-09 14:13:49 +0000107{
108 std::vector<T> quantized;
109 quantized.reserve(boost::numeric_cast<size_t>(std::distance(first, last)));
110
111 for (auto it = first; it != last; ++it)
112 {
113 auto f = *it;
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100114 T q = SelectiveQuantize<T>(f, qScale, qOffset);
telsoa014fcda012018-03-09 14:13:49 +0000115 quantized.push_back(q);
116 }
117
118 return quantized;
119}
120
121template<typename T>
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100122std::vector<T> QuantizedVector(const std::vector<float>& array, float qScale = 1.f, int32_t qOffset = 0)
telsoa014fcda012018-03-09 14:13:49 +0000123{
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100124 return QuantizedVector<T>(array.begin(), array.end(), qScale, qOffset);
telsoa014fcda012018-03-09 14:13:49 +0000125}
126
127template<typename T>
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100128std::vector<T> QuantizedVector(std::initializer_list<float> array, float qScale = 1.f, int32_t qOffset = 0)
telsoa014fcda012018-03-09 14:13:49 +0000129{
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100130 return QuantizedVector<T>(array.begin(), array.end(), qScale, qOffset);
telsoa014fcda012018-03-09 14:13:49 +0000131}
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100132
133} // namespace armnnUtils