blob: 483ef720f9310a231011dbc5bba2effc318631c0 [file] [log] [blame]
Sadik Armagan2e6dc3a2019-04-03 17:48:18 +01001//
2// Copyright © 2017 Arm Ltd. All rights reserved.
3// 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>
10#include <armnn/utility/IgnoreUnused.hpp>
Jan Eilers53ef7952021-06-02 12:01:25 +010011#include <armnn/utility/NumericCast.hpp>
Matteo Martincighe011d202019-11-28 11:35:47 +000012#include <armnnUtils/FloatingPointConverter.hpp>
Jan Eilers53ef7952021-06-02 12:01:25 +010013#include <armnnUtils/TensorUtils.hpp>
Matteo Martincighe011d202019-11-28 11:35:47 +000014
Aron Virginas-Tard4f0fea2019-04-09 14:08:06 +010015#include <ResolveType.hpp>
Sadik Armagan2e6dc3a2019-04-03 17:48:18 +010016
17namespace armnn
18{
19
20class BaseIterator
21{
22public:
23 BaseIterator() {}
24
25 virtual ~BaseIterator() {}
26
27 virtual BaseIterator& operator++() = 0;
28
29 virtual BaseIterator& operator+=(const unsigned int increment) = 0;
30
31 virtual BaseIterator& operator-=(const unsigned int increment) = 0;
Francis Murtagh43aec582019-05-27 12:14:10 +010032
33 virtual BaseIterator& operator[](const unsigned int index) = 0;
Sadik Armagan2e6dc3a2019-04-03 17:48:18 +010034};
35
Derek Lambertif30f7d32019-04-09 10:25:02 +010036template<typename IType>
Sadik Armagan2e6dc3a2019-04-03 17:48:18 +010037class Decoder : public BaseIterator
38{
39public:
Derek Lambertif30f7d32019-04-09 10:25:02 +010040 Decoder() {}
Sadik Armagan2e6dc3a2019-04-03 17:48:18 +010041
42 virtual ~Decoder() {}
43
Matthew Benthamc394a6d2019-06-24 12:51:25 +010044 virtual void Reset(void*) = 0;
45
Derek Lambertif30f7d32019-04-09 10:25:02 +010046 virtual IType Get() const = 0;
Finn Williamsb9dcfe62020-09-17 15:58:31 +010047
Finn Williamsea8ce702020-09-29 19:54:00 +010048 virtual std::vector<float>
49 DecodeTensor(const TensorShape &tensorShape,
Finn Williamsea8ce702020-09-29 19:54:00 +010050 bool isDepthwise = false) = 0;
Sadik Armagan2e6dc3a2019-04-03 17:48:18 +010051};
52
Derek Lambertif30f7d32019-04-09 10:25:02 +010053template<typename IType>
Sadik Armagan2e6dc3a2019-04-03 17:48:18 +010054class Encoder : public BaseIterator
55{
56public:
Derek Lambertif30f7d32019-04-09 10:25:02 +010057 Encoder() {}
Sadik Armagan2e6dc3a2019-04-03 17:48:18 +010058
59 virtual ~Encoder() {}
60
Matthew Benthamc394a6d2019-06-24 12:51:25 +010061 virtual void Reset(void*) = 0;
62
Derek Lambertif30f7d32019-04-09 10:25:02 +010063 virtual void Set(IType right) = 0;
Nattapat Chaimanowongeb2b3292019-05-07 12:02:30 +010064
65 virtual IType Get() const = 0;
Sadik Armagan2e6dc3a2019-04-03 17:48:18 +010066};
67
68template<typename T, typename Base>
69class TypedIterator : public Base
70{
71public:
Matthew Benthamc394a6d2019-06-24 12:51:25 +010072 TypedIterator(T* data = nullptr)
Francis Murtagh43aec582019-05-27 12:14:10 +010073 : m_Iterator(data), m_Start(data)
Sadik Armagan2e6dc3a2019-04-03 17:48:18 +010074 {}
75
Matthew Benthamc394a6d2019-06-24 12:51:25 +010076 void Reset(void* data) override
77 {
78 m_Iterator = reinterpret_cast<T*>(data);
79 m_Start = m_Iterator;
80 }
81
Sadik Armagan2e6dc3a2019-04-03 17:48:18 +010082 TypedIterator& operator++() override
83 {
Narumol Prangnawaratac2770a2020-04-01 16:51:23 +010084 ARMNN_ASSERT(m_Iterator);
Sadik Armagan2e6dc3a2019-04-03 17:48:18 +010085 ++m_Iterator;
86 return *this;
87 }
88
89 TypedIterator& operator+=(const unsigned int increment) override
90 {
Narumol Prangnawaratac2770a2020-04-01 16:51:23 +010091 ARMNN_ASSERT(m_Iterator);
Sadik Armagan2e6dc3a2019-04-03 17:48:18 +010092 m_Iterator += increment;
93 return *this;
94 }
95
96 TypedIterator& operator-=(const unsigned int increment) override
97 {
Narumol Prangnawaratac2770a2020-04-01 16:51:23 +010098 ARMNN_ASSERT(m_Iterator);
Sadik Armagan2e6dc3a2019-04-03 17:48:18 +010099 m_Iterator -= increment;
100 return *this;
101 }
102
Francis Murtagh43aec582019-05-27 12:14:10 +0100103 TypedIterator& operator[](const unsigned int index) override
104 {
Narumol Prangnawaratac2770a2020-04-01 16:51:23 +0100105 ARMNN_ASSERT(m_Iterator);
Francis Murtagh43aec582019-05-27 12:14:10 +0100106 m_Iterator = m_Start + index;
107 return *this;
108 }
109
Nattapat Chaimanowongeb2b3292019-05-07 12:02:30 +0100110protected:
Sadik Armagan2e6dc3a2019-04-03 17:48:18 +0100111 T* m_Iterator;
Francis Murtagh43aec582019-05-27 12:14:10 +0100112 T* m_Start;
Sadik Armagan2e6dc3a2019-04-03 17:48:18 +0100113};
114
Derek Lambertif30f7d32019-04-09 10:25:02 +0100115class QASymm8Decoder : public TypedIterator<const uint8_t, Decoder<float>>
Sadik Armagan2e6dc3a2019-04-03 17:48:18 +0100116{
117public:
118 QASymm8Decoder(const uint8_t* data, const float scale, const int32_t offset)
119 : TypedIterator(data), m_Scale(scale), m_Offset(offset) {}
120
Matthew Benthamc394a6d2019-06-24 12:51:25 +0100121 QASymm8Decoder(const float scale, const int32_t offset)
122 : QASymm8Decoder(nullptr, scale, offset) {}
123
Sadik Armagan2e6dc3a2019-04-03 17:48:18 +0100124 float Get() const override
125 {
126 return armnn::Dequantize(*m_Iterator, m_Scale, m_Offset);
127 }
Finn Williamsea8ce702020-09-29 19:54:00 +0100128 std::vector<float> DecodeTensor (const TensorShape& tensorShape,
Finn Williamsea8ce702020-09-29 19:54:00 +0100129 const bool isDepthwise) override
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100130 {
Jan Eilers53ef7952021-06-02 12:01:25 +0100131 IgnoreUnused(isDepthwise);
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100132
Finn Williamsea8ce702020-09-29 19:54:00 +0100133 const unsigned int size = tensorShape.GetNumElements();
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100134 std::vector<float> decodedTensor;
135 decodedTensor.reserve(size);
136
137 for (uint32_t i = 0; i < size; ++i)
138 {
139 this->operator[](i);
140 decodedTensor.emplace_back(armnn::Dequantize(*m_Iterator, m_Scale, m_Offset));
141 }
142
143 return decodedTensor;
144 }
145
Sadik Armagan2e6dc3a2019-04-03 17:48:18 +0100146private:
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100147
Sadik Armagan2e6dc3a2019-04-03 17:48:18 +0100148 const float m_Scale;
149 const int32_t m_Offset;
150};
151
Ryan OShea9add1202020-02-07 10:06:33 +0000152class QASymmS8Decoder : public TypedIterator<const int8_t, Decoder<float>>
153{
154public:
155 QASymmS8Decoder(const int8_t* data, const float scale, const int32_t offset)
156 : TypedIterator(data), m_Scale(scale), m_Offset(offset) {}
157
158 QASymmS8Decoder(const float scale, const int32_t offset)
159 : QASymmS8Decoder(nullptr, scale, offset) {}
160
161 float Get() const override
162 {
163 return armnn::Dequantize(*m_Iterator, m_Scale, m_Offset);
164 }
Finn Williamsea8ce702020-09-29 19:54:00 +0100165 std::vector<float> DecodeTensor (const TensorShape& tensorShape,
Finn Williamsea8ce702020-09-29 19:54:00 +0100166 const bool isDepthwise) override
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100167 {
Jan Eilers53ef7952021-06-02 12:01:25 +0100168 IgnoreUnused(isDepthwise);
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100169
Finn Williamsea8ce702020-09-29 19:54:00 +0100170 const unsigned int size = tensorShape.GetNumElements();
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100171 std::vector<float> decodedTensor;
172 decodedTensor.reserve(size);
173
174 for (uint32_t i = 0; i < size; ++i)
175 {
176 this->operator[](i);
177 decodedTensor.emplace_back(armnn::Dequantize(*m_Iterator, m_Scale, m_Offset));
178 }
179
180 return decodedTensor;
181 }
182
Ryan OShea9add1202020-02-07 10:06:33 +0000183private:
184 const float m_Scale;
185 const int32_t m_Offset;
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100186
Ryan OShea9add1202020-02-07 10:06:33 +0000187};
188
Finn Williamsfd271062019-12-04 14:27:27 +0000189class QSymmS8Decoder : public TypedIterator<const int8_t, Decoder<float>>
190{
191public:
192 QSymmS8Decoder(const int8_t* data, const float scale, const int32_t offset)
193 : TypedIterator(data), m_Scale(scale), m_Offset(offset) {}
194
195 QSymmS8Decoder(const float scale, const int32_t offset)
196 : QSymmS8Decoder(nullptr, scale, offset) {}
197
198 float Get() const override
199 {
200 return armnn::Dequantize(*m_Iterator, m_Scale, m_Offset);
201 }
Finn Williamsea8ce702020-09-29 19:54:00 +0100202 std::vector<float> DecodeTensor (const TensorShape& tensorShape,
Finn Williamsea8ce702020-09-29 19:54:00 +0100203 const bool isDepthwise) override
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100204 {
Jan Eilers53ef7952021-06-02 12:01:25 +0100205 IgnoreUnused(isDepthwise);
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100206
Finn Williamsea8ce702020-09-29 19:54:00 +0100207 const unsigned int size = tensorShape.GetNumElements();
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100208 std::vector<float> decodedTensor;
209 decodedTensor.reserve(size);
210
211 for (uint32_t i = 0; i < size; ++i)
212 {
213 this->operator[](i);
214 decodedTensor.emplace_back(armnn::Dequantize(*m_Iterator, m_Scale, m_Offset));
215 }
216
217 return decodedTensor;
218 }
219
Finn Williamsfd271062019-12-04 14:27:27 +0000220private:
221 const float m_Scale;
222 const int32_t m_Offset;
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100223
Finn Williamsfd271062019-12-04 14:27:27 +0000224};
225
Derek Lambertif30f7d32019-04-09 10:25:02 +0100226class QSymm16Decoder : public TypedIterator<const int16_t, Decoder<float>>
Sadik Armagan2999a022019-04-09 14:20:12 +0100227{
228public:
229 QSymm16Decoder(const int16_t* data, const float scale, const int32_t offset)
230 : TypedIterator(data), m_Scale(scale), m_Offset(offset) {}
231
Matthew Benthamc394a6d2019-06-24 12:51:25 +0100232 QSymm16Decoder(const float scale, const int32_t offset)
233 : QSymm16Decoder(nullptr, scale, offset) {}
234
Sadik Armagan2999a022019-04-09 14:20:12 +0100235 float Get() const override
236 {
237 return armnn::Dequantize(*m_Iterator, m_Scale, m_Offset);
238 }
Finn Williamsea8ce702020-09-29 19:54:00 +0100239 std::vector<float> DecodeTensor (const TensorShape& tensorShape,
Finn Williamsea8ce702020-09-29 19:54:00 +0100240 const bool isDepthwise) override
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100241 {
Jan Eilers53ef7952021-06-02 12:01:25 +0100242 IgnoreUnused(isDepthwise);
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100243
Finn Williamsea8ce702020-09-29 19:54:00 +0100244 const unsigned int size = tensorShape.GetNumElements();
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100245 std::vector<float> decodedTensor;
246 decodedTensor.reserve(size);
247
248 for (uint32_t i = 0; i < size; ++i)
249 {
250 this->operator[](i);
251 decodedTensor.emplace_back(armnn::Dequantize(*m_Iterator, m_Scale, m_Offset));
252 }
253
254 return decodedTensor;
255 }
256
Sadik Armagan2999a022019-04-09 14:20:12 +0100257private:
258 const float m_Scale;
259 const int32_t m_Offset;
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100260
Sadik Armagan2999a022019-04-09 14:20:12 +0100261};
262
Narumol Prangnawarat88325222020-03-06 14:45:57 +0000263class BFloat16Decoder : public TypedIterator<const BFloat16, Decoder<float>>
264{
265public:
266 BFloat16Decoder(const BFloat16* data)
267 : TypedIterator(data) {}
268
269 BFloat16Decoder()
270 : BFloat16Decoder(nullptr) {}
271
272 float Get() const override
273 {
274 float val = 0.f;
275 armnnUtils::FloatingPointConverter::ConvertBFloat16ToFloat32(m_Iterator, 1, &val);
276 return val;
277 }
Finn Williamsea8ce702020-09-29 19:54:00 +0100278 std::vector<float> DecodeTensor (const TensorShape& tensorShape,
Finn Williamsea8ce702020-09-29 19:54:00 +0100279 const bool isDepthwise) override
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100280 {
Jan Eilers53ef7952021-06-02 12:01:25 +0100281 IgnoreUnused(isDepthwise);
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100282
Finn Williamsea8ce702020-09-29 19:54:00 +0100283 const unsigned int size = tensorShape.GetNumElements();
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100284 std::vector<float> decodedTensor;
285 decodedTensor.reserve(size);
286
287 for (uint32_t i = 0; i < size; ++i)
288 {
289 this->operator[](i);
290
291 float val = 0.f;
292 armnnUtils::FloatingPointConverter::ConvertBFloat16ToFloat32(m_Iterator, 1, &val);
293 decodedTensor.emplace_back(val);
294 }
295
296 return decodedTensor;
297 }
298
Narumol Prangnawarat88325222020-03-06 14:45:57 +0000299};
300
Matthew Jacksone69c3992019-09-09 14:31:21 +0100301class Float16Decoder : public TypedIterator<const Half, Decoder<float>>
Sadik Armagan2e6dc3a2019-04-03 17:48:18 +0100302{
303public:
Matthew Jacksone69c3992019-09-09 14:31:21 +0100304 Float16Decoder(const Half* data)
Sadik Armagan2e6dc3a2019-04-03 17:48:18 +0100305 : TypedIterator(data) {}
306
Matthew Jacksone69c3992019-09-09 14:31:21 +0100307 Float16Decoder()
308 : Float16Decoder(nullptr) {}
309
310 float Get() const override
311 {
312 float val = 0.f;
313 armnnUtils::FloatingPointConverter::ConvertFloat16To32(m_Iterator, 1, &val);
314 return val;
315 }
Finn Williamsea8ce702020-09-29 19:54:00 +0100316 std::vector<float> DecodeTensor (const TensorShape& tensorShape,
Finn Williamsea8ce702020-09-29 19:54:00 +0100317 const bool isDepthwise) override
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100318 {
Jan Eilers53ef7952021-06-02 12:01:25 +0100319 IgnoreUnused(isDepthwise);
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100320
Finn Williamsea8ce702020-09-29 19:54:00 +0100321 const unsigned int size = tensorShape.GetNumElements();
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100322 std::vector<float> decodedTensor;
323 decodedTensor.reserve(size);
324
325 for (uint32_t i = 0; i < size; ++i)
326 {
327 float val = 0.f;
328 this->operator[](i);
329 armnnUtils::FloatingPointConverter::ConvertFloat16To32(m_Iterator, 1, &val);
330 decodedTensor.emplace_back(val);
331 }
332
333 return decodedTensor;
334 }
335
336
Matthew Jacksone69c3992019-09-09 14:31:21 +0100337};
338
339class Float32Decoder : public TypedIterator<const float, Decoder<float>>
340{
341public:
342 Float32Decoder(const float* data)
343 : TypedIterator(data) {}
344
345 Float32Decoder()
346 : Float32Decoder(nullptr) {}
Matthew Benthamc394a6d2019-06-24 12:51:25 +0100347
Derek Lambertif30f7d32019-04-09 10:25:02 +0100348 float Get() const override
Sadik Armagan2e6dc3a2019-04-03 17:48:18 +0100349 {
Derek Lambertif30f7d32019-04-09 10:25:02 +0100350 return *m_Iterator;
Sadik Armagan2e6dc3a2019-04-03 17:48:18 +0100351 }
Finn Williamsea8ce702020-09-29 19:54:00 +0100352 std::vector<float> DecodeTensor (const TensorShape& tensorShape,
Finn Williamsea8ce702020-09-29 19:54:00 +0100353 const bool isDepthwise) override
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100354 {
Jan Eilers53ef7952021-06-02 12:01:25 +0100355 IgnoreUnused(isDepthwise);
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
359 decodedTensor.reserve(size);
360 decodedTensor.assign(m_Start, m_Start + size);
361
362 return decodedTensor;
363 }
Sadik Armagan2e6dc3a2019-04-03 17:48:18 +0100364};
365
Mike Kelly9b398322019-05-22 17:21:49 +0100366class ScaledInt32Decoder : public TypedIterator<const int32_t, Decoder<float>>
367{
368public:
369 ScaledInt32Decoder(const int32_t* data, const float scale)
370 : TypedIterator(data), m_Scale(scale) {}
371
Matthew Benthamc394a6d2019-06-24 12:51:25 +0100372 ScaledInt32Decoder(const float scale)
373 : ScaledInt32Decoder(nullptr, scale) {}
374
Mike Kelly9b398322019-05-22 17:21:49 +0100375 float Get() const override
376 {
377 return static_cast<float>(*m_Iterator) * m_Scale;
378 }
Finn Williamsea8ce702020-09-29 19:54:00 +0100379 std::vector<float> DecodeTensor (const TensorShape& tensorShape,
Finn Williamsea8ce702020-09-29 19:54:00 +0100380 const bool isDepthwise) override
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100381 {
Jan Eilers53ef7952021-06-02 12:01:25 +0100382 IgnoreUnused(isDepthwise);
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100383
Finn Williamsea8ce702020-09-29 19:54:00 +0100384 const unsigned int size = tensorShape.GetNumElements();
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100385 std::vector<float> decodedTensor;
386 decodedTensor.reserve(size);
387
388 for (uint32_t i = 0; i < size; ++i)
389 {
390 this->operator[](i);
391 decodedTensor.emplace_back(static_cast<float>(*m_Iterator) * m_Scale);
392 }
393
394 return decodedTensor;
395 }
396
Mike Kelly9b398322019-05-22 17:21:49 +0100397private:
398 const float m_Scale;
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100399
Mike Kelly9b398322019-05-22 17:21:49 +0100400};
401
Aron Virginas-Tar198ee402019-08-02 18:54:28 +0100402class Int32Decoder : public TypedIterator<const int32_t, Decoder<float>>
403{
404public:
405 Int32Decoder(const int32_t* data)
406 : TypedIterator(data) {}
407
408 Int32Decoder()
409 : Int32Decoder(nullptr) {}
410
411 float Get() const override
412 {
413 return static_cast<float>(*m_Iterator);
414 }
Finn Williamsea8ce702020-09-29 19:54:00 +0100415 std::vector<float> DecodeTensor (const TensorShape& tensorShape,
Finn Williamsea8ce702020-09-29 19:54:00 +0100416 const bool isDepthwise) override
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100417 {
Jan Eilers53ef7952021-06-02 12:01:25 +0100418 IgnoreUnused(isDepthwise);
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100419
Finn Williamsea8ce702020-09-29 19:54:00 +0100420 const unsigned int size = tensorShape.GetNumElements();
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100421 std::vector<float> decodedTensor;
422 decodedTensor.reserve(size);
423
424 for (uint32_t i = 0; i < size; ++i)
425 {
426 this->operator[](i);
427 decodedTensor.emplace_back(static_cast<float>(*m_Iterator));
428 }
429
430 return decodedTensor;
431 }
Aron Virginas-Tar198ee402019-08-02 18:54:28 +0100432};
433
Finn Williamscbd2c232020-06-22 15:58:32 +0100434class Int32ToInt32tDecoder : public TypedIterator<const int32_t, Decoder<int32_t>>
435{
436public:
437 Int32ToInt32tDecoder(const int32_t* data)
438 : TypedIterator(data){}
439
440 Int32ToInt32tDecoder()
441 : Int32ToInt32tDecoder(nullptr) {}
442
443 int32_t Get() const override
444 {
445 return *m_Iterator;
446 }
Finn Williamsea8ce702020-09-29 19:54:00 +0100447 std::vector<float> DecodeTensor (const TensorShape& tensorShape,
Finn Williamsea8ce702020-09-29 19:54:00 +0100448 const bool isDepthwise) override
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100449 {
Jan Eilers53ef7952021-06-02 12:01:25 +0100450 IgnoreUnused(isDepthwise);
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100451
Finn Williamsea8ce702020-09-29 19:54:00 +0100452 const unsigned int size = tensorShape.GetNumElements();
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100453 std::vector<float> decodedTensor;
454 decodedTensor.reserve(size);
455
456 for (uint32_t i = 0; i < size; ++i)
457 {
458 this->operator[](i);
459 decodedTensor.emplace_back(*m_Iterator);
460 }
461
462 return decodedTensor;
463 }
Finn Williamscbd2c232020-06-22 15:58:32 +0100464};
465
Sadik Armaganb60dd242020-03-19 13:53:16 +0000466class BooleanDecoder : public TypedIterator<const uint8_t, Decoder<float>>
467{
468public:
469 BooleanDecoder(const uint8_t* data)
470 : TypedIterator(data) {}
471
472 BooleanDecoder()
473 : BooleanDecoder(nullptr) {}
474
475 float Get() const override
476 {
477 return *m_Iterator;
478 }
Finn Williamsea8ce702020-09-29 19:54:00 +0100479 std::vector<float> DecodeTensor (const TensorShape& tensorShape,
Finn Williamsea8ce702020-09-29 19:54:00 +0100480 const bool isDepthwise) override
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100481 {
Jan Eilers53ef7952021-06-02 12:01:25 +0100482 IgnoreUnused(isDepthwise);
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100483
Finn Williamsea8ce702020-09-29 19:54:00 +0100484 const unsigned int size = tensorShape.GetNumElements();
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100485 std::vector<float> decodedTensor;
486 decodedTensor.reserve(size);
487
488 for (uint32_t i = 0; i < size; ++i)
489 {
490 this->operator[](i);
491 decodedTensor.emplace_back(*m_Iterator);
492 }
493
494 return decodedTensor;
495 }
Sadik Armaganb60dd242020-03-19 13:53:16 +0000496};
497
James Conroyaba90cd2020-11-06 16:28:18 +0000498class BooleanDecoderBool : public TypedIterator<const uint8_t, Decoder<bool>>
499{
500public:
501 BooleanDecoderBool(const uint8_t* data)
502 : TypedIterator(data) {}
503
504 BooleanDecoderBool()
505 : BooleanDecoderBool(nullptr) {}
506
507 bool Get() const override
508 {
509 return *m_Iterator;
510 }
511
512 std::vector<float> DecodeTensor(const TensorShape& tensorShape,
James Conroyaba90cd2020-11-06 16:28:18 +0000513 const bool isDepthwise) override
514 {
Jan Eilers53ef7952021-06-02 12:01:25 +0100515 IgnoreUnused(isDepthwise);
James Conroyaba90cd2020-11-06 16:28:18 +0000516
517 const unsigned int size = tensorShape.GetNumElements();
518 std::vector<float> decodedTensor;
519 decodedTensor.reserve(size);
520
521 for (uint32_t i = 0; i < size; ++i)
522 {
523 this->operator[](i);
524 decodedTensor.emplace_back(*m_Iterator);
525 }
526
527 return decodedTensor;
528 }
529};
530
Derek Lambertif30f7d32019-04-09 10:25:02 +0100531class QASymm8Encoder : public TypedIterator<uint8_t, Encoder<float>>
Sadik Armagan2e6dc3a2019-04-03 17:48:18 +0100532{
533public:
534 QASymm8Encoder(uint8_t* data, const float scale, const int32_t offset)
535 : TypedIterator(data), m_Scale(scale), m_Offset(offset) {}
536
Matthew Benthamc394a6d2019-06-24 12:51:25 +0100537 QASymm8Encoder(const float scale, const int32_t offset)
538 : QASymm8Encoder(nullptr, scale, offset) {}
539
Derek Lambertif30f7d32019-04-09 10:25:02 +0100540 void Set(float right) override
Sadik Armagan2e6dc3a2019-04-03 17:48:18 +0100541 {
542 *m_Iterator = armnn::Quantize<uint8_t>(right, m_Scale, m_Offset);
543 }
544
Nattapat Chaimanowongeb2b3292019-05-07 12:02:30 +0100545 float Get() const override
546 {
547 return armnn::Dequantize(*m_Iterator, m_Scale, m_Offset);
548 }
549
Sadik Armagan2e6dc3a2019-04-03 17:48:18 +0100550private:
551 const float m_Scale;
552 const int32_t m_Offset;
553};
554
Ryan OShea9add1202020-02-07 10:06:33 +0000555class QASymmS8Encoder : public TypedIterator<int8_t, Encoder<float>>
556{
557public:
558 QASymmS8Encoder(int8_t* data, const float scale, const int32_t offset)
559 : TypedIterator(data), m_Scale(scale), m_Offset(offset) {}
560
561 QASymmS8Encoder(const float scale, const int32_t offset)
562 : QASymmS8Encoder(nullptr, scale, offset) {}
563
564 void Set(float right) override
565 {
566 *m_Iterator = armnn::Quantize<int8_t>(right, m_Scale, m_Offset);
567 }
568
569 float Get() const override
570 {
571 return armnn::Dequantize(*m_Iterator, m_Scale, m_Offset);
572 }
573
574private:
575 const float m_Scale;
576 const int32_t m_Offset;
577};
578
Finn Williamsfd271062019-12-04 14:27:27 +0000579class QSymmS8Encoder : public TypedIterator<int8_t, Encoder<float>>
580{
581public:
582 QSymmS8Encoder(int8_t* data, const float scale, const int32_t offset)
583 : TypedIterator(data), m_Scale(scale), m_Offset(offset) {}
584
585 QSymmS8Encoder(const float scale, const int32_t offset)
586 : QSymmS8Encoder(nullptr, scale, offset) {}
587
588 void Set(float right) override
589 {
590 *m_Iterator = armnn::Quantize<int8_t>(right, m_Scale, m_Offset);
591 }
592
593 float Get() const override
594 {
595 return armnn::Dequantize(*m_Iterator, m_Scale, m_Offset);
596 }
597
598private:
599 const float m_Scale;
600 const int32_t m_Offset;
601};
602
Derek Lambertif30f7d32019-04-09 10:25:02 +0100603class QSymm16Encoder : public TypedIterator<int16_t, Encoder<float>>
604{
605public:
606 QSymm16Encoder(int16_t* data, const float scale, const int32_t offset)
607 : TypedIterator(data), m_Scale(scale), m_Offset(offset) {}
608
Matthew Benthamc394a6d2019-06-24 12:51:25 +0100609 QSymm16Encoder(const float scale, const int32_t offset)
610 : QSymm16Encoder(nullptr, scale, offset) {}
611
Derek Lambertif30f7d32019-04-09 10:25:02 +0100612 void Set(float right) override
613 {
614 *m_Iterator = armnn::Quantize<int16_t>(right, m_Scale, m_Offset);
615 }
616
Nattapat Chaimanowongeb2b3292019-05-07 12:02:30 +0100617 float Get() const override
618 {
619 return armnn::Dequantize(*m_Iterator, m_Scale, m_Offset);
620 }
621
Derek Lambertif30f7d32019-04-09 10:25:02 +0100622private:
623 const float m_Scale;
624 const int32_t m_Offset;
625};
626
Narumol Prangnawarat88325222020-03-06 14:45:57 +0000627class BFloat16Encoder : public TypedIterator<armnn::BFloat16, Encoder<float>>
628{
629public:
630 BFloat16Encoder(armnn::BFloat16* data)
631 : TypedIterator(data) {}
632
633 BFloat16Encoder()
634 : BFloat16Encoder(nullptr) {}
635
636 void Set(float right) override
637 {
638 armnnUtils::FloatingPointConverter::ConvertFloat32ToBFloat16(&right, 1, m_Iterator);
639 }
640
641 float Get() const override
642 {
643 float val = 0.f;
644 armnnUtils::FloatingPointConverter::ConvertBFloat16ToFloat32(m_Iterator, 1, &val);
645 return val;
646 }
647};
648
Matthew Jacksone69c3992019-09-09 14:31:21 +0100649class Float16Encoder : public TypedIterator<Half, Encoder<float>>
Derek Lambertif30f7d32019-04-09 10:25:02 +0100650{
651public:
Matthew Jacksone69c3992019-09-09 14:31:21 +0100652 Float16Encoder(Half* data)
Derek Lambertif30f7d32019-04-09 10:25:02 +0100653 : TypedIterator(data) {}
654
Matthew Jacksone69c3992019-09-09 14:31:21 +0100655 Float16Encoder()
656 : Float16Encoder(nullptr) {}
657
658 void Set(float right) override
659 {
660 armnnUtils::FloatingPointConverter::ConvertFloat32To16(&right, 1, m_Iterator);
661 }
662
663 float Get() const override
664 {
665 float val = 0.f;
666 armnnUtils::FloatingPointConverter::ConvertFloat16To32(m_Iterator, 1, &val);
667 return val;
668 }
669};
670
671class Float32Encoder : public TypedIterator<float, Encoder<float>>
672{
673public:
674 Float32Encoder(float* data)
675 : TypedIterator(data) {}
676
677 Float32Encoder()
678 : Float32Encoder(nullptr) {}
Matthew Benthamc394a6d2019-06-24 12:51:25 +0100679
Derek Lambertif30f7d32019-04-09 10:25:02 +0100680 void Set(float right) override
681 {
682 *m_Iterator = right;
683 }
Nattapat Chaimanowongeb2b3292019-05-07 12:02:30 +0100684
685 float Get() const override
686 {
687 return *m_Iterator;
688 }
Derek Lambertif30f7d32019-04-09 10:25:02 +0100689};
690
Aron Virginas-Tar198ee402019-08-02 18:54:28 +0100691class Int32Encoder : public TypedIterator<int32_t, Encoder<float>>
692{
693public:
694 Int32Encoder(int32_t* data)
695 : TypedIterator(data) {}
696
697 Int32Encoder()
698 : Int32Encoder(nullptr) {}
699
700 void Set(float right) override
701 {
702 *m_Iterator = static_cast<int32_t>(right);
703 }
704
705 float Get() const override
706 {
707 return static_cast<float>(*m_Iterator);
708 }
709};
710
Finn Williamscbd2c232020-06-22 15:58:32 +0100711class Int32ToInt32tEncoder : public TypedIterator<int32_t, Encoder<int32_t>>
712{
713public:
714 Int32ToInt32tEncoder(int32_t* data)
715 : TypedIterator(data){}
716
717 Int32ToInt32tEncoder()
718 : Int32ToInt32tEncoder(nullptr) {}
719
720 void Set(int32_t right) override
721 {
722 *m_Iterator = right;
723 }
724
725 int32_t Get() const override
726 {
727 return *m_Iterator;
728 }
729};
730
Derek Lambertif30f7d32019-04-09 10:25:02 +0100731class BooleanEncoder : public TypedIterator<uint8_t, Encoder<bool>>
Sadik Armagan2e6dc3a2019-04-03 17:48:18 +0100732{
733public:
734 BooleanEncoder(uint8_t* data)
735 : TypedIterator(data) {}
736
Matthew Benthamc394a6d2019-06-24 12:51:25 +0100737 BooleanEncoder()
738 : BooleanEncoder(nullptr) {}
739
Sadik Armagan2e6dc3a2019-04-03 17:48:18 +0100740 void Set(bool right) override
741 {
742 *m_Iterator = right;
743 }
Nattapat Chaimanowongeb2b3292019-05-07 12:02:30 +0100744
745 bool Get() const override
746 {
747 return *m_Iterator;
748 }
Sadik Armagan2e6dc3a2019-04-03 17:48:18 +0100749};
750
Jan Eilers53ef7952021-06-02 12:01:25 +0100751/// PerAxisIterator for per-axis quantization. Iterates over a tensor as layed out in memory and keeps track
752/// of the axis index.
Keith Davis5236e1d2019-11-04 08:58:33 +0000753template<typename T, typename Base>
754class PerAxisIterator : public Base
755{
756public:
Jan Eilers53ef7952021-06-02 12:01:25 +0100757 PerAxisIterator(T* data = nullptr,
758 unsigned int axisFactor = 0,
759 unsigned int axisDimensionality=0)
760 : m_Iterator(data),
761 m_Start(data),
762 m_AxisIndex(0), // iterates over the dimension of axis
763 m_AxisDimensionality(axisDimensionality), // tensorShape[quantization_dim]
764 m_AxisFactor(axisFactor),
765 m_Index(0)
Keith Davis5236e1d2019-11-04 08:58:33 +0000766 {}
767
Jan Eilers53ef7952021-06-02 12:01:25 +0100768 PerAxisIterator(T* data = nullptr,
769 const armnn::TensorShape& tensorShape = TensorShape(),
770 const unsigned int axis = 0)
771 : m_Iterator(data),
772 m_Start(data),
773 m_AxisIndex(0),
774 m_Index(0)
Keith Davis5236e1d2019-11-04 08:58:33 +0000775 {
Jan Eilers53ef7952021-06-02 12:01:25 +0100776 m_AxisDimensionality = tensorShape[axis];
777 m_AxisFactor = armnnUtils::GetNumElementsAfter(tensorShape, axis);
Keith Davis5236e1d2019-11-04 08:58:33 +0000778 }
779
780 void Reset(void* data) override
781 {
782 m_Iterator = reinterpret_cast<T*>(data);
783 m_Start = m_Iterator;
784 m_AxisIndex = 0;
Jan Eilers53ef7952021-06-02 12:01:25 +0100785 m_Index = 0;
Keith Davis5236e1d2019-11-04 08:58:33 +0000786 }
787
788 PerAxisIterator& operator++() override
789 {
Jan Eilers53ef7952021-06-02 12:01:25 +0100790 ++m_Index;
791 this -> operator[](m_Index);
Keith Davis5236e1d2019-11-04 08:58:33 +0000792 return *this;
793 }
794
795 PerAxisIterator& operator+=(const unsigned int increment) override
796 {
Jan Eilers53ef7952021-06-02 12:01:25 +0100797 m_Index += increment;
798 this -> operator[](m_Index);
Keith Davis5236e1d2019-11-04 08:58:33 +0000799 return *this;
800 }
801
802 PerAxisIterator& operator-=(const unsigned int decrement) override
803 {
Jan Eilers53ef7952021-06-02 12:01:25 +0100804 m_Index -= decrement;
805 this -> operator[](m_Index);
806 return *this;
807 }
808
809
810 inline PerAxisIterator& SetIndexOnMem(const unsigned int index)
811 {
Narumol Prangnawaratac2770a2020-04-01 16:51:23 +0100812 ARMNN_ASSERT(m_Iterator);
Jan Eilers53ef7952021-06-02 12:01:25 +0100813 m_Iterator = m_Start + index;
814 if (index < m_AxisFactor)
815 {
816 m_AxisIndex = 0;
817 }
818 else
819 {
820 m_AxisIndex = (index / m_AxisFactor) % m_AxisDimensionality;
821 }
822 m_Index = index;
Keith Davis5236e1d2019-11-04 08:58:33 +0000823 return *this;
824 }
825
826 PerAxisIterator& operator[](const unsigned int index) override
827 {
Jan Eilers53ef7952021-06-02 12:01:25 +0100828 SetIndexOnMem(index);
Keith Davis5236e1d2019-11-04 08:58:33 +0000829 return *this;
830 }
831
832 protected:
833 T* m_Iterator;
834 T* m_Start;
835 unsigned int m_AxisIndex;
Jan Eilers53ef7952021-06-02 12:01:25 +0100836 unsigned int m_AxisDimensionality; // tensorShape[quantization_dim]
Keith Davis5236e1d2019-11-04 08:58:33 +0000837 unsigned int m_AxisFactor;
Jan Eilers53ef7952021-06-02 12:01:25 +0100838 unsigned int m_Index;
Keith Davis5236e1d2019-11-04 08:58:33 +0000839};
840
841class QSymm8PerAxisDecoder : public PerAxisIterator<const int8_t, Decoder<float>>
842{
843public:
Jan Eilers53ef7952021-06-02 12:01:25 +0100844 QSymm8PerAxisDecoder(const int8_t* data, const armnn::TensorInfo& tensorInfo)
845 : PerAxisIterator(data, tensorInfo.GetShape(), tensorInfo.GetQuantizationDim().value()),
846 m_Scales(tensorInfo.GetQuantizationScales())
847 {}
Keith Davis5236e1d2019-11-04 08:58:33 +0000848
849 float Get() const override
850 {
Jan Eilers53ef7952021-06-02 12:01:25 +0100851 return armnn::Dequantize(*m_Iterator, GetScale(), 0);
Keith Davis5236e1d2019-11-04 08:58:33 +0000852 }
853
854 // Get scale of the current value
855 float GetScale() const
856 {
Finn Williamsea8ce702020-09-29 19:54:00 +0100857 return m_Scales[m_AxisIndex];
Keith Davis5236e1d2019-11-04 08:58:33 +0000858 }
859
Finn Williamsea8ce702020-09-29 19:54:00 +0100860 std::vector<float> DecodeTensor(const TensorShape &tensorShape,
Finn Williamsea8ce702020-09-29 19:54:00 +0100861 bool isDepthwise) override
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100862 {
Jan Eilers53ef7952021-06-02 12:01:25 +0100863 IgnoreUnused(isDepthwise);
Finn Williamsea8ce702020-09-29 19:54:00 +0100864
Jan Eilers53ef7952021-06-02 12:01:25 +0100865 const unsigned int size = tensorShape.GetNumElements();
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100866 std::vector<float> decodedTensor;
867 decodedTensor.reserve(size);
868
Jan Eilers53ef7952021-06-02 12:01:25 +0100869 for (uint32_t i = 0; i < size; ++i)
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100870 {
Jan Eilers53ef7952021-06-02 12:01:25 +0100871 SetIndexOnMem(i);
872 decodedTensor.emplace_back(armnn::Dequantize(*m_Iterator, GetScale(), 0));
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100873 }
874 return decodedTensor;
875 }
876
Keith Davis5236e1d2019-11-04 08:58:33 +0000877private:
Finn Williamsea8ce702020-09-29 19:54:00 +0100878 std::vector<float> m_Scales;
Keith Davis5236e1d2019-11-04 08:58:33 +0000879};
880
881class QSymm8PerAxisEncoder : public PerAxisIterator<int8_t, Encoder<float>>
882{
883public:
884 QSymm8PerAxisEncoder(int8_t* data, const std::vector<float>& scale, unsigned int axisFactor)
885 : PerAxisIterator(data, axisFactor), m_Scale(scale) {}
886
887 void Set(float right)
888 {
889 *m_Iterator = armnn::Quantize<int8_t>(right, m_Scale[m_AxisIndex], 0);
890 }
891
892 float Get() const
893 {
894 return armnn::Dequantize(*m_Iterator, m_Scale[m_AxisIndex], 0);
895 }
896
897 // Get scale of the current value
898 float GetScale() const
899 {
900 return m_Scale[m_AxisIndex];
901 }
902
903private:
904 std::vector<float> m_Scale;
905};
906
Aron Virginas-Tarb67f9572019-11-04 15:00:19 +0000907class ScaledInt32PerAxisDecoder : public PerAxisIterator<const int32_t, Decoder<float>>
908{
909public:
Jan Eilers53ef7952021-06-02 12:01:25 +0100910 ScaledInt32PerAxisDecoder(const int32_t* data, const armnn::TensorInfo tensorInfo)
911 : PerAxisIterator(data, tensorInfo.GetShape(), tensorInfo.GetQuantizationDim().value()),
912 m_Scales(tensorInfo.GetQuantizationScales())
913 {}
Aron Virginas-Tarb67f9572019-11-04 15:00:19 +0000914
915 float Get() const override
916 {
917 return armnn::Dequantize(*m_Iterator, m_Scales[m_AxisIndex], 0);
918 }
919
920 // Get scale of the current value
921 float GetScale() const
922 {
923 return m_Scales[m_AxisIndex];
924 }
925
Finn Williamsea8ce702020-09-29 19:54:00 +0100926 std::vector<float> DecodeTensor(const TensorShape &tensorShape,
Finn Williamsea8ce702020-09-29 19:54:00 +0100927 bool isDepthwise) override
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100928 {
Finn Williamsea8ce702020-09-29 19:54:00 +0100929 const uint32_t size = tensorShape.GetNumElements();
Finn Williamsea8ce702020-09-29 19:54:00 +0100930
931 const uint32_t stepSize = isDepthwise ?
932 tensorShape[2] * tensorShape[3] : tensorShape.GetNumElements() / tensorShape[0];
933
Jan Eilers53ef7952021-06-02 12:01:25 +0100934 const uint32_t stepNum = size / stepSize;
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100935
936 std::vector<float> decodedTensor;
937 decodedTensor.reserve(size);
938
Finn Williamsea8ce702020-09-29 19:54:00 +0100939 // channelMultiplier is only used in depthwise convolutions and in other cases will have no effect
940 // stepSize is the length of a contiguous area sharing a quantization scale within a tensor
941 // stepNum is the number of those steps/blocks in the tensor
Jan Eilers53ef7952021-06-02 12:01:25 +0100942 for (uint32_t step = 0; step < stepNum; ++step)
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100943 {
Jan Eilers53ef7952021-06-02 12:01:25 +0100944 //scale = (channelMultiplier * step + mult) % scaleSize;
945 for (uint32_t i = 0; i < stepSize; ++i)
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100946 {
Jan Eilers53ef7952021-06-02 12:01:25 +0100947 unsigned int index = step * stepSize + i;
948 this->operator[](index);
949 decodedTensor.emplace_back(armnn::Dequantize(*m_Iterator, m_Scales[step], 0));
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100950 }
951 }
952 return decodedTensor;
953 }
954
Aron Virginas-Tarb67f9572019-11-04 15:00:19 +0000955private:
956 std::vector<float> m_Scales;
957};
958
959} // namespace armnn