blob: 694c22913c3dc038704734482a979d6ee142b2c3 [file] [log] [blame]
Sadik Armagan2e6dc3a2019-04-03 17:48:18 +01001//
John Mcloughlinb41793a2023-10-16 10:28:40 +01002// Copyright © 2017-2023 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>
Narumol Prangnawaratac2770a2020-04-01 16:51:23 +01009#include <armnn/utility/Assert.hpp>
Jan Eilers53ef7952021-06-02 12:01:25 +010010#include <armnn/utility/NumericCast.hpp>
Matteo Martincighe011d202019-11-28 11:35:47 +000011#include <armnnUtils/FloatingPointConverter.hpp>
Jan Eilers53ef7952021-06-02 12:01:25 +010012#include <armnnUtils/TensorUtils.hpp>
Matteo Martincighe011d202019-11-28 11:35:47 +000013
Aron Virginas-Tard4f0fea2019-04-09 14:08:06 +010014#include <ResolveType.hpp>
Sadik Armagan2e6dc3a2019-04-03 17:48:18 +010015
16namespace armnn
17{
18
19class BaseIterator
20{
21public:
22 BaseIterator() {}
23
24 virtual ~BaseIterator() {}
25
26 virtual BaseIterator& operator++() = 0;
27
28 virtual BaseIterator& operator+=(const unsigned int increment) = 0;
29
30 virtual BaseIterator& operator-=(const unsigned int increment) = 0;
Francis Murtagh43aec582019-05-27 12:14:10 +010031
32 virtual BaseIterator& operator[](const unsigned int index) = 0;
Sadik Armagan2e6dc3a2019-04-03 17:48:18 +010033};
34
Derek Lambertif30f7d32019-04-09 10:25:02 +010035template<typename IType>
Sadik Armagan2e6dc3a2019-04-03 17:48:18 +010036class Decoder : public BaseIterator
37{
38public:
Derek Lambertif30f7d32019-04-09 10:25:02 +010039 Decoder() {}
Sadik Armagan2e6dc3a2019-04-03 17:48:18 +010040
41 virtual ~Decoder() {}
42
Matthew Benthamc394a6d2019-06-24 12:51:25 +010043 virtual void Reset(void*) = 0;
44
Derek Lambertif30f7d32019-04-09 10:25:02 +010045 virtual IType Get() const = 0;
Finn Williamsb9dcfe62020-09-17 15:58:31 +010046
Teresa Charlin5306dc82023-10-30 22:29:58 +000047 virtual std::vector<float> DecodeTensor(const TensorShape &tensorShape, bool isDepthwise = false) = 0;
Sadik Armagan2e6dc3a2019-04-03 17:48:18 +010048};
49
Derek Lambertif30f7d32019-04-09 10:25:02 +010050template<typename IType>
Sadik Armagan2e6dc3a2019-04-03 17:48:18 +010051class Encoder : public BaseIterator
52{
53public:
Derek Lambertif30f7d32019-04-09 10:25:02 +010054 Encoder() {}
Sadik Armagan2e6dc3a2019-04-03 17:48:18 +010055
56 virtual ~Encoder() {}
57
Matthew Benthamc394a6d2019-06-24 12:51:25 +010058 virtual void Reset(void*) = 0;
59
Derek Lambertif30f7d32019-04-09 10:25:02 +010060 virtual void Set(IType right) = 0;
Nattapat Chaimanowongeb2b3292019-05-07 12:02:30 +010061
62 virtual IType Get() const = 0;
Sadik Armagan2e6dc3a2019-04-03 17:48:18 +010063};
64
65template<typename T, typename Base>
66class TypedIterator : public Base
67{
68public:
Matthew Benthamc394a6d2019-06-24 12:51:25 +010069 TypedIterator(T* data = nullptr)
Francis Murtagh43aec582019-05-27 12:14:10 +010070 : m_Iterator(data), m_Start(data)
Sadik Armagan2e6dc3a2019-04-03 17:48:18 +010071 {}
72
Matthew Benthamc394a6d2019-06-24 12:51:25 +010073 void Reset(void* data) override
74 {
75 m_Iterator = reinterpret_cast<T*>(data);
76 m_Start = m_Iterator;
77 }
78
Sadik Armagan2e6dc3a2019-04-03 17:48:18 +010079 TypedIterator& operator++() override
80 {
Narumol Prangnawaratac2770a2020-04-01 16:51:23 +010081 ARMNN_ASSERT(m_Iterator);
Sadik Armagan2e6dc3a2019-04-03 17:48:18 +010082 ++m_Iterator;
83 return *this;
84 }
85
86 TypedIterator& operator+=(const unsigned int increment) override
87 {
Narumol Prangnawaratac2770a2020-04-01 16:51:23 +010088 ARMNN_ASSERT(m_Iterator);
Sadik Armagan2e6dc3a2019-04-03 17:48:18 +010089 m_Iterator += increment;
90 return *this;
91 }
92
93 TypedIterator& operator-=(const unsigned int increment) override
94 {
Narumol Prangnawaratac2770a2020-04-01 16:51:23 +010095 ARMNN_ASSERT(m_Iterator);
Sadik Armagan2e6dc3a2019-04-03 17:48:18 +010096 m_Iterator -= increment;
97 return *this;
98 }
99
Francis Murtagh43aec582019-05-27 12:14:10 +0100100 TypedIterator& operator[](const unsigned int index) override
101 {
Narumol Prangnawaratac2770a2020-04-01 16:51:23 +0100102 ARMNN_ASSERT(m_Iterator);
Francis Murtagh43aec582019-05-27 12:14:10 +0100103 m_Iterator = m_Start + index;
104 return *this;
105 }
106
Nattapat Chaimanowongeb2b3292019-05-07 12:02:30 +0100107protected:
Sadik Armagan2e6dc3a2019-04-03 17:48:18 +0100108 T* m_Iterator;
Francis Murtagh43aec582019-05-27 12:14:10 +0100109 T* m_Start;
Sadik Armagan2e6dc3a2019-04-03 17:48:18 +0100110};
111
Derek Lambertif30f7d32019-04-09 10:25:02 +0100112class QASymm8Decoder : public TypedIterator<const uint8_t, Decoder<float>>
Sadik Armagan2e6dc3a2019-04-03 17:48:18 +0100113{
114public:
115 QASymm8Decoder(const uint8_t* data, const float scale, const int32_t offset)
116 : TypedIterator(data), m_Scale(scale), m_Offset(offset) {}
117
Matthew Benthamc394a6d2019-06-24 12:51:25 +0100118 QASymm8Decoder(const float scale, const int32_t offset)
119 : QASymm8Decoder(nullptr, scale, offset) {}
120
Sadik Armagan2e6dc3a2019-04-03 17:48:18 +0100121 float Get() const override
122 {
123 return armnn::Dequantize(*m_Iterator, m_Scale, m_Offset);
124 }
Teresa Charlin5306dc82023-10-30 22:29:58 +0000125 std::vector<float> DecodeTensor (const TensorShape& tensorShape, const bool) override
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100126 {
Finn Williamsea8ce702020-09-29 19:54:00 +0100127 const unsigned int size = tensorShape.GetNumElements();
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100128 std::vector<float> decodedTensor;
129 decodedTensor.reserve(size);
130
131 for (uint32_t i = 0; i < size; ++i)
132 {
133 this->operator[](i);
134 decodedTensor.emplace_back(armnn::Dequantize(*m_Iterator, m_Scale, m_Offset));
135 }
136
137 return decodedTensor;
138 }
139
Sadik Armagan2e6dc3a2019-04-03 17:48:18 +0100140private:
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100141
Sadik Armagan2e6dc3a2019-04-03 17:48:18 +0100142 const float m_Scale;
143 const int32_t m_Offset;
144};
145
Ryan OShea9add1202020-02-07 10:06:33 +0000146class QASymmS8Decoder : public TypedIterator<const int8_t, Decoder<float>>
147{
148public:
149 QASymmS8Decoder(const int8_t* data, const float scale, const int32_t offset)
150 : TypedIterator(data), m_Scale(scale), m_Offset(offset) {}
151
152 QASymmS8Decoder(const float scale, const int32_t offset)
153 : QASymmS8Decoder(nullptr, scale, offset) {}
154
155 float Get() const override
156 {
157 return armnn::Dequantize(*m_Iterator, m_Scale, m_Offset);
158 }
Teresa Charlin5306dc82023-10-30 22:29:58 +0000159 std::vector<float> DecodeTensor (const TensorShape& tensorShape, const bool) override
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100160 {
Finn Williamsea8ce702020-09-29 19:54:00 +0100161 const unsigned int size = tensorShape.GetNumElements();
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100162 std::vector<float> decodedTensor;
163 decodedTensor.reserve(size);
164
165 for (uint32_t i = 0; i < size; ++i)
166 {
167 this->operator[](i);
168 decodedTensor.emplace_back(armnn::Dequantize(*m_Iterator, m_Scale, m_Offset));
169 }
170
171 return decodedTensor;
172 }
173
Ryan OShea9add1202020-02-07 10:06:33 +0000174private:
175 const float m_Scale;
176 const int32_t m_Offset;
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100177
Ryan OShea9add1202020-02-07 10:06:33 +0000178};
179
Finn Williamsfd271062019-12-04 14:27:27 +0000180class QSymmS8Decoder : public TypedIterator<const int8_t, Decoder<float>>
181{
182public:
183 QSymmS8Decoder(const int8_t* data, const float scale, const int32_t offset)
184 : TypedIterator(data), m_Scale(scale), m_Offset(offset) {}
185
186 QSymmS8Decoder(const float scale, const int32_t offset)
187 : QSymmS8Decoder(nullptr, scale, offset) {}
188
189 float Get() const override
190 {
191 return armnn::Dequantize(*m_Iterator, m_Scale, m_Offset);
192 }
Teresa Charlin5306dc82023-10-30 22:29:58 +0000193 std::vector<float> DecodeTensor (const TensorShape& tensorShape, const bool) override
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100194 {
Finn Williamsea8ce702020-09-29 19:54:00 +0100195 const unsigned int size = tensorShape.GetNumElements();
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100196 std::vector<float> decodedTensor;
197 decodedTensor.reserve(size);
198
199 for (uint32_t i = 0; i < size; ++i)
200 {
201 this->operator[](i);
202 decodedTensor.emplace_back(armnn::Dequantize(*m_Iterator, m_Scale, m_Offset));
203 }
204
205 return decodedTensor;
206 }
207
Finn Williamsfd271062019-12-04 14:27:27 +0000208private:
209 const float m_Scale;
210 const int32_t m_Offset;
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100211
Finn Williamsfd271062019-12-04 14:27:27 +0000212};
213
Derek Lambertif30f7d32019-04-09 10:25:02 +0100214class QSymm16Decoder : public TypedIterator<const int16_t, Decoder<float>>
Sadik Armagan2999a022019-04-09 14:20:12 +0100215{
216public:
217 QSymm16Decoder(const int16_t* data, const float scale, const int32_t offset)
218 : TypedIterator(data), m_Scale(scale), m_Offset(offset) {}
219
Matthew Benthamc394a6d2019-06-24 12:51:25 +0100220 QSymm16Decoder(const float scale, const int32_t offset)
221 : QSymm16Decoder(nullptr, scale, offset) {}
222
Sadik Armagan2999a022019-04-09 14:20:12 +0100223 float Get() const override
224 {
225 return armnn::Dequantize(*m_Iterator, m_Scale, m_Offset);
226 }
Teresa Charlin5306dc82023-10-30 22:29:58 +0000227 std::vector<float> DecodeTensor (const TensorShape& tensorShape, const bool) override
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100228 {
Finn Williamsea8ce702020-09-29 19:54:00 +0100229 const unsigned int size = tensorShape.GetNumElements();
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100230 std::vector<float> decodedTensor;
231 decodedTensor.reserve(size);
232
233 for (uint32_t i = 0; i < size; ++i)
234 {
235 this->operator[](i);
236 decodedTensor.emplace_back(armnn::Dequantize(*m_Iterator, m_Scale, m_Offset));
237 }
238
239 return decodedTensor;
240 }
241
Sadik Armagan2999a022019-04-09 14:20:12 +0100242private:
243 const float m_Scale;
244 const int32_t m_Offset;
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100245
Sadik Armagan2999a022019-04-09 14:20:12 +0100246};
247
Matthew Jacksone69c3992019-09-09 14:31:21 +0100248class Float16Decoder : public TypedIterator<const Half, Decoder<float>>
Sadik Armagan2e6dc3a2019-04-03 17:48:18 +0100249{
250public:
Matthew Jacksone69c3992019-09-09 14:31:21 +0100251 Float16Decoder(const Half* data)
Sadik Armagan2e6dc3a2019-04-03 17:48:18 +0100252 : TypedIterator(data) {}
253
Matthew Jacksone69c3992019-09-09 14:31:21 +0100254 Float16Decoder()
255 : Float16Decoder(nullptr) {}
256
257 float Get() const override
258 {
259 float val = 0.f;
260 armnnUtils::FloatingPointConverter::ConvertFloat16To32(m_Iterator, 1, &val);
261 return val;
262 }
Teresa Charlin5306dc82023-10-30 22:29:58 +0000263 std::vector<float> DecodeTensor (const TensorShape& tensorShape, const bool ) override
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100264 {
Finn Williamsea8ce702020-09-29 19:54:00 +0100265 const unsigned int size = tensorShape.GetNumElements();
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100266 std::vector<float> decodedTensor;
267 decodedTensor.reserve(size);
268
269 for (uint32_t i = 0; i < size; ++i)
270 {
271 float val = 0.f;
272 this->operator[](i);
273 armnnUtils::FloatingPointConverter::ConvertFloat16To32(m_Iterator, 1, &val);
274 decodedTensor.emplace_back(val);
275 }
276
277 return decodedTensor;
278 }
279
280
Matthew Jacksone69c3992019-09-09 14:31:21 +0100281};
282
283class Float32Decoder : public TypedIterator<const float, Decoder<float>>
284{
285public:
286 Float32Decoder(const float* data)
287 : TypedIterator(data) {}
288
289 Float32Decoder()
290 : Float32Decoder(nullptr) {}
Matthew Benthamc394a6d2019-06-24 12:51:25 +0100291
Derek Lambertif30f7d32019-04-09 10:25:02 +0100292 float Get() const override
Sadik Armagan2e6dc3a2019-04-03 17:48:18 +0100293 {
Derek Lambertif30f7d32019-04-09 10:25:02 +0100294 return *m_Iterator;
Sadik Armagan2e6dc3a2019-04-03 17:48:18 +0100295 }
Teresa Charlin5306dc82023-10-30 22:29:58 +0000296 std::vector<float> DecodeTensor (const TensorShape& tensorShape, const bool) override
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100297 {
Finn Williamsea8ce702020-09-29 19:54:00 +0100298 const unsigned int size = tensorShape.GetNumElements();
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100299 std::vector<float> decodedTensor;
300
301 decodedTensor.reserve(size);
302 decodedTensor.assign(m_Start, m_Start + size);
303
304 return decodedTensor;
305 }
Sadik Armagan2e6dc3a2019-04-03 17:48:18 +0100306};
307
Mike Kelly9b398322019-05-22 17:21:49 +0100308class ScaledInt32Decoder : public TypedIterator<const int32_t, Decoder<float>>
309{
310public:
311 ScaledInt32Decoder(const int32_t* data, const float scale)
312 : TypedIterator(data), m_Scale(scale) {}
313
Matthew Benthamc394a6d2019-06-24 12:51:25 +0100314 ScaledInt32Decoder(const float scale)
315 : ScaledInt32Decoder(nullptr, scale) {}
316
Mike Kelly9b398322019-05-22 17:21:49 +0100317 float Get() const override
318 {
319 return static_cast<float>(*m_Iterator) * m_Scale;
320 }
Teresa Charlin5306dc82023-10-30 22:29:58 +0000321 std::vector<float> DecodeTensor (const TensorShape& tensorShape, const bool) override
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100322 {
Finn Williamsea8ce702020-09-29 19:54:00 +0100323 const unsigned int size = tensorShape.GetNumElements();
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100324 std::vector<float> decodedTensor;
325 decodedTensor.reserve(size);
326
327 for (uint32_t i = 0; i < size; ++i)
328 {
329 this->operator[](i);
330 decodedTensor.emplace_back(static_cast<float>(*m_Iterator) * m_Scale);
331 }
332
333 return decodedTensor;
334 }
335
Mike Kelly9b398322019-05-22 17:21:49 +0100336private:
337 const float m_Scale;
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100338
Mike Kelly9b398322019-05-22 17:21:49 +0100339};
340
Aron Virginas-Tar198ee402019-08-02 18:54:28 +0100341class Int32Decoder : public TypedIterator<const int32_t, Decoder<float>>
342{
343public:
344 Int32Decoder(const int32_t* data)
345 : TypedIterator(data) {}
346
347 Int32Decoder()
348 : Int32Decoder(nullptr) {}
349
350 float Get() const override
351 {
352 return static_cast<float>(*m_Iterator);
353 }
Teresa Charlin5306dc82023-10-30 22:29:58 +0000354 std::vector<float> DecodeTensor (const TensorShape& tensorShape, const bool) override
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100355 {
Finn Williamsea8ce702020-09-29 19:54:00 +0100356 const unsigned int size = tensorShape.GetNumElements();
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100357 std::vector<float> decodedTensor;
358 decodedTensor.reserve(size);
359
360 for (uint32_t i = 0; i < size; ++i)
361 {
362 this->operator[](i);
363 decodedTensor.emplace_back(static_cast<float>(*m_Iterator));
364 }
365
366 return decodedTensor;
367 }
Aron Virginas-Tar198ee402019-08-02 18:54:28 +0100368};
369
Finn Williamscbd2c232020-06-22 15:58:32 +0100370class Int32ToInt32tDecoder : public TypedIterator<const int32_t, Decoder<int32_t>>
371{
372public:
373 Int32ToInt32tDecoder(const int32_t* data)
374 : TypedIterator(data){}
375
376 Int32ToInt32tDecoder()
377 : Int32ToInt32tDecoder(nullptr) {}
378
379 int32_t Get() const override
380 {
381 return *m_Iterator;
382 }
Teresa Charlin5306dc82023-10-30 22:29:58 +0000383 std::vector<float> DecodeTensor (const TensorShape& tensorShape, const bool) override
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100384 {
Teresa Charlin5306dc82023-10-30 22:29:58 +0000385 const unsigned int size = tensorShape.GetNumElements();
386 std::vector<float> decodedTensor;
387 decodedTensor.reserve(size);
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100388
Teresa Charlin5306dc82023-10-30 22:29:58 +0000389 for (uint32_t i = 0; i < size; ++i)
390 {
391 this->operator[](i);
392 decodedTensor.emplace_back(static_cast<float>(*m_Iterator));
393 }
394
395 return decodedTensor;
396 }
397};
398
399class Int64Decoder : public TypedIterator<const int64_t, Decoder<double_t>>
400{
401public:
402 Int64Decoder(const int64_t* data)
403 : TypedIterator(data) {}
404
405 Int64Decoder()
406 : Int64Decoder(nullptr) {}
407
408 double_t Get() const override
409 {
410 return static_cast<double_t>(*m_Iterator);
411 }
412 std::vector<float> DecodeTensor (const TensorShape& tensorShape, const bool) override
413 {
Finn Williamsea8ce702020-09-29 19:54:00 +0100414 const unsigned int size = tensorShape.GetNumElements();
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100415 std::vector<float> decodedTensor;
416 decodedTensor.reserve(size);
417
418 for (uint32_t i = 0; i < size; ++i)
419 {
420 this->operator[](i);
Rob Hughesc013bc82021-07-14 09:31:31 +0100421 decodedTensor.emplace_back(static_cast<float>(*m_Iterator));
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100422 }
423
424 return decodedTensor;
425 }
Finn Williamscbd2c232020-06-22 15:58:32 +0100426};
427
Sadik Armaganb60dd242020-03-19 13:53:16 +0000428class BooleanDecoder : public TypedIterator<const uint8_t, Decoder<float>>
429{
430public:
431 BooleanDecoder(const uint8_t* data)
432 : TypedIterator(data) {}
433
434 BooleanDecoder()
435 : BooleanDecoder(nullptr) {}
436
437 float Get() const override
438 {
439 return *m_Iterator;
440 }
Teresa Charlin5306dc82023-10-30 22:29:58 +0000441 std::vector<float> DecodeTensor (const TensorShape& tensorShape, const bool) override
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100442 {
Finn Williamsea8ce702020-09-29 19:54:00 +0100443 const unsigned int size = tensorShape.GetNumElements();
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100444 std::vector<float> decodedTensor;
445 decodedTensor.reserve(size);
446
447 for (uint32_t i = 0; i < size; ++i)
448 {
449 this->operator[](i);
450 decodedTensor.emplace_back(*m_Iterator);
451 }
452
453 return decodedTensor;
454 }
Sadik Armaganb60dd242020-03-19 13:53:16 +0000455};
456
James Conroyaba90cd2020-11-06 16:28:18 +0000457class BooleanDecoderBool : public TypedIterator<const uint8_t, Decoder<bool>>
458{
459public:
460 BooleanDecoderBool(const uint8_t* data)
461 : TypedIterator(data) {}
462
463 BooleanDecoderBool()
464 : BooleanDecoderBool(nullptr) {}
465
466 bool Get() const override
467 {
468 return *m_Iterator;
469 }
470
Teresa Charlin5306dc82023-10-30 22:29:58 +0000471 std::vector<float> DecodeTensor(const TensorShape& tensorShape, const bool) override
James Conroyaba90cd2020-11-06 16:28:18 +0000472 {
James Conroyaba90cd2020-11-06 16:28:18 +0000473 const unsigned int size = tensorShape.GetNumElements();
474 std::vector<float> decodedTensor;
475 decodedTensor.reserve(size);
476
477 for (uint32_t i = 0; i < size; ++i)
478 {
479 this->operator[](i);
480 decodedTensor.emplace_back(*m_Iterator);
481 }
482
483 return decodedTensor;
484 }
485};
486
Derek Lambertif30f7d32019-04-09 10:25:02 +0100487class QASymm8Encoder : public TypedIterator<uint8_t, Encoder<float>>
Sadik Armagan2e6dc3a2019-04-03 17:48:18 +0100488{
489public:
490 QASymm8Encoder(uint8_t* data, const float scale, const int32_t offset)
491 : TypedIterator(data), m_Scale(scale), m_Offset(offset) {}
492
Matthew Benthamc394a6d2019-06-24 12:51:25 +0100493 QASymm8Encoder(const float scale, const int32_t offset)
494 : QASymm8Encoder(nullptr, scale, offset) {}
495
Derek Lambertif30f7d32019-04-09 10:25:02 +0100496 void Set(float right) override
Sadik Armagan2e6dc3a2019-04-03 17:48:18 +0100497 {
498 *m_Iterator = armnn::Quantize<uint8_t>(right, m_Scale, m_Offset);
499 }
500
Nattapat Chaimanowongeb2b3292019-05-07 12:02:30 +0100501 float Get() const override
502 {
503 return armnn::Dequantize(*m_Iterator, m_Scale, m_Offset);
504 }
505
Sadik Armagan2e6dc3a2019-04-03 17:48:18 +0100506private:
507 const float m_Scale;
508 const int32_t m_Offset;
509};
510
Ryan OShea9add1202020-02-07 10:06:33 +0000511class QASymmS8Encoder : public TypedIterator<int8_t, Encoder<float>>
512{
513public:
514 QASymmS8Encoder(int8_t* data, const float scale, const int32_t offset)
515 : TypedIterator(data), m_Scale(scale), m_Offset(offset) {}
516
517 QASymmS8Encoder(const float scale, const int32_t offset)
518 : QASymmS8Encoder(nullptr, scale, offset) {}
519
520 void Set(float right) override
521 {
522 *m_Iterator = armnn::Quantize<int8_t>(right, m_Scale, m_Offset);
523 }
524
525 float Get() const override
526 {
527 return armnn::Dequantize(*m_Iterator, m_Scale, m_Offset);
528 }
529
530private:
531 const float m_Scale;
532 const int32_t m_Offset;
533};
534
Finn Williamsfd271062019-12-04 14:27:27 +0000535class QSymmS8Encoder : public TypedIterator<int8_t, Encoder<float>>
536{
537public:
538 QSymmS8Encoder(int8_t* data, const float scale, const int32_t offset)
539 : TypedIterator(data), m_Scale(scale), m_Offset(offset) {}
540
541 QSymmS8Encoder(const float scale, const int32_t offset)
542 : QSymmS8Encoder(nullptr, scale, offset) {}
543
544 void Set(float right) override
545 {
546 *m_Iterator = armnn::Quantize<int8_t>(right, m_Scale, m_Offset);
547 }
548
549 float Get() const override
550 {
551 return armnn::Dequantize(*m_Iterator, m_Scale, m_Offset);
552 }
553
554private:
555 const float m_Scale;
556 const int32_t m_Offset;
557};
558
Derek Lambertif30f7d32019-04-09 10:25:02 +0100559class QSymm16Encoder : public TypedIterator<int16_t, Encoder<float>>
560{
561public:
562 QSymm16Encoder(int16_t* data, const float scale, const int32_t offset)
563 : TypedIterator(data), m_Scale(scale), m_Offset(offset) {}
564
Matthew Benthamc394a6d2019-06-24 12:51:25 +0100565 QSymm16Encoder(const float scale, const int32_t offset)
566 : QSymm16Encoder(nullptr, scale, offset) {}
567
Derek Lambertif30f7d32019-04-09 10:25:02 +0100568 void Set(float right) override
569 {
570 *m_Iterator = armnn::Quantize<int16_t>(right, m_Scale, m_Offset);
571 }
572
Nattapat Chaimanowongeb2b3292019-05-07 12:02:30 +0100573 float Get() const override
574 {
575 return armnn::Dequantize(*m_Iterator, m_Scale, m_Offset);
576 }
577
Derek Lambertif30f7d32019-04-09 10:25:02 +0100578private:
579 const float m_Scale;
580 const int32_t m_Offset;
581};
582
Matthew Jacksone69c3992019-09-09 14:31:21 +0100583class Float16Encoder : public TypedIterator<Half, Encoder<float>>
Derek Lambertif30f7d32019-04-09 10:25:02 +0100584{
585public:
Matthew Jacksone69c3992019-09-09 14:31:21 +0100586 Float16Encoder(Half* data)
Derek Lambertif30f7d32019-04-09 10:25:02 +0100587 : TypedIterator(data) {}
588
Matthew Jacksone69c3992019-09-09 14:31:21 +0100589 Float16Encoder()
590 : Float16Encoder(nullptr) {}
591
592 void Set(float right) override
593 {
594 armnnUtils::FloatingPointConverter::ConvertFloat32To16(&right, 1, m_Iterator);
595 }
596
597 float Get() const override
598 {
599 float val = 0.f;
600 armnnUtils::FloatingPointConverter::ConvertFloat16To32(m_Iterator, 1, &val);
601 return val;
602 }
603};
604
605class Float32Encoder : public TypedIterator<float, Encoder<float>>
606{
607public:
608 Float32Encoder(float* data)
609 : TypedIterator(data) {}
610
611 Float32Encoder()
612 : Float32Encoder(nullptr) {}
Matthew Benthamc394a6d2019-06-24 12:51:25 +0100613
Derek Lambertif30f7d32019-04-09 10:25:02 +0100614 void Set(float right) override
615 {
616 *m_Iterator = right;
617 }
Nattapat Chaimanowongeb2b3292019-05-07 12:02:30 +0100618
619 float Get() const override
620 {
621 return *m_Iterator;
622 }
Derek Lambertif30f7d32019-04-09 10:25:02 +0100623};
624
Aron Virginas-Tar198ee402019-08-02 18:54:28 +0100625class Int32Encoder : public TypedIterator<int32_t, Encoder<float>>
626{
627public:
628 Int32Encoder(int32_t* data)
629 : TypedIterator(data) {}
630
631 Int32Encoder()
632 : Int32Encoder(nullptr) {}
633
634 void Set(float right) override
635 {
636 *m_Iterator = static_cast<int32_t>(right);
637 }
638
639 float Get() const override
640 {
641 return static_cast<float>(*m_Iterator);
642 }
643};
644
Finn Williamscbd2c232020-06-22 15:58:32 +0100645class Int32ToInt32tEncoder : public TypedIterator<int32_t, Encoder<int32_t>>
646{
647public:
648 Int32ToInt32tEncoder(int32_t* data)
649 : TypedIterator(data){}
650
651 Int32ToInt32tEncoder()
652 : Int32ToInt32tEncoder(nullptr) {}
653
654 void Set(int32_t right) override
655 {
656 *m_Iterator = right;
657 }
658
659 int32_t Get() const override
660 {
661 return *m_Iterator;
662 }
663};
664
Teresa Charlin5306dc82023-10-30 22:29:58 +0000665class Int64Encoder : public TypedIterator<int64_t, Encoder<double>>
666{
667public:
668 Int64Encoder(int64_t* data)
669 : TypedIterator(data) {}
670
671 Int64Encoder()
672 : Int64Encoder(nullptr) {}
673
674 void Set(double right) override
675 {
676 *m_Iterator = static_cast<int64_t>(right);
677 }
678
679 double_t Get() const override
680 {
681 return static_cast<double>(*m_Iterator);
682 }
683};
684
Derek Lambertif30f7d32019-04-09 10:25:02 +0100685class BooleanEncoder : public TypedIterator<uint8_t, Encoder<bool>>
Sadik Armagan2e6dc3a2019-04-03 17:48:18 +0100686{
687public:
688 BooleanEncoder(uint8_t* data)
689 : TypedIterator(data) {}
690
Matthew Benthamc394a6d2019-06-24 12:51:25 +0100691 BooleanEncoder()
692 : BooleanEncoder(nullptr) {}
693
Sadik Armagan2e6dc3a2019-04-03 17:48:18 +0100694 void Set(bool right) override
695 {
696 *m_Iterator = right;
697 }
Nattapat Chaimanowongeb2b3292019-05-07 12:02:30 +0100698
699 bool Get() const override
700 {
701 return *m_Iterator;
702 }
Sadik Armagan2e6dc3a2019-04-03 17:48:18 +0100703};
704
Jan Eilers53ef7952021-06-02 12:01:25 +0100705/// PerAxisIterator for per-axis quantization. Iterates over a tensor as layed out in memory and keeps track
706/// of the axis index.
Keith Davis5236e1d2019-11-04 08:58:33 +0000707template<typename T, typename Base>
708class PerAxisIterator : public Base
709{
710public:
Jan Eilers53ef7952021-06-02 12:01:25 +0100711 PerAxisIterator(T* data = nullptr,
712 unsigned int axisFactor = 0,
713 unsigned int axisDimensionality=0)
714 : m_Iterator(data),
715 m_Start(data),
716 m_AxisIndex(0), // iterates over the dimension of axis
717 m_AxisDimensionality(axisDimensionality), // tensorShape[quantization_dim]
718 m_AxisFactor(axisFactor),
719 m_Index(0)
Keith Davis5236e1d2019-11-04 08:58:33 +0000720 {}
721
Jan Eilers53ef7952021-06-02 12:01:25 +0100722 PerAxisIterator(T* data = nullptr,
723 const armnn::TensorShape& tensorShape = TensorShape(),
724 const unsigned int axis = 0)
725 : m_Iterator(data),
726 m_Start(data),
727 m_AxisIndex(0),
728 m_Index(0)
Keith Davis5236e1d2019-11-04 08:58:33 +0000729 {
Jan Eilers53ef7952021-06-02 12:01:25 +0100730 m_AxisDimensionality = tensorShape[axis];
731 m_AxisFactor = armnnUtils::GetNumElementsAfter(tensorShape, axis);
Keith Davis5236e1d2019-11-04 08:58:33 +0000732 }
733
734 void Reset(void* data) override
735 {
736 m_Iterator = reinterpret_cast<T*>(data);
737 m_Start = m_Iterator;
738 m_AxisIndex = 0;
Jan Eilers53ef7952021-06-02 12:01:25 +0100739 m_Index = 0;
Keith Davis5236e1d2019-11-04 08:58:33 +0000740 }
741
742 PerAxisIterator& operator++() override
743 {
Jan Eilers53ef7952021-06-02 12:01:25 +0100744 ++m_Index;
745 this -> operator[](m_Index);
Keith Davis5236e1d2019-11-04 08:58:33 +0000746 return *this;
747 }
748
749 PerAxisIterator& operator+=(const unsigned int increment) override
750 {
Jan Eilers53ef7952021-06-02 12:01:25 +0100751 m_Index += increment;
752 this -> operator[](m_Index);
Keith Davis5236e1d2019-11-04 08:58:33 +0000753 return *this;
754 }
755
756 PerAxisIterator& operator-=(const unsigned int decrement) override
757 {
Jan Eilers53ef7952021-06-02 12:01:25 +0100758 m_Index -= decrement;
759 this -> operator[](m_Index);
760 return *this;
761 }
762
763
764 inline PerAxisIterator& SetIndexOnMem(const unsigned int index)
765 {
Narumol Prangnawaratac2770a2020-04-01 16:51:23 +0100766 ARMNN_ASSERT(m_Iterator);
Jan Eilers53ef7952021-06-02 12:01:25 +0100767 m_Iterator = m_Start + index;
768 if (index < m_AxisFactor)
769 {
770 m_AxisIndex = 0;
771 }
772 else
773 {
774 m_AxisIndex = (index / m_AxisFactor) % m_AxisDimensionality;
775 }
776 m_Index = index;
Keith Davis5236e1d2019-11-04 08:58:33 +0000777 return *this;
778 }
779
780 PerAxisIterator& operator[](const unsigned int index) override
781 {
Jan Eilers53ef7952021-06-02 12:01:25 +0100782 SetIndexOnMem(index);
Keith Davis5236e1d2019-11-04 08:58:33 +0000783 return *this;
784 }
785
786 protected:
787 T* m_Iterator;
788 T* m_Start;
789 unsigned int m_AxisIndex;
Jan Eilers53ef7952021-06-02 12:01:25 +0100790 unsigned int m_AxisDimensionality; // tensorShape[quantization_dim]
Keith Davis5236e1d2019-11-04 08:58:33 +0000791 unsigned int m_AxisFactor;
Jan Eilers53ef7952021-06-02 12:01:25 +0100792 unsigned int m_Index;
Keith Davis5236e1d2019-11-04 08:58:33 +0000793};
794
795class QSymm8PerAxisDecoder : public PerAxisIterator<const int8_t, Decoder<float>>
796{
797public:
Jan Eilers53ef7952021-06-02 12:01:25 +0100798 QSymm8PerAxisDecoder(const int8_t* data, const armnn::TensorInfo& tensorInfo)
799 : PerAxisIterator(data, tensorInfo.GetShape(), tensorInfo.GetQuantizationDim().value()),
800 m_Scales(tensorInfo.GetQuantizationScales())
801 {}
Keith Davis5236e1d2019-11-04 08:58:33 +0000802
803 float Get() const override
804 {
Jan Eilers53ef7952021-06-02 12:01:25 +0100805 return armnn::Dequantize(*m_Iterator, GetScale(), 0);
Keith Davis5236e1d2019-11-04 08:58:33 +0000806 }
807
808 // Get scale of the current value
809 float GetScale() const
810 {
Finn Williamsea8ce702020-09-29 19:54:00 +0100811 return m_Scales[m_AxisIndex];
Keith Davis5236e1d2019-11-04 08:58:33 +0000812 }
813
Teresa Charlin5306dc82023-10-30 22:29:58 +0000814 std::vector<float> DecodeTensor(const TensorShape &tensorShape, const bool) override
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100815 {
Jan Eilers53ef7952021-06-02 12:01:25 +0100816 const unsigned int size = tensorShape.GetNumElements();
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100817 std::vector<float> decodedTensor;
818 decodedTensor.reserve(size);
819
Jan Eilers53ef7952021-06-02 12:01:25 +0100820 for (uint32_t i = 0; i < size; ++i)
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100821 {
Jan Eilers53ef7952021-06-02 12:01:25 +0100822 SetIndexOnMem(i);
823 decodedTensor.emplace_back(armnn::Dequantize(*m_Iterator, GetScale(), 0));
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100824 }
825 return decodedTensor;
826 }
827
Keith Davis5236e1d2019-11-04 08:58:33 +0000828private:
Finn Williamsea8ce702020-09-29 19:54:00 +0100829 std::vector<float> m_Scales;
Keith Davis5236e1d2019-11-04 08:58:33 +0000830};
831
832class QSymm8PerAxisEncoder : public PerAxisIterator<int8_t, Encoder<float>>
833{
834public:
835 QSymm8PerAxisEncoder(int8_t* data, const std::vector<float>& scale, unsigned int axisFactor)
836 : PerAxisIterator(data, axisFactor), m_Scale(scale) {}
837
838 void Set(float right)
839 {
840 *m_Iterator = armnn::Quantize<int8_t>(right, m_Scale[m_AxisIndex], 0);
841 }
842
843 float Get() const
844 {
845 return armnn::Dequantize(*m_Iterator, m_Scale[m_AxisIndex], 0);
846 }
847
848 // Get scale of the current value
849 float GetScale() const
850 {
851 return m_Scale[m_AxisIndex];
852 }
853
854private:
855 std::vector<float> m_Scale;
856};
857
Aron Virginas-Tarb67f9572019-11-04 15:00:19 +0000858class ScaledInt32PerAxisDecoder : public PerAxisIterator<const int32_t, Decoder<float>>
859{
860public:
Jan Eilers53ef7952021-06-02 12:01:25 +0100861 ScaledInt32PerAxisDecoder(const int32_t* data, const armnn::TensorInfo tensorInfo)
862 : PerAxisIterator(data, tensorInfo.GetShape(), tensorInfo.GetQuantizationDim().value()),
863 m_Scales(tensorInfo.GetQuantizationScales())
864 {}
Aron Virginas-Tarb67f9572019-11-04 15:00:19 +0000865
866 float Get() const override
867 {
868 return armnn::Dequantize(*m_Iterator, m_Scales[m_AxisIndex], 0);
869 }
870
871 // Get scale of the current value
872 float GetScale() const
873 {
874 return m_Scales[m_AxisIndex];
875 }
876
Finn Williamsea8ce702020-09-29 19:54:00 +0100877 std::vector<float> DecodeTensor(const TensorShape &tensorShape,
Finn Williamsea8ce702020-09-29 19:54:00 +0100878 bool isDepthwise) override
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100879 {
Finn Williamsea8ce702020-09-29 19:54:00 +0100880 const uint32_t size = tensorShape.GetNumElements();
Finn Williamsea8ce702020-09-29 19:54:00 +0100881
882 const uint32_t stepSize = isDepthwise ?
883 tensorShape[2] * tensorShape[3] : tensorShape.GetNumElements() / tensorShape[0];
884
Jan Eilers53ef7952021-06-02 12:01:25 +0100885 const uint32_t stepNum = size / stepSize;
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100886
887 std::vector<float> decodedTensor;
888 decodedTensor.reserve(size);
889
Finn Williamsea8ce702020-09-29 19:54:00 +0100890 // channelMultiplier is only used in depthwise convolutions and in other cases will have no effect
891 // stepSize is the length of a contiguous area sharing a quantization scale within a tensor
892 // stepNum is the number of those steps/blocks in the tensor
Jan Eilers53ef7952021-06-02 12:01:25 +0100893 for (uint32_t step = 0; step < stepNum; ++step)
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100894 {
Jan Eilers53ef7952021-06-02 12:01:25 +0100895 //scale = (channelMultiplier * step + mult) % scaleSize;
896 for (uint32_t i = 0; i < stepSize; ++i)
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100897 {
Jan Eilers53ef7952021-06-02 12:01:25 +0100898 unsigned int index = step * stepSize + i;
899 this->operator[](index);
900 decodedTensor.emplace_back(armnn::Dequantize(*m_Iterator, m_Scales[step], 0));
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100901 }
902 }
903 return decodedTensor;
904 }
905
Aron Virginas-Tarb67f9572019-11-04 15:00:19 +0000906private:
907 std::vector<float> m_Scales;
908};
909
John Mcloughlinb41793a2023-10-16 10:28:40 +0100910class QSymm16PerAxisEncoder : public PerAxisIterator<int16_t, Encoder<float>>
911{
912public:
913 QSymm16PerAxisEncoder(int16_t* data, const std::vector<float>& scale,
914 unsigned int axisFactor, unsigned int axisDimensionality)
915 : PerAxisIterator(data, axisFactor, axisDimensionality), m_Scale(scale) {}
916
917 void Set(float right)
918 {
919 *m_Iterator = armnn::Quantize<int16_t>(right, m_Scale[m_AxisIndex], 0);
920 }
921
922 float Get() const
923 {
924 return armnn::Dequantize(*m_Iterator, m_Scale[m_AxisIndex], 0);
925 }
926
927 // Get scale of the current value
928 float GetScale() const
929 {
930 return m_Scale[m_AxisIndex];
931 }
932
933private:
934 std::vector<float> m_Scale;
935};
936
Aron Virginas-Tarb67f9572019-11-04 15:00:19 +0000937} // namespace armnn