blob: 5c5fff39d6f7c51afc748a7c00d3d4034e8d1154 [file] [log] [blame]
Sadik Armagan2e6dc3a2019-04-03 17:48:18 +01001//
Colm Donelanb4ef1632024-02-01 15:00:43 +00002// Copyright © 2017-2024 Arm Ltd and Contributors. All rights reserved.
Sadik Armagan2e6dc3a2019-04-03 17:48:18 +01003// SPDX-License-Identifier: MIT
4//
5
6#pragma once
7
Matthew Bentham246bd462020-01-20 16:16:06 +00008#include <armnn/TypesUtils.hpp>
Jan Eilers53ef7952021-06-02 12:01:25 +01009#include <armnn/utility/NumericCast.hpp>
Matteo Martincighe011d202019-11-28 11:35:47 +000010#include <armnnUtils/FloatingPointConverter.hpp>
Jan Eilers53ef7952021-06-02 12:01:25 +010011#include <armnnUtils/TensorUtils.hpp>
Matteo Martincighe011d202019-11-28 11:35:47 +000012
Aron Virginas-Tard4f0fea2019-04-09 14:08:06 +010013#include <ResolveType.hpp>
Sadik Armagan2e6dc3a2019-04-03 17:48:18 +010014
15namespace armnn
16{
17
18class BaseIterator
19{
20public:
21 BaseIterator() {}
22
23 virtual ~BaseIterator() {}
24
25 virtual BaseIterator& operator++() = 0;
26
27 virtual BaseIterator& operator+=(const unsigned int increment) = 0;
28
29 virtual BaseIterator& operator-=(const unsigned int increment) = 0;
Francis Murtagh43aec582019-05-27 12:14:10 +010030
31 virtual BaseIterator& operator[](const unsigned int index) = 0;
Sadik Armagan2e6dc3a2019-04-03 17:48:18 +010032};
33
Derek Lambertif30f7d32019-04-09 10:25:02 +010034template<typename IType>
Sadik Armagan2e6dc3a2019-04-03 17:48:18 +010035class Decoder : public BaseIterator
36{
37public:
Derek Lambertif30f7d32019-04-09 10:25:02 +010038 Decoder() {}
Sadik Armagan2e6dc3a2019-04-03 17:48:18 +010039
40 virtual ~Decoder() {}
41
Matthew Benthamc394a6d2019-06-24 12:51:25 +010042 virtual void Reset(void*) = 0;
43
Derek Lambertif30f7d32019-04-09 10:25:02 +010044 virtual IType Get() const = 0;
Finn Williamsb9dcfe62020-09-17 15:58:31 +010045
Teresa Charlin5306dc82023-10-30 22:29:58 +000046 virtual std::vector<float> DecodeTensor(const TensorShape &tensorShape, bool isDepthwise = false) = 0;
Sadik Armagan2e6dc3a2019-04-03 17:48:18 +010047};
48
Derek Lambertif30f7d32019-04-09 10:25:02 +010049template<typename IType>
Sadik Armagan2e6dc3a2019-04-03 17:48:18 +010050class Encoder : public BaseIterator
51{
52public:
Derek Lambertif30f7d32019-04-09 10:25:02 +010053 Encoder() {}
Sadik Armagan2e6dc3a2019-04-03 17:48:18 +010054
55 virtual ~Encoder() {}
56
Matthew Benthamc394a6d2019-06-24 12:51:25 +010057 virtual void Reset(void*) = 0;
58
Derek Lambertif30f7d32019-04-09 10:25:02 +010059 virtual void Set(IType right) = 0;
Nattapat Chaimanowongeb2b3292019-05-07 12:02:30 +010060
61 virtual IType Get() const = 0;
Sadik Armagan2e6dc3a2019-04-03 17:48:18 +010062};
63
64template<typename T, typename Base>
65class TypedIterator : public Base
66{
67public:
Matthew Benthamc394a6d2019-06-24 12:51:25 +010068 TypedIterator(T* data = nullptr)
Francis Murtagh43aec582019-05-27 12:14:10 +010069 : m_Iterator(data), m_Start(data)
Sadik Armagan2e6dc3a2019-04-03 17:48:18 +010070 {}
71
Matthew Benthamc394a6d2019-06-24 12:51:25 +010072 void Reset(void* data) override
73 {
74 m_Iterator = reinterpret_cast<T*>(data);
75 m_Start = m_Iterator;
76 }
77
Sadik Armagan2e6dc3a2019-04-03 17:48:18 +010078 TypedIterator& operator++() override
79 {
Colm Donelanb4ef1632024-02-01 15:00:43 +000080 ARMNN_THROW_INVALIDARG_MSG_IF_FALSE(m_Iterator, "TypedIterator: m_Iterator is null!");
Sadik Armagan2e6dc3a2019-04-03 17:48:18 +010081 ++m_Iterator;
82 return *this;
83 }
84
85 TypedIterator& operator+=(const unsigned int increment) override
86 {
Colm Donelanb4ef1632024-02-01 15:00:43 +000087 ARMNN_THROW_INVALIDARG_MSG_IF_FALSE(m_Iterator, "TypedIterator: m_Iterator is null!");
Sadik Armagan2e6dc3a2019-04-03 17:48:18 +010088 m_Iterator += increment;
89 return *this;
90 }
91
92 TypedIterator& operator-=(const unsigned int increment) override
93 {
Colm Donelanb4ef1632024-02-01 15:00:43 +000094 ARMNN_THROW_INVALIDARG_MSG_IF_FALSE(m_Iterator, "TypedIterator: m_Iterator is null!");
Sadik Armagan2e6dc3a2019-04-03 17:48:18 +010095 m_Iterator -= increment;
96 return *this;
97 }
98
Francis Murtagh43aec582019-05-27 12:14:10 +010099 TypedIterator& operator[](const unsigned int index) override
100 {
Colm Donelanb4ef1632024-02-01 15:00:43 +0000101 ARMNN_THROW_INVALIDARG_MSG_IF_FALSE(m_Iterator, "TypedIterator: m_Iterator is null!");
Francis Murtagh43aec582019-05-27 12:14:10 +0100102 m_Iterator = m_Start + index;
103 return *this;
104 }
105
Nattapat Chaimanowongeb2b3292019-05-07 12:02:30 +0100106protected:
Sadik Armagan2e6dc3a2019-04-03 17:48:18 +0100107 T* m_Iterator;
Francis Murtagh43aec582019-05-27 12:14:10 +0100108 T* m_Start;
Sadik Armagan2e6dc3a2019-04-03 17:48:18 +0100109};
110
Derek Lambertif30f7d32019-04-09 10:25:02 +0100111class QASymm8Decoder : public TypedIterator<const uint8_t, Decoder<float>>
Sadik Armagan2e6dc3a2019-04-03 17:48:18 +0100112{
113public:
114 QASymm8Decoder(const uint8_t* data, const float scale, const int32_t offset)
115 : TypedIterator(data), m_Scale(scale), m_Offset(offset) {}
116
Matthew Benthamc394a6d2019-06-24 12:51:25 +0100117 QASymm8Decoder(const float scale, const int32_t offset)
118 : QASymm8Decoder(nullptr, scale, offset) {}
119
Sadik Armagan2e6dc3a2019-04-03 17:48:18 +0100120 float Get() const override
121 {
122 return armnn::Dequantize(*m_Iterator, m_Scale, m_Offset);
123 }
Teresa Charlin5306dc82023-10-30 22:29:58 +0000124 std::vector<float> DecodeTensor (const TensorShape& tensorShape, const bool) override
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100125 {
Finn Williamsea8ce702020-09-29 19:54:00 +0100126 const unsigned int size = tensorShape.GetNumElements();
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100127 std::vector<float> decodedTensor;
128 decodedTensor.reserve(size);
129
130 for (uint32_t i = 0; i < size; ++i)
131 {
132 this->operator[](i);
133 decodedTensor.emplace_back(armnn::Dequantize(*m_Iterator, m_Scale, m_Offset));
134 }
135
136 return decodedTensor;
137 }
138
Sadik Armagan2e6dc3a2019-04-03 17:48:18 +0100139private:
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100140
Sadik Armagan2e6dc3a2019-04-03 17:48:18 +0100141 const float m_Scale;
142 const int32_t m_Offset;
143};
144
Ryan OShea9add1202020-02-07 10:06:33 +0000145class QASymmS8Decoder : public TypedIterator<const int8_t, Decoder<float>>
146{
147public:
148 QASymmS8Decoder(const int8_t* data, const float scale, const int32_t offset)
149 : TypedIterator(data), m_Scale(scale), m_Offset(offset) {}
150
151 QASymmS8Decoder(const float scale, const int32_t offset)
152 : QASymmS8Decoder(nullptr, scale, offset) {}
153
154 float Get() const override
155 {
156 return armnn::Dequantize(*m_Iterator, m_Scale, m_Offset);
157 }
Teresa Charlin5306dc82023-10-30 22:29:58 +0000158 std::vector<float> DecodeTensor (const TensorShape& tensorShape, const bool) override
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100159 {
Finn Williamsea8ce702020-09-29 19:54:00 +0100160 const unsigned int size = tensorShape.GetNumElements();
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100161 std::vector<float> decodedTensor;
162 decodedTensor.reserve(size);
163
164 for (uint32_t i = 0; i < size; ++i)
165 {
166 this->operator[](i);
167 decodedTensor.emplace_back(armnn::Dequantize(*m_Iterator, m_Scale, m_Offset));
168 }
169
170 return decodedTensor;
171 }
172
Ryan OShea9add1202020-02-07 10:06:33 +0000173private:
174 const float m_Scale;
175 const int32_t m_Offset;
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100176
Ryan OShea9add1202020-02-07 10:06:33 +0000177};
178
Finn Williamsfd271062019-12-04 14:27:27 +0000179class QSymmS8Decoder : public TypedIterator<const int8_t, Decoder<float>>
180{
181public:
182 QSymmS8Decoder(const int8_t* data, const float scale, const int32_t offset)
183 : TypedIterator(data), m_Scale(scale), m_Offset(offset) {}
184
185 QSymmS8Decoder(const float scale, const int32_t offset)
186 : QSymmS8Decoder(nullptr, scale, offset) {}
187
188 float Get() const override
189 {
190 return armnn::Dequantize(*m_Iterator, m_Scale, m_Offset);
191 }
Teresa Charlin5306dc82023-10-30 22:29:58 +0000192 std::vector<float> DecodeTensor (const TensorShape& tensorShape, const bool) override
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100193 {
Finn Williamsea8ce702020-09-29 19:54:00 +0100194 const unsigned int size = tensorShape.GetNumElements();
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100195 std::vector<float> decodedTensor;
196 decodedTensor.reserve(size);
197
198 for (uint32_t i = 0; i < size; ++i)
199 {
200 this->operator[](i);
201 decodedTensor.emplace_back(armnn::Dequantize(*m_Iterator, m_Scale, m_Offset));
202 }
203
204 return decodedTensor;
205 }
206
Finn Williamsfd271062019-12-04 14:27:27 +0000207private:
208 const float m_Scale;
209 const int32_t m_Offset;
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100210
Finn Williamsfd271062019-12-04 14:27:27 +0000211};
212
Derek Lambertif30f7d32019-04-09 10:25:02 +0100213class QSymm16Decoder : public TypedIterator<const int16_t, Decoder<float>>
Sadik Armagan2999a022019-04-09 14:20:12 +0100214{
215public:
216 QSymm16Decoder(const int16_t* data, const float scale, const int32_t offset)
217 : TypedIterator(data), m_Scale(scale), m_Offset(offset) {}
218
Matthew Benthamc394a6d2019-06-24 12:51:25 +0100219 QSymm16Decoder(const float scale, const int32_t offset)
220 : QSymm16Decoder(nullptr, scale, offset) {}
221
Sadik Armagan2999a022019-04-09 14:20:12 +0100222 float Get() const override
223 {
224 return armnn::Dequantize(*m_Iterator, m_Scale, m_Offset);
225 }
Teresa Charlin5306dc82023-10-30 22:29:58 +0000226 std::vector<float> DecodeTensor (const TensorShape& tensorShape, const bool) override
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100227 {
Finn Williamsea8ce702020-09-29 19:54:00 +0100228 const unsigned int size = tensorShape.GetNumElements();
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100229 std::vector<float> decodedTensor;
230 decodedTensor.reserve(size);
231
232 for (uint32_t i = 0; i < size; ++i)
233 {
234 this->operator[](i);
235 decodedTensor.emplace_back(armnn::Dequantize(*m_Iterator, m_Scale, m_Offset));
236 }
237
238 return decodedTensor;
239 }
240
Sadik Armagan2999a022019-04-09 14:20:12 +0100241private:
242 const float m_Scale;
243 const int32_t m_Offset;
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100244
Sadik Armagan2999a022019-04-09 14:20:12 +0100245};
246
Matthew Jacksone69c3992019-09-09 14:31:21 +0100247class Float16Decoder : public TypedIterator<const Half, Decoder<float>>
Sadik Armagan2e6dc3a2019-04-03 17:48:18 +0100248{
249public:
Matthew Jacksone69c3992019-09-09 14:31:21 +0100250 Float16Decoder(const Half* data)
Sadik Armagan2e6dc3a2019-04-03 17:48:18 +0100251 : TypedIterator(data) {}
252
Matthew Jacksone69c3992019-09-09 14:31:21 +0100253 Float16Decoder()
254 : Float16Decoder(nullptr) {}
255
256 float Get() const override
257 {
258 float val = 0.f;
259 armnnUtils::FloatingPointConverter::ConvertFloat16To32(m_Iterator, 1, &val);
260 return val;
261 }
Teresa Charlin5306dc82023-10-30 22:29:58 +0000262 std::vector<float> DecodeTensor (const TensorShape& tensorShape, const bool ) override
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100263 {
Finn Williamsea8ce702020-09-29 19:54:00 +0100264 const unsigned int size = tensorShape.GetNumElements();
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100265 std::vector<float> decodedTensor;
266 decodedTensor.reserve(size);
267
268 for (uint32_t i = 0; i < size; ++i)
269 {
270 float val = 0.f;
271 this->operator[](i);
272 armnnUtils::FloatingPointConverter::ConvertFloat16To32(m_Iterator, 1, &val);
273 decodedTensor.emplace_back(val);
274 }
275
276 return decodedTensor;
277 }
278
279
Matthew Jacksone69c3992019-09-09 14:31:21 +0100280};
281
282class Float32Decoder : public TypedIterator<const float, Decoder<float>>
283{
284public:
285 Float32Decoder(const float* data)
286 : TypedIterator(data) {}
287
288 Float32Decoder()
289 : Float32Decoder(nullptr) {}
Matthew Benthamc394a6d2019-06-24 12:51:25 +0100290
Derek Lambertif30f7d32019-04-09 10:25:02 +0100291 float Get() const override
Sadik Armagan2e6dc3a2019-04-03 17:48:18 +0100292 {
Derek Lambertif30f7d32019-04-09 10:25:02 +0100293 return *m_Iterator;
Sadik Armagan2e6dc3a2019-04-03 17:48:18 +0100294 }
Teresa Charlin5306dc82023-10-30 22:29:58 +0000295 std::vector<float> DecodeTensor (const TensorShape& tensorShape, const bool) override
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100296 {
Finn Williamsea8ce702020-09-29 19:54:00 +0100297 const unsigned int size = tensorShape.GetNumElements();
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100298 std::vector<float> decodedTensor;
299
300 decodedTensor.reserve(size);
301 decodedTensor.assign(m_Start, m_Start + size);
302
303 return decodedTensor;
304 }
Sadik Armagan2e6dc3a2019-04-03 17:48:18 +0100305};
306
Mike Kelly9b398322019-05-22 17:21:49 +0100307class ScaledInt32Decoder : public TypedIterator<const int32_t, Decoder<float>>
308{
309public:
310 ScaledInt32Decoder(const int32_t* data, const float scale)
311 : TypedIterator(data), m_Scale(scale) {}
312
Matthew Benthamc394a6d2019-06-24 12:51:25 +0100313 ScaledInt32Decoder(const float scale)
314 : ScaledInt32Decoder(nullptr, scale) {}
315
Mike Kelly9b398322019-05-22 17:21:49 +0100316 float Get() const override
317 {
318 return static_cast<float>(*m_Iterator) * m_Scale;
319 }
Teresa Charlin5306dc82023-10-30 22:29:58 +0000320 std::vector<float> DecodeTensor (const TensorShape& tensorShape, const bool) override
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100321 {
Finn Williamsea8ce702020-09-29 19:54:00 +0100322 const unsigned int size = tensorShape.GetNumElements();
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100323 std::vector<float> decodedTensor;
324 decodedTensor.reserve(size);
325
326 for (uint32_t i = 0; i < size; ++i)
327 {
328 this->operator[](i);
329 decodedTensor.emplace_back(static_cast<float>(*m_Iterator) * m_Scale);
330 }
331
332 return decodedTensor;
333 }
334
Mike Kelly9b398322019-05-22 17:21:49 +0100335private:
336 const float m_Scale;
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100337
Mike Kelly9b398322019-05-22 17:21:49 +0100338};
339
Aron Virginas-Tar198ee402019-08-02 18:54:28 +0100340class Int32Decoder : public TypedIterator<const int32_t, Decoder<float>>
341{
342public:
343 Int32Decoder(const int32_t* data)
344 : TypedIterator(data) {}
345
346 Int32Decoder()
347 : Int32Decoder(nullptr) {}
348
349 float Get() const override
350 {
351 return static_cast<float>(*m_Iterator);
352 }
Teresa Charlin5306dc82023-10-30 22:29:58 +0000353 std::vector<float> DecodeTensor (const TensorShape& tensorShape, const bool) override
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100354 {
Finn Williamsea8ce702020-09-29 19:54:00 +0100355 const unsigned int size = tensorShape.GetNumElements();
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100356 std::vector<float> decodedTensor;
357 decodedTensor.reserve(size);
358
359 for (uint32_t i = 0; i < size; ++i)
360 {
361 this->operator[](i);
362 decodedTensor.emplace_back(static_cast<float>(*m_Iterator));
363 }
364
365 return decodedTensor;
366 }
Aron Virginas-Tar198ee402019-08-02 18:54:28 +0100367};
368
Finn Williamscbd2c232020-06-22 15:58:32 +0100369class Int32ToInt32tDecoder : public TypedIterator<const int32_t, Decoder<int32_t>>
370{
371public:
372 Int32ToInt32tDecoder(const int32_t* data)
373 : TypedIterator(data){}
374
375 Int32ToInt32tDecoder()
376 : Int32ToInt32tDecoder(nullptr) {}
377
378 int32_t Get() const override
379 {
380 return *m_Iterator;
381 }
Teresa Charlin5306dc82023-10-30 22:29:58 +0000382 std::vector<float> DecodeTensor (const TensorShape& tensorShape, const bool) override
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100383 {
Teresa Charlin5306dc82023-10-30 22:29:58 +0000384 const unsigned int size = tensorShape.GetNumElements();
385 std::vector<float> decodedTensor;
386 decodedTensor.reserve(size);
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100387
Teresa Charlin5306dc82023-10-30 22:29:58 +0000388 for (uint32_t i = 0; i < size; ++i)
389 {
390 this->operator[](i);
391 decodedTensor.emplace_back(static_cast<float>(*m_Iterator));
392 }
393
394 return decodedTensor;
395 }
396};
397
398class Int64Decoder : public TypedIterator<const int64_t, Decoder<double_t>>
399{
400public:
401 Int64Decoder(const int64_t* data)
402 : TypedIterator(data) {}
403
404 Int64Decoder()
405 : Int64Decoder(nullptr) {}
406
407 double_t Get() const override
408 {
409 return static_cast<double_t>(*m_Iterator);
410 }
411 std::vector<float> DecodeTensor (const TensorShape& tensorShape, const bool) override
412 {
Finn Williamsea8ce702020-09-29 19:54:00 +0100413 const unsigned int size = tensorShape.GetNumElements();
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100414 std::vector<float> decodedTensor;
415 decodedTensor.reserve(size);
416
417 for (uint32_t i = 0; i < size; ++i)
418 {
419 this->operator[](i);
Rob Hughesc013bc82021-07-14 09:31:31 +0100420 decodedTensor.emplace_back(static_cast<float>(*m_Iterator));
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100421 }
422
423 return decodedTensor;
424 }
Finn Williamscbd2c232020-06-22 15:58:32 +0100425};
426
Sadik Armaganb60dd242020-03-19 13:53:16 +0000427class BooleanDecoder : public TypedIterator<const uint8_t, Decoder<float>>
428{
429public:
430 BooleanDecoder(const uint8_t* data)
431 : TypedIterator(data) {}
432
433 BooleanDecoder()
434 : BooleanDecoder(nullptr) {}
435
436 float Get() const override
437 {
438 return *m_Iterator;
439 }
Teresa Charlin5306dc82023-10-30 22:29:58 +0000440 std::vector<float> DecodeTensor (const TensorShape& tensorShape, const bool) override
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100441 {
Finn Williamsea8ce702020-09-29 19:54:00 +0100442 const unsigned int size = tensorShape.GetNumElements();
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100443 std::vector<float> decodedTensor;
444 decodedTensor.reserve(size);
445
446 for (uint32_t i = 0; i < size; ++i)
447 {
448 this->operator[](i);
449 decodedTensor.emplace_back(*m_Iterator);
450 }
451
452 return decodedTensor;
453 }
Sadik Armaganb60dd242020-03-19 13:53:16 +0000454};
455
James Conroyaba90cd2020-11-06 16:28:18 +0000456class BooleanDecoderBool : public TypedIterator<const uint8_t, Decoder<bool>>
457{
458public:
459 BooleanDecoderBool(const uint8_t* data)
460 : TypedIterator(data) {}
461
462 BooleanDecoderBool()
463 : BooleanDecoderBool(nullptr) {}
464
465 bool Get() const override
466 {
467 return *m_Iterator;
468 }
469
Teresa Charlin5306dc82023-10-30 22:29:58 +0000470 std::vector<float> DecodeTensor(const TensorShape& tensorShape, const bool) override
James Conroyaba90cd2020-11-06 16:28:18 +0000471 {
James Conroyaba90cd2020-11-06 16:28:18 +0000472 const unsigned int size = tensorShape.GetNumElements();
473 std::vector<float> decodedTensor;
474 decodedTensor.reserve(size);
475
476 for (uint32_t i = 0; i < size; ++i)
477 {
478 this->operator[](i);
479 decodedTensor.emplace_back(*m_Iterator);
480 }
481
482 return decodedTensor;
483 }
484};
485
Derek Lambertif30f7d32019-04-09 10:25:02 +0100486class QASymm8Encoder : public TypedIterator<uint8_t, Encoder<float>>
Sadik Armagan2e6dc3a2019-04-03 17:48:18 +0100487{
488public:
489 QASymm8Encoder(uint8_t* data, const float scale, const int32_t offset)
490 : TypedIterator(data), m_Scale(scale), m_Offset(offset) {}
491
Matthew Benthamc394a6d2019-06-24 12:51:25 +0100492 QASymm8Encoder(const float scale, const int32_t offset)
493 : QASymm8Encoder(nullptr, scale, offset) {}
494
Derek Lambertif30f7d32019-04-09 10:25:02 +0100495 void Set(float right) override
Sadik Armagan2e6dc3a2019-04-03 17:48:18 +0100496 {
497 *m_Iterator = armnn::Quantize<uint8_t>(right, m_Scale, m_Offset);
498 }
499
Nattapat Chaimanowongeb2b3292019-05-07 12:02:30 +0100500 float Get() const override
501 {
502 return armnn::Dequantize(*m_Iterator, m_Scale, m_Offset);
503 }
504
Sadik Armagan2e6dc3a2019-04-03 17:48:18 +0100505private:
506 const float m_Scale;
507 const int32_t m_Offset;
508};
509
Ryan OShea9add1202020-02-07 10:06:33 +0000510class QASymmS8Encoder : public TypedIterator<int8_t, Encoder<float>>
511{
512public:
513 QASymmS8Encoder(int8_t* data, const float scale, const int32_t offset)
514 : TypedIterator(data), m_Scale(scale), m_Offset(offset) {}
515
516 QASymmS8Encoder(const float scale, const int32_t offset)
517 : QASymmS8Encoder(nullptr, scale, offset) {}
518
519 void Set(float right) override
520 {
521 *m_Iterator = armnn::Quantize<int8_t>(right, m_Scale, m_Offset);
522 }
523
524 float Get() const override
525 {
526 return armnn::Dequantize(*m_Iterator, m_Scale, m_Offset);
527 }
528
529private:
530 const float m_Scale;
531 const int32_t m_Offset;
532};
533
Finn Williamsfd271062019-12-04 14:27:27 +0000534class QSymmS8Encoder : public TypedIterator<int8_t, Encoder<float>>
535{
536public:
537 QSymmS8Encoder(int8_t* data, const float scale, const int32_t offset)
538 : TypedIterator(data), m_Scale(scale), m_Offset(offset) {}
539
540 QSymmS8Encoder(const float scale, const int32_t offset)
541 : QSymmS8Encoder(nullptr, scale, offset) {}
542
543 void Set(float right) override
544 {
545 *m_Iterator = armnn::Quantize<int8_t>(right, m_Scale, m_Offset);
546 }
547
548 float Get() const override
549 {
550 return armnn::Dequantize(*m_Iterator, m_Scale, m_Offset);
551 }
552
553private:
554 const float m_Scale;
555 const int32_t m_Offset;
556};
557
Derek Lambertif30f7d32019-04-09 10:25:02 +0100558class QSymm16Encoder : public TypedIterator<int16_t, Encoder<float>>
559{
560public:
561 QSymm16Encoder(int16_t* data, const float scale, const int32_t offset)
562 : TypedIterator(data), m_Scale(scale), m_Offset(offset) {}
563
Matthew Benthamc394a6d2019-06-24 12:51:25 +0100564 QSymm16Encoder(const float scale, const int32_t offset)
565 : QSymm16Encoder(nullptr, scale, offset) {}
566
Derek Lambertif30f7d32019-04-09 10:25:02 +0100567 void Set(float right) override
568 {
569 *m_Iterator = armnn::Quantize<int16_t>(right, m_Scale, m_Offset);
570 }
571
Nattapat Chaimanowongeb2b3292019-05-07 12:02:30 +0100572 float Get() const override
573 {
574 return armnn::Dequantize(*m_Iterator, m_Scale, m_Offset);
575 }
576
Derek Lambertif30f7d32019-04-09 10:25:02 +0100577private:
578 const float m_Scale;
579 const int32_t m_Offset;
580};
581
Matthew Jacksone69c3992019-09-09 14:31:21 +0100582class Float16Encoder : public TypedIterator<Half, Encoder<float>>
Derek Lambertif30f7d32019-04-09 10:25:02 +0100583{
584public:
Matthew Jacksone69c3992019-09-09 14:31:21 +0100585 Float16Encoder(Half* data)
Derek Lambertif30f7d32019-04-09 10:25:02 +0100586 : TypedIterator(data) {}
587
Matthew Jacksone69c3992019-09-09 14:31:21 +0100588 Float16Encoder()
589 : Float16Encoder(nullptr) {}
590
591 void Set(float right) override
592 {
593 armnnUtils::FloatingPointConverter::ConvertFloat32To16(&right, 1, m_Iterator);
594 }
595
596 float Get() const override
597 {
598 float val = 0.f;
599 armnnUtils::FloatingPointConverter::ConvertFloat16To32(m_Iterator, 1, &val);
600 return val;
601 }
602};
603
604class Float32Encoder : public TypedIterator<float, Encoder<float>>
605{
606public:
607 Float32Encoder(float* data)
608 : TypedIterator(data) {}
609
610 Float32Encoder()
611 : Float32Encoder(nullptr) {}
Matthew Benthamc394a6d2019-06-24 12:51:25 +0100612
Derek Lambertif30f7d32019-04-09 10:25:02 +0100613 void Set(float right) override
614 {
615 *m_Iterator = right;
616 }
Nattapat Chaimanowongeb2b3292019-05-07 12:02:30 +0100617
618 float Get() const override
619 {
620 return *m_Iterator;
621 }
Derek Lambertif30f7d32019-04-09 10:25:02 +0100622};
623
Aron Virginas-Tar198ee402019-08-02 18:54:28 +0100624class Int32Encoder : public TypedIterator<int32_t, Encoder<float>>
625{
626public:
627 Int32Encoder(int32_t* data)
628 : TypedIterator(data) {}
629
630 Int32Encoder()
631 : Int32Encoder(nullptr) {}
632
633 void Set(float right) override
634 {
635 *m_Iterator = static_cast<int32_t>(right);
636 }
637
638 float Get() const override
639 {
640 return static_cast<float>(*m_Iterator);
641 }
642};
643
Finn Williamscbd2c232020-06-22 15:58:32 +0100644class Int32ToInt32tEncoder : public TypedIterator<int32_t, Encoder<int32_t>>
645{
646public:
647 Int32ToInt32tEncoder(int32_t* data)
648 : TypedIterator(data){}
649
650 Int32ToInt32tEncoder()
651 : Int32ToInt32tEncoder(nullptr) {}
652
653 void Set(int32_t right) override
654 {
655 *m_Iterator = right;
656 }
657
658 int32_t Get() const override
659 {
660 return *m_Iterator;
661 }
662};
663
Teresa Charlin5306dc82023-10-30 22:29:58 +0000664class Int64Encoder : public TypedIterator<int64_t, Encoder<double>>
665{
666public:
667 Int64Encoder(int64_t* data)
668 : TypedIterator(data) {}
669
670 Int64Encoder()
671 : Int64Encoder(nullptr) {}
672
673 void Set(double right) override
674 {
675 *m_Iterator = static_cast<int64_t>(right);
676 }
677
678 double_t Get() const override
679 {
680 return static_cast<double>(*m_Iterator);
681 }
682};
683
Derek Lambertif30f7d32019-04-09 10:25:02 +0100684class BooleanEncoder : public TypedIterator<uint8_t, Encoder<bool>>
Sadik Armagan2e6dc3a2019-04-03 17:48:18 +0100685{
686public:
687 BooleanEncoder(uint8_t* data)
688 : TypedIterator(data) {}
689
Matthew Benthamc394a6d2019-06-24 12:51:25 +0100690 BooleanEncoder()
691 : BooleanEncoder(nullptr) {}
692
Sadik Armagan2e6dc3a2019-04-03 17:48:18 +0100693 void Set(bool right) override
694 {
695 *m_Iterator = right;
696 }
Nattapat Chaimanowongeb2b3292019-05-07 12:02:30 +0100697
698 bool Get() const override
699 {
700 return *m_Iterator;
701 }
Sadik Armagan2e6dc3a2019-04-03 17:48:18 +0100702};
703
Jan Eilers53ef7952021-06-02 12:01:25 +0100704/// PerAxisIterator for per-axis quantization. Iterates over a tensor as layed out in memory and keeps track
705/// of the axis index.
Keith Davis5236e1d2019-11-04 08:58:33 +0000706template<typename T, typename Base>
707class PerAxisIterator : public Base
708{
709public:
Jan Eilers53ef7952021-06-02 12:01:25 +0100710 PerAxisIterator(T* data = nullptr,
711 unsigned int axisFactor = 0,
712 unsigned int axisDimensionality=0)
713 : m_Iterator(data),
714 m_Start(data),
715 m_AxisIndex(0), // iterates over the dimension of axis
716 m_AxisDimensionality(axisDimensionality), // tensorShape[quantization_dim]
717 m_AxisFactor(axisFactor),
718 m_Index(0)
Keith Davis5236e1d2019-11-04 08:58:33 +0000719 {}
720
Jan Eilers53ef7952021-06-02 12:01:25 +0100721 PerAxisIterator(T* data = nullptr,
722 const armnn::TensorShape& tensorShape = TensorShape(),
723 const unsigned int axis = 0)
724 : m_Iterator(data),
725 m_Start(data),
726 m_AxisIndex(0),
727 m_Index(0)
Keith Davis5236e1d2019-11-04 08:58:33 +0000728 {
Jan Eilers53ef7952021-06-02 12:01:25 +0100729 m_AxisDimensionality = tensorShape[axis];
730 m_AxisFactor = armnnUtils::GetNumElementsAfter(tensorShape, axis);
Keith Davis5236e1d2019-11-04 08:58:33 +0000731 }
732
733 void Reset(void* data) override
734 {
735 m_Iterator = reinterpret_cast<T*>(data);
736 m_Start = m_Iterator;
737 m_AxisIndex = 0;
Jan Eilers53ef7952021-06-02 12:01:25 +0100738 m_Index = 0;
Keith Davis5236e1d2019-11-04 08:58:33 +0000739 }
740
741 PerAxisIterator& operator++() override
742 {
Jan Eilers53ef7952021-06-02 12:01:25 +0100743 ++m_Index;
744 this -> operator[](m_Index);
Keith Davis5236e1d2019-11-04 08:58:33 +0000745 return *this;
746 }
747
748 PerAxisIterator& operator+=(const unsigned int increment) override
749 {
Jan Eilers53ef7952021-06-02 12:01:25 +0100750 m_Index += increment;
751 this -> operator[](m_Index);
Keith Davis5236e1d2019-11-04 08:58:33 +0000752 return *this;
753 }
754
755 PerAxisIterator& operator-=(const unsigned int decrement) override
756 {
Jan Eilers53ef7952021-06-02 12:01:25 +0100757 m_Index -= decrement;
758 this -> operator[](m_Index);
759 return *this;
760 }
761
762
763 inline PerAxisIterator& SetIndexOnMem(const unsigned int index)
764 {
Colm Donelanb4ef1632024-02-01 15:00:43 +0000765 ARMNN_THROW_INVALIDARG_MSG_IF_FALSE(m_Iterator, "PerAxisIterator: m_Iterator is null!");
Jan Eilers53ef7952021-06-02 12:01:25 +0100766 m_Iterator = m_Start + index;
767 if (index < m_AxisFactor)
768 {
769 m_AxisIndex = 0;
770 }
771 else
772 {
773 m_AxisIndex = (index / m_AxisFactor) % m_AxisDimensionality;
774 }
775 m_Index = index;
Keith Davis5236e1d2019-11-04 08:58:33 +0000776 return *this;
777 }
778
779 PerAxisIterator& operator[](const unsigned int index) override
780 {
Jan Eilers53ef7952021-06-02 12:01:25 +0100781 SetIndexOnMem(index);
Keith Davis5236e1d2019-11-04 08:58:33 +0000782 return *this;
783 }
784
785 protected:
786 T* m_Iterator;
787 T* m_Start;
788 unsigned int m_AxisIndex;
Jan Eilers53ef7952021-06-02 12:01:25 +0100789 unsigned int m_AxisDimensionality; // tensorShape[quantization_dim]
Keith Davis5236e1d2019-11-04 08:58:33 +0000790 unsigned int m_AxisFactor;
Jan Eilers53ef7952021-06-02 12:01:25 +0100791 unsigned int m_Index;
Keith Davis5236e1d2019-11-04 08:58:33 +0000792};
793
794class QSymm8PerAxisDecoder : public PerAxisIterator<const int8_t, Decoder<float>>
795{
796public:
Jan Eilers53ef7952021-06-02 12:01:25 +0100797 QSymm8PerAxisDecoder(const int8_t* data, const armnn::TensorInfo& tensorInfo)
798 : PerAxisIterator(data, tensorInfo.GetShape(), tensorInfo.GetQuantizationDim().value()),
799 m_Scales(tensorInfo.GetQuantizationScales())
800 {}
Keith Davis5236e1d2019-11-04 08:58:33 +0000801
802 float Get() const override
803 {
Jan Eilers53ef7952021-06-02 12:01:25 +0100804 return armnn::Dequantize(*m_Iterator, GetScale(), 0);
Keith Davis5236e1d2019-11-04 08:58:33 +0000805 }
806
807 // Get scale of the current value
808 float GetScale() const
809 {
Finn Williamsea8ce702020-09-29 19:54:00 +0100810 return m_Scales[m_AxisIndex];
Keith Davis5236e1d2019-11-04 08:58:33 +0000811 }
812
Teresa Charlin5306dc82023-10-30 22:29:58 +0000813 std::vector<float> DecodeTensor(const TensorShape &tensorShape, const bool) override
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100814 {
Jan Eilers53ef7952021-06-02 12:01:25 +0100815 const unsigned int size = tensorShape.GetNumElements();
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100816 std::vector<float> decodedTensor;
817 decodedTensor.reserve(size);
818
Jan Eilers53ef7952021-06-02 12:01:25 +0100819 for (uint32_t i = 0; i < size; ++i)
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100820 {
Jan Eilers53ef7952021-06-02 12:01:25 +0100821 SetIndexOnMem(i);
822 decodedTensor.emplace_back(armnn::Dequantize(*m_Iterator, GetScale(), 0));
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100823 }
824 return decodedTensor;
825 }
826
Keith Davis5236e1d2019-11-04 08:58:33 +0000827private:
Finn Williamsea8ce702020-09-29 19:54:00 +0100828 std::vector<float> m_Scales;
Keith Davis5236e1d2019-11-04 08:58:33 +0000829};
830
831class QSymm8PerAxisEncoder : public PerAxisIterator<int8_t, Encoder<float>>
832{
833public:
834 QSymm8PerAxisEncoder(int8_t* data, const std::vector<float>& scale, unsigned int axisFactor)
835 : PerAxisIterator(data, axisFactor), m_Scale(scale) {}
836
837 void Set(float right)
838 {
839 *m_Iterator = armnn::Quantize<int8_t>(right, m_Scale[m_AxisIndex], 0);
840 }
841
842 float Get() const
843 {
844 return armnn::Dequantize(*m_Iterator, m_Scale[m_AxisIndex], 0);
845 }
846
847 // Get scale of the current value
848 float GetScale() const
849 {
850 return m_Scale[m_AxisIndex];
851 }
852
853private:
854 std::vector<float> m_Scale;
855};
856
Aron Virginas-Tarb67f9572019-11-04 15:00:19 +0000857class ScaledInt32PerAxisDecoder : public PerAxisIterator<const int32_t, Decoder<float>>
858{
859public:
Jan Eilers53ef7952021-06-02 12:01:25 +0100860 ScaledInt32PerAxisDecoder(const int32_t* data, const armnn::TensorInfo tensorInfo)
861 : PerAxisIterator(data, tensorInfo.GetShape(), tensorInfo.GetQuantizationDim().value()),
862 m_Scales(tensorInfo.GetQuantizationScales())
863 {}
Aron Virginas-Tarb67f9572019-11-04 15:00:19 +0000864
865 float Get() const override
866 {
867 return armnn::Dequantize(*m_Iterator, m_Scales[m_AxisIndex], 0);
868 }
869
870 // Get scale of the current value
871 float GetScale() const
872 {
873 return m_Scales[m_AxisIndex];
874 }
875
Finn Williamsea8ce702020-09-29 19:54:00 +0100876 std::vector<float> DecodeTensor(const TensorShape &tensorShape,
Finn Williamsea8ce702020-09-29 19:54:00 +0100877 bool isDepthwise) override
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100878 {
Finn Williamsea8ce702020-09-29 19:54:00 +0100879 const uint32_t size = tensorShape.GetNumElements();
Finn Williamsea8ce702020-09-29 19:54:00 +0100880
881 const uint32_t stepSize = isDepthwise ?
882 tensorShape[2] * tensorShape[3] : tensorShape.GetNumElements() / tensorShape[0];
883
Jan Eilers53ef7952021-06-02 12:01:25 +0100884 const uint32_t stepNum = size / stepSize;
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100885
886 std::vector<float> decodedTensor;
887 decodedTensor.reserve(size);
888
Finn Williamsea8ce702020-09-29 19:54:00 +0100889 // channelMultiplier is only used in depthwise convolutions and in other cases will have no effect
890 // stepSize is the length of a contiguous area sharing a quantization scale within a tensor
891 // stepNum is the number of those steps/blocks in the tensor
Jan Eilers53ef7952021-06-02 12:01:25 +0100892 for (uint32_t step = 0; step < stepNum; ++step)
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100893 {
Jan Eilers53ef7952021-06-02 12:01:25 +0100894 //scale = (channelMultiplier * step + mult) % scaleSize;
895 for (uint32_t i = 0; i < stepSize; ++i)
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100896 {
Jan Eilers53ef7952021-06-02 12:01:25 +0100897 unsigned int index = step * stepSize + i;
898 this->operator[](index);
899 decodedTensor.emplace_back(armnn::Dequantize(*m_Iterator, m_Scales[step], 0));
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100900 }
901 }
902 return decodedTensor;
903 }
904
Aron Virginas-Tarb67f9572019-11-04 15:00:19 +0000905private:
906 std::vector<float> m_Scales;
907};
908
John Mcloughlinb41793a2023-10-16 10:28:40 +0100909class QSymm16PerAxisEncoder : public PerAxisIterator<int16_t, Encoder<float>>
910{
911public:
912 QSymm16PerAxisEncoder(int16_t* data, const std::vector<float>& scale,
913 unsigned int axisFactor, unsigned int axisDimensionality)
914 : PerAxisIterator(data, axisFactor, axisDimensionality), m_Scale(scale) {}
915
916 void Set(float right)
917 {
918 *m_Iterator = armnn::Quantize<int16_t>(right, m_Scale[m_AxisIndex], 0);
919 }
920
921 float Get() const
922 {
923 return armnn::Dequantize(*m_Iterator, m_Scale[m_AxisIndex], 0);
924 }
925
926 // Get scale of the current value
927 float GetScale() const
928 {
929 return m_Scale[m_AxisIndex];
930 }
931
932private:
933 std::vector<float> m_Scale;
934};
935
Aron Virginas-Tarb67f9572019-11-04 15:00:19 +0000936} // namespace armnn