blob: a10f383e90eb9ddb72a60c1be2cfc6913d92f4f3 [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>
Matteo Martincighe011d202019-11-28 11:35:47 +000011#include <armnnUtils/FloatingPointConverter.hpp>
12
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
Aron Virginas-Tar5edc8812019-11-05 18:00:21 +000025 virtual BaseIterator& SetIndex(unsigned int index, unsigned int axisIndex = 0) = 0;
26
Sadik Armagan2e6dc3a2019-04-03 17:48:18 +010027 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,
50 const unsigned int channelMultiplier = 1,
51 bool isDepthwise = false) = 0;
Sadik Armagan2e6dc3a2019-04-03 17:48:18 +010052};
53
Derek Lambertif30f7d32019-04-09 10:25:02 +010054template<typename IType>
Sadik Armagan2e6dc3a2019-04-03 17:48:18 +010055class Encoder : public BaseIterator
56{
57public:
Derek Lambertif30f7d32019-04-09 10:25:02 +010058 Encoder() {}
Sadik Armagan2e6dc3a2019-04-03 17:48:18 +010059
60 virtual ~Encoder() {}
61
Matthew Benthamc394a6d2019-06-24 12:51:25 +010062 virtual void Reset(void*) = 0;
63
Derek Lambertif30f7d32019-04-09 10:25:02 +010064 virtual void Set(IType right) = 0;
Nattapat Chaimanowongeb2b3292019-05-07 12:02:30 +010065
66 virtual IType Get() const = 0;
Sadik Armagan2e6dc3a2019-04-03 17:48:18 +010067};
68
69template<typename T, typename Base>
70class TypedIterator : public Base
71{
72public:
Matthew Benthamc394a6d2019-06-24 12:51:25 +010073 TypedIterator(T* data = nullptr)
Francis Murtagh43aec582019-05-27 12:14:10 +010074 : m_Iterator(data), m_Start(data)
Sadik Armagan2e6dc3a2019-04-03 17:48:18 +010075 {}
76
Matthew Benthamc394a6d2019-06-24 12:51:25 +010077 void Reset(void* data) override
78 {
79 m_Iterator = reinterpret_cast<T*>(data);
80 m_Start = m_Iterator;
81 }
82
Sadik Armagan2e6dc3a2019-04-03 17:48:18 +010083 TypedIterator& operator++() override
84 {
Narumol Prangnawaratac2770a2020-04-01 16:51:23 +010085 ARMNN_ASSERT(m_Iterator);
Sadik Armagan2e6dc3a2019-04-03 17:48:18 +010086 ++m_Iterator;
87 return *this;
88 }
89
90 TypedIterator& operator+=(const unsigned int increment) override
91 {
Narumol Prangnawaratac2770a2020-04-01 16:51:23 +010092 ARMNN_ASSERT(m_Iterator);
Sadik Armagan2e6dc3a2019-04-03 17:48:18 +010093 m_Iterator += increment;
94 return *this;
95 }
96
97 TypedIterator& operator-=(const unsigned int increment) override
98 {
Narumol Prangnawaratac2770a2020-04-01 16:51:23 +010099 ARMNN_ASSERT(m_Iterator);
Sadik Armagan2e6dc3a2019-04-03 17:48:18 +0100100 m_Iterator -= increment;
101 return *this;
102 }
103
Francis Murtagh43aec582019-05-27 12:14:10 +0100104 TypedIterator& operator[](const unsigned int index) override
105 {
Narumol Prangnawaratac2770a2020-04-01 16:51:23 +0100106 ARMNN_ASSERT(m_Iterator);
Francis Murtagh43aec582019-05-27 12:14:10 +0100107 m_Iterator = m_Start + index;
108 return *this;
109 }
110
Aron Virginas-Tar5edc8812019-11-05 18:00:21 +0000111 TypedIterator& SetIndex(unsigned int index, unsigned int axisIndex = 0) override
112 {
Jan Eilers8eb25602020-03-09 12:13:48 +0000113 IgnoreUnused(axisIndex);
Narumol Prangnawaratac2770a2020-04-01 16:51:23 +0100114 ARMNN_ASSERT(m_Iterator);
Aron Virginas-Tar5edc8812019-11-05 18:00:21 +0000115 m_Iterator = m_Start + index;
116 return *this;
117 }
118
Nattapat Chaimanowongeb2b3292019-05-07 12:02:30 +0100119protected:
Sadik Armagan2e6dc3a2019-04-03 17:48:18 +0100120 T* m_Iterator;
Francis Murtagh43aec582019-05-27 12:14:10 +0100121 T* m_Start;
Sadik Armagan2e6dc3a2019-04-03 17:48:18 +0100122};
123
Derek Lambertif30f7d32019-04-09 10:25:02 +0100124class QASymm8Decoder : public TypedIterator<const uint8_t, Decoder<float>>
Sadik Armagan2e6dc3a2019-04-03 17:48:18 +0100125{
126public:
127 QASymm8Decoder(const uint8_t* data, const float scale, const int32_t offset)
128 : TypedIterator(data), m_Scale(scale), m_Offset(offset) {}
129
Matthew Benthamc394a6d2019-06-24 12:51:25 +0100130 QASymm8Decoder(const float scale, const int32_t offset)
131 : QASymm8Decoder(nullptr, scale, offset) {}
132
Sadik Armagan2e6dc3a2019-04-03 17:48:18 +0100133 float Get() const override
134 {
135 return armnn::Dequantize(*m_Iterator, m_Scale, m_Offset);
136 }
Finn Williamsea8ce702020-09-29 19:54:00 +0100137 std::vector<float> DecodeTensor (const TensorShape& tensorShape,
138 const unsigned int channelMultiplier,
139 const bool isDepthwise) override
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100140 {
Finn Williamsea8ce702020-09-29 19:54:00 +0100141 IgnoreUnused(channelMultiplier, isDepthwise);
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100142
Finn Williamsea8ce702020-09-29 19:54:00 +0100143 const unsigned int size = tensorShape.GetNumElements();
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100144 std::vector<float> decodedTensor;
145 decodedTensor.reserve(size);
146
147 for (uint32_t i = 0; i < size; ++i)
148 {
149 this->operator[](i);
150 decodedTensor.emplace_back(armnn::Dequantize(*m_Iterator, m_Scale, m_Offset));
151 }
152
153 return decodedTensor;
154 }
155
Sadik Armagan2e6dc3a2019-04-03 17:48:18 +0100156private:
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100157
Sadik Armagan2e6dc3a2019-04-03 17:48:18 +0100158 const float m_Scale;
159 const int32_t m_Offset;
160};
161
Ryan OShea9add1202020-02-07 10:06:33 +0000162class QASymmS8Decoder : public TypedIterator<const int8_t, Decoder<float>>
163{
164public:
165 QASymmS8Decoder(const int8_t* data, const float scale, const int32_t offset)
166 : TypedIterator(data), m_Scale(scale), m_Offset(offset) {}
167
168 QASymmS8Decoder(const float scale, const int32_t offset)
169 : QASymmS8Decoder(nullptr, scale, offset) {}
170
171 float Get() const override
172 {
173 return armnn::Dequantize(*m_Iterator, m_Scale, m_Offset);
174 }
Finn Williamsea8ce702020-09-29 19:54:00 +0100175 std::vector<float> DecodeTensor (const TensorShape& tensorShape,
176 const unsigned int channelMultiplier,
177 const bool isDepthwise) override
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100178 {
Finn Williamsea8ce702020-09-29 19:54:00 +0100179 IgnoreUnused(channelMultiplier, isDepthwise);
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100180
Finn Williamsea8ce702020-09-29 19:54:00 +0100181 const unsigned int size = tensorShape.GetNumElements();
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100182 std::vector<float> decodedTensor;
183 decodedTensor.reserve(size);
184
185 for (uint32_t i = 0; i < size; ++i)
186 {
187 this->operator[](i);
188 decodedTensor.emplace_back(armnn::Dequantize(*m_Iterator, m_Scale, m_Offset));
189 }
190
191 return decodedTensor;
192 }
193
Ryan OShea9add1202020-02-07 10:06:33 +0000194private:
195 const float m_Scale;
196 const int32_t m_Offset;
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100197
Ryan OShea9add1202020-02-07 10:06:33 +0000198};
199
Finn Williamsfd271062019-12-04 14:27:27 +0000200class QSymmS8Decoder : public TypedIterator<const int8_t, Decoder<float>>
201{
202public:
203 QSymmS8Decoder(const int8_t* data, const float scale, const int32_t offset)
204 : TypedIterator(data), m_Scale(scale), m_Offset(offset) {}
205
206 QSymmS8Decoder(const float scale, const int32_t offset)
207 : QSymmS8Decoder(nullptr, scale, offset) {}
208
209 float Get() const override
210 {
211 return armnn::Dequantize(*m_Iterator, m_Scale, m_Offset);
212 }
Finn Williamsea8ce702020-09-29 19:54:00 +0100213 std::vector<float> DecodeTensor (const TensorShape& tensorShape,
214 const unsigned int channelMultiplier,
215 const bool isDepthwise) override
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100216 {
Finn Williamsea8ce702020-09-29 19:54:00 +0100217 IgnoreUnused(channelMultiplier, isDepthwise);
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100218
Finn Williamsea8ce702020-09-29 19:54:00 +0100219 const unsigned int size = tensorShape.GetNumElements();
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100220 std::vector<float> decodedTensor;
221 decodedTensor.reserve(size);
222
223 for (uint32_t i = 0; i < size; ++i)
224 {
225 this->operator[](i);
226 decodedTensor.emplace_back(armnn::Dequantize(*m_Iterator, m_Scale, m_Offset));
227 }
228
229 return decodedTensor;
230 }
231
Finn Williamsfd271062019-12-04 14:27:27 +0000232private:
233 const float m_Scale;
234 const int32_t m_Offset;
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100235
Finn Williamsfd271062019-12-04 14:27:27 +0000236};
237
Derek Lambertif30f7d32019-04-09 10:25:02 +0100238class QSymm16Decoder : public TypedIterator<const int16_t, Decoder<float>>
Sadik Armagan2999a022019-04-09 14:20:12 +0100239{
240public:
241 QSymm16Decoder(const int16_t* data, const float scale, const int32_t offset)
242 : TypedIterator(data), m_Scale(scale), m_Offset(offset) {}
243
Matthew Benthamc394a6d2019-06-24 12:51:25 +0100244 QSymm16Decoder(const float scale, const int32_t offset)
245 : QSymm16Decoder(nullptr, scale, offset) {}
246
Sadik Armagan2999a022019-04-09 14:20:12 +0100247 float Get() const override
248 {
249 return armnn::Dequantize(*m_Iterator, m_Scale, m_Offset);
250 }
Finn Williamsea8ce702020-09-29 19:54:00 +0100251 std::vector<float> DecodeTensor (const TensorShape& tensorShape,
252 const unsigned int channelMultiplier,
253 const bool isDepthwise) override
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100254 {
Finn Williamsea8ce702020-09-29 19:54:00 +0100255 IgnoreUnused(channelMultiplier, isDepthwise);
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100256
Finn Williamsea8ce702020-09-29 19:54:00 +0100257 const unsigned int size = tensorShape.GetNumElements();
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100258 std::vector<float> decodedTensor;
259 decodedTensor.reserve(size);
260
261 for (uint32_t i = 0; i < size; ++i)
262 {
263 this->operator[](i);
264 decodedTensor.emplace_back(armnn::Dequantize(*m_Iterator, m_Scale, m_Offset));
265 }
266
267 return decodedTensor;
268 }
269
Sadik Armagan2999a022019-04-09 14:20:12 +0100270private:
271 const float m_Scale;
272 const int32_t m_Offset;
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100273
Sadik Armagan2999a022019-04-09 14:20:12 +0100274};
275
Narumol Prangnawarat88325222020-03-06 14:45:57 +0000276class BFloat16Decoder : public TypedIterator<const BFloat16, Decoder<float>>
277{
278public:
279 BFloat16Decoder(const BFloat16* data)
280 : TypedIterator(data) {}
281
282 BFloat16Decoder()
283 : BFloat16Decoder(nullptr) {}
284
285 float Get() const override
286 {
287 float val = 0.f;
288 armnnUtils::FloatingPointConverter::ConvertBFloat16ToFloat32(m_Iterator, 1, &val);
289 return val;
290 }
Finn Williamsea8ce702020-09-29 19:54:00 +0100291 std::vector<float> DecodeTensor (const TensorShape& tensorShape,
292 const unsigned int channelMultiplier,
293 const bool isDepthwise) override
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100294 {
Finn Williamsea8ce702020-09-29 19:54:00 +0100295 IgnoreUnused(channelMultiplier, isDepthwise);
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 decodedTensor.reserve(size);
300
301 for (uint32_t i = 0; i < size; ++i)
302 {
303 this->operator[](i);
304
305 float val = 0.f;
306 armnnUtils::FloatingPointConverter::ConvertBFloat16ToFloat32(m_Iterator, 1, &val);
307 decodedTensor.emplace_back(val);
308 }
309
310 return decodedTensor;
311 }
312
Narumol Prangnawarat88325222020-03-06 14:45:57 +0000313};
314
Matthew Jacksone69c3992019-09-09 14:31:21 +0100315class Float16Decoder : public TypedIterator<const Half, Decoder<float>>
Sadik Armagan2e6dc3a2019-04-03 17:48:18 +0100316{
317public:
Matthew Jacksone69c3992019-09-09 14:31:21 +0100318 Float16Decoder(const Half* data)
Sadik Armagan2e6dc3a2019-04-03 17:48:18 +0100319 : TypedIterator(data) {}
320
Matthew Jacksone69c3992019-09-09 14:31:21 +0100321 Float16Decoder()
322 : Float16Decoder(nullptr) {}
323
324 float Get() const override
325 {
326 float val = 0.f;
327 armnnUtils::FloatingPointConverter::ConvertFloat16To32(m_Iterator, 1, &val);
328 return val;
329 }
Finn Williamsea8ce702020-09-29 19:54:00 +0100330 std::vector<float> DecodeTensor (const TensorShape& tensorShape,
331 const unsigned int channelMultiplier,
332 const bool isDepthwise) override
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100333 {
Finn Williamsea8ce702020-09-29 19:54:00 +0100334 IgnoreUnused(channelMultiplier, isDepthwise);
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100335
Finn Williamsea8ce702020-09-29 19:54:00 +0100336 const unsigned int size = tensorShape.GetNumElements();
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100337 std::vector<float> decodedTensor;
338 decodedTensor.reserve(size);
339
340 for (uint32_t i = 0; i < size; ++i)
341 {
342 float val = 0.f;
343 this->operator[](i);
344 armnnUtils::FloatingPointConverter::ConvertFloat16To32(m_Iterator, 1, &val);
345 decodedTensor.emplace_back(val);
346 }
347
348 return decodedTensor;
349 }
350
351
Matthew Jacksone69c3992019-09-09 14:31:21 +0100352};
353
354class Float32Decoder : public TypedIterator<const float, Decoder<float>>
355{
356public:
357 Float32Decoder(const float* data)
358 : TypedIterator(data) {}
359
360 Float32Decoder()
361 : Float32Decoder(nullptr) {}
Matthew Benthamc394a6d2019-06-24 12:51:25 +0100362
Derek Lambertif30f7d32019-04-09 10:25:02 +0100363 float Get() const override
Sadik Armagan2e6dc3a2019-04-03 17:48:18 +0100364 {
Derek Lambertif30f7d32019-04-09 10:25:02 +0100365 return *m_Iterator;
Sadik Armagan2e6dc3a2019-04-03 17:48:18 +0100366 }
Finn Williamsea8ce702020-09-29 19:54:00 +0100367 std::vector<float> DecodeTensor (const TensorShape& tensorShape,
368 const unsigned int channelMultiplier,
369 const bool isDepthwise) override
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100370 {
Finn Williamsea8ce702020-09-29 19:54:00 +0100371 IgnoreUnused(channelMultiplier, isDepthwise);
372 const unsigned int size = tensorShape.GetNumElements();
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100373 std::vector<float> decodedTensor;
374
375 decodedTensor.reserve(size);
376 decodedTensor.assign(m_Start, m_Start + size);
377
378 return decodedTensor;
379 }
Sadik Armagan2e6dc3a2019-04-03 17:48:18 +0100380};
381
Mike Kelly9b398322019-05-22 17:21:49 +0100382class ScaledInt32Decoder : public TypedIterator<const int32_t, Decoder<float>>
383{
384public:
385 ScaledInt32Decoder(const int32_t* data, const float scale)
386 : TypedIterator(data), m_Scale(scale) {}
387
Matthew Benthamc394a6d2019-06-24 12:51:25 +0100388 ScaledInt32Decoder(const float scale)
389 : ScaledInt32Decoder(nullptr, scale) {}
390
Mike Kelly9b398322019-05-22 17:21:49 +0100391 float Get() const override
392 {
393 return static_cast<float>(*m_Iterator) * m_Scale;
394 }
Finn Williamsea8ce702020-09-29 19:54:00 +0100395 std::vector<float> DecodeTensor (const TensorShape& tensorShape,
396 const unsigned int channelMultiplier,
397 const bool isDepthwise) override
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100398 {
Finn Williamsea8ce702020-09-29 19:54:00 +0100399 IgnoreUnused(channelMultiplier, isDepthwise);
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100400
Finn Williamsea8ce702020-09-29 19:54:00 +0100401 const unsigned int size = tensorShape.GetNumElements();
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100402 std::vector<float> decodedTensor;
403 decodedTensor.reserve(size);
404
405 for (uint32_t i = 0; i < size; ++i)
406 {
407 this->operator[](i);
408 decodedTensor.emplace_back(static_cast<float>(*m_Iterator) * m_Scale);
409 }
410
411 return decodedTensor;
412 }
413
Mike Kelly9b398322019-05-22 17:21:49 +0100414private:
415 const float m_Scale;
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100416
Mike Kelly9b398322019-05-22 17:21:49 +0100417};
418
Aron Virginas-Tar198ee402019-08-02 18:54:28 +0100419class Int32Decoder : public TypedIterator<const int32_t, Decoder<float>>
420{
421public:
422 Int32Decoder(const int32_t* data)
423 : TypedIterator(data) {}
424
425 Int32Decoder()
426 : Int32Decoder(nullptr) {}
427
428 float Get() const override
429 {
430 return static_cast<float>(*m_Iterator);
431 }
Finn Williamsea8ce702020-09-29 19:54:00 +0100432 std::vector<float> DecodeTensor (const TensorShape& tensorShape,
433 const unsigned int channelMultiplier,
434 const bool isDepthwise) override
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100435 {
Finn Williamsea8ce702020-09-29 19:54:00 +0100436 IgnoreUnused(channelMultiplier, isDepthwise);
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100437
Finn Williamsea8ce702020-09-29 19:54:00 +0100438 const unsigned int size = tensorShape.GetNumElements();
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100439 std::vector<float> decodedTensor;
440 decodedTensor.reserve(size);
441
442 for (uint32_t i = 0; i < size; ++i)
443 {
444 this->operator[](i);
445 decodedTensor.emplace_back(static_cast<float>(*m_Iterator));
446 }
447
448 return decodedTensor;
449 }
Aron Virginas-Tar198ee402019-08-02 18:54:28 +0100450};
451
Finn Williamscbd2c232020-06-22 15:58:32 +0100452class Int32ToInt32tDecoder : public TypedIterator<const int32_t, Decoder<int32_t>>
453{
454public:
455 Int32ToInt32tDecoder(const int32_t* data)
456 : TypedIterator(data){}
457
458 Int32ToInt32tDecoder()
459 : Int32ToInt32tDecoder(nullptr) {}
460
461 int32_t Get() const override
462 {
463 return *m_Iterator;
464 }
Finn Williamsea8ce702020-09-29 19:54:00 +0100465 std::vector<float> DecodeTensor (const TensorShape& tensorShape,
466 const unsigned int channelMultiplier,
467 const bool isDepthwise) override
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100468 {
Finn Williamsea8ce702020-09-29 19:54:00 +0100469 IgnoreUnused(channelMultiplier, isDepthwise);
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100470
Finn Williamsea8ce702020-09-29 19:54:00 +0100471 const unsigned int size = tensorShape.GetNumElements();
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100472 std::vector<float> decodedTensor;
473 decodedTensor.reserve(size);
474
475 for (uint32_t i = 0; i < size; ++i)
476 {
477 this->operator[](i);
478 decodedTensor.emplace_back(*m_Iterator);
479 }
480
481 return decodedTensor;
482 }
Finn Williamscbd2c232020-06-22 15:58:32 +0100483};
484
Sadik Armaganb60dd242020-03-19 13:53:16 +0000485class BooleanDecoder : public TypedIterator<const uint8_t, Decoder<float>>
486{
487public:
488 BooleanDecoder(const uint8_t* data)
489 : TypedIterator(data) {}
490
491 BooleanDecoder()
492 : BooleanDecoder(nullptr) {}
493
494 float Get() const override
495 {
496 return *m_Iterator;
497 }
Finn Williamsea8ce702020-09-29 19:54:00 +0100498 std::vector<float> DecodeTensor (const TensorShape& tensorShape,
499 const unsigned int channelMultiplier,
500 const bool isDepthwise) override
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100501 {
Finn Williamsea8ce702020-09-29 19:54:00 +0100502 IgnoreUnused(channelMultiplier, isDepthwise);
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100503
Finn Williamsea8ce702020-09-29 19:54:00 +0100504 const unsigned int size = tensorShape.GetNumElements();
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100505 std::vector<float> decodedTensor;
506 decodedTensor.reserve(size);
507
508 for (uint32_t i = 0; i < size; ++i)
509 {
510 this->operator[](i);
511 decodedTensor.emplace_back(*m_Iterator);
512 }
513
514 return decodedTensor;
515 }
Sadik Armaganb60dd242020-03-19 13:53:16 +0000516};
517
Derek Lambertif30f7d32019-04-09 10:25:02 +0100518class QASymm8Encoder : public TypedIterator<uint8_t, Encoder<float>>
Sadik Armagan2e6dc3a2019-04-03 17:48:18 +0100519{
520public:
521 QASymm8Encoder(uint8_t* data, const float scale, const int32_t offset)
522 : TypedIterator(data), m_Scale(scale), m_Offset(offset) {}
523
Matthew Benthamc394a6d2019-06-24 12:51:25 +0100524 QASymm8Encoder(const float scale, const int32_t offset)
525 : QASymm8Encoder(nullptr, scale, offset) {}
526
Derek Lambertif30f7d32019-04-09 10:25:02 +0100527 void Set(float right) override
Sadik Armagan2e6dc3a2019-04-03 17:48:18 +0100528 {
529 *m_Iterator = armnn::Quantize<uint8_t>(right, m_Scale, m_Offset);
530 }
531
Nattapat Chaimanowongeb2b3292019-05-07 12:02:30 +0100532 float Get() const override
533 {
534 return armnn::Dequantize(*m_Iterator, m_Scale, m_Offset);
535 }
536
Sadik Armagan2e6dc3a2019-04-03 17:48:18 +0100537private:
538 const float m_Scale;
539 const int32_t m_Offset;
540};
541
Ryan OShea9add1202020-02-07 10:06:33 +0000542class QASymmS8Encoder : public TypedIterator<int8_t, Encoder<float>>
543{
544public:
545 QASymmS8Encoder(int8_t* data, const float scale, const int32_t offset)
546 : TypedIterator(data), m_Scale(scale), m_Offset(offset) {}
547
548 QASymmS8Encoder(const float scale, const int32_t offset)
549 : QASymmS8Encoder(nullptr, scale, offset) {}
550
551 void Set(float right) override
552 {
553 *m_Iterator = armnn::Quantize<int8_t>(right, m_Scale, m_Offset);
554 }
555
556 float Get() const override
557 {
558 return armnn::Dequantize(*m_Iterator, m_Scale, m_Offset);
559 }
560
561private:
562 const float m_Scale;
563 const int32_t m_Offset;
564};
565
Finn Williamsfd271062019-12-04 14:27:27 +0000566class QSymmS8Encoder : public TypedIterator<int8_t, Encoder<float>>
567{
568public:
569 QSymmS8Encoder(int8_t* data, const float scale, const int32_t offset)
570 : TypedIterator(data), m_Scale(scale), m_Offset(offset) {}
571
572 QSymmS8Encoder(const float scale, const int32_t offset)
573 : QSymmS8Encoder(nullptr, scale, offset) {}
574
575 void Set(float right) override
576 {
577 *m_Iterator = armnn::Quantize<int8_t>(right, m_Scale, m_Offset);
578 }
579
580 float Get() const override
581 {
582 return armnn::Dequantize(*m_Iterator, m_Scale, m_Offset);
583 }
584
585private:
586 const float m_Scale;
587 const int32_t m_Offset;
588};
589
Derek Lambertif30f7d32019-04-09 10:25:02 +0100590class QSymm16Encoder : public TypedIterator<int16_t, Encoder<float>>
591{
592public:
593 QSymm16Encoder(int16_t* data, const float scale, const int32_t offset)
594 : TypedIterator(data), m_Scale(scale), m_Offset(offset) {}
595
Matthew Benthamc394a6d2019-06-24 12:51:25 +0100596 QSymm16Encoder(const float scale, const int32_t offset)
597 : QSymm16Encoder(nullptr, scale, offset) {}
598
Derek Lambertif30f7d32019-04-09 10:25:02 +0100599 void Set(float right) override
600 {
601 *m_Iterator = armnn::Quantize<int16_t>(right, m_Scale, m_Offset);
602 }
603
Nattapat Chaimanowongeb2b3292019-05-07 12:02:30 +0100604 float Get() const override
605 {
606 return armnn::Dequantize(*m_Iterator, m_Scale, m_Offset);
607 }
608
Derek Lambertif30f7d32019-04-09 10:25:02 +0100609private:
610 const float m_Scale;
611 const int32_t m_Offset;
612};
613
Narumol Prangnawarat88325222020-03-06 14:45:57 +0000614class BFloat16Encoder : public TypedIterator<armnn::BFloat16, Encoder<float>>
615{
616public:
617 BFloat16Encoder(armnn::BFloat16* data)
618 : TypedIterator(data) {}
619
620 BFloat16Encoder()
621 : BFloat16Encoder(nullptr) {}
622
623 void Set(float right) override
624 {
625 armnnUtils::FloatingPointConverter::ConvertFloat32ToBFloat16(&right, 1, m_Iterator);
626 }
627
628 float Get() const override
629 {
630 float val = 0.f;
631 armnnUtils::FloatingPointConverter::ConvertBFloat16ToFloat32(m_Iterator, 1, &val);
632 return val;
633 }
634};
635
Matthew Jacksone69c3992019-09-09 14:31:21 +0100636class Float16Encoder : public TypedIterator<Half, Encoder<float>>
Derek Lambertif30f7d32019-04-09 10:25:02 +0100637{
638public:
Matthew Jacksone69c3992019-09-09 14:31:21 +0100639 Float16Encoder(Half* data)
Derek Lambertif30f7d32019-04-09 10:25:02 +0100640 : TypedIterator(data) {}
641
Matthew Jacksone69c3992019-09-09 14:31:21 +0100642 Float16Encoder()
643 : Float16Encoder(nullptr) {}
644
645 void Set(float right) override
646 {
647 armnnUtils::FloatingPointConverter::ConvertFloat32To16(&right, 1, m_Iterator);
648 }
649
650 float Get() const override
651 {
652 float val = 0.f;
653 armnnUtils::FloatingPointConverter::ConvertFloat16To32(m_Iterator, 1, &val);
654 return val;
655 }
656};
657
658class Float32Encoder : public TypedIterator<float, Encoder<float>>
659{
660public:
661 Float32Encoder(float* data)
662 : TypedIterator(data) {}
663
664 Float32Encoder()
665 : Float32Encoder(nullptr) {}
Matthew Benthamc394a6d2019-06-24 12:51:25 +0100666
Derek Lambertif30f7d32019-04-09 10:25:02 +0100667 void Set(float right) override
668 {
669 *m_Iterator = right;
670 }
Nattapat Chaimanowongeb2b3292019-05-07 12:02:30 +0100671
672 float Get() const override
673 {
674 return *m_Iterator;
675 }
Derek Lambertif30f7d32019-04-09 10:25:02 +0100676};
677
Aron Virginas-Tar198ee402019-08-02 18:54:28 +0100678class Int32Encoder : public TypedIterator<int32_t, Encoder<float>>
679{
680public:
681 Int32Encoder(int32_t* data)
682 : TypedIterator(data) {}
683
684 Int32Encoder()
685 : Int32Encoder(nullptr) {}
686
687 void Set(float right) override
688 {
689 *m_Iterator = static_cast<int32_t>(right);
690 }
691
692 float Get() const override
693 {
694 return static_cast<float>(*m_Iterator);
695 }
696};
697
Finn Williamscbd2c232020-06-22 15:58:32 +0100698class Int32ToInt32tEncoder : public TypedIterator<int32_t, Encoder<int32_t>>
699{
700public:
701 Int32ToInt32tEncoder(int32_t* data)
702 : TypedIterator(data){}
703
704 Int32ToInt32tEncoder()
705 : Int32ToInt32tEncoder(nullptr) {}
706
707 void Set(int32_t right) override
708 {
709 *m_Iterator = right;
710 }
711
712 int32_t Get() const override
713 {
714 return *m_Iterator;
715 }
716};
717
Derek Lambertif30f7d32019-04-09 10:25:02 +0100718class BooleanEncoder : public TypedIterator<uint8_t, Encoder<bool>>
Sadik Armagan2e6dc3a2019-04-03 17:48:18 +0100719{
720public:
721 BooleanEncoder(uint8_t* data)
722 : TypedIterator(data) {}
723
Matthew Benthamc394a6d2019-06-24 12:51:25 +0100724 BooleanEncoder()
725 : BooleanEncoder(nullptr) {}
726
Sadik Armagan2e6dc3a2019-04-03 17:48:18 +0100727 void Set(bool right) override
728 {
729 *m_Iterator = right;
730 }
Nattapat Chaimanowongeb2b3292019-05-07 12:02:30 +0100731
732 bool Get() const override
733 {
734 return *m_Iterator;
735 }
Sadik Armagan2e6dc3a2019-04-03 17:48:18 +0100736};
737
Keith Davis5236e1d2019-11-04 08:58:33 +0000738// PerAxisIterator for per-axis quantization
739template<typename T, typename Base>
740class PerAxisIterator : public Base
741{
742public:
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100743 // axisFactor is used to calculate channelStep
Keith Davis5236e1d2019-11-04 08:58:33 +0000744 PerAxisIterator(T* data = nullptr, unsigned int axisFactor = 0)
745 : m_Iterator(data), m_Start(data), m_AxisIndex(0), m_AxisFactor(axisFactor)
746 {}
747
748 // This should be called to set index for per-axis Encoder/Decoder
Aron Virginas-Tar5edc8812019-11-05 18:00:21 +0000749 PerAxisIterator& SetIndex(unsigned int index, unsigned int axisIndex) override
Keith Davis5236e1d2019-11-04 08:58:33 +0000750 {
Narumol Prangnawaratac2770a2020-04-01 16:51:23 +0100751 ARMNN_ASSERT(m_Iterator);
Keith Davis5236e1d2019-11-04 08:58:33 +0000752 m_Iterator = m_Start + index;
753 m_AxisIndex = axisIndex;
754 return *this;
755 }
756
757 void Reset(void* data) override
758 {
759 m_Iterator = reinterpret_cast<T*>(data);
760 m_Start = m_Iterator;
761 m_AxisIndex = 0;
762 }
763
764 PerAxisIterator& operator++() override
765 {
Narumol Prangnawaratac2770a2020-04-01 16:51:23 +0100766 ARMNN_ASSERT(m_Iterator);
Keith Davis5236e1d2019-11-04 08:58:33 +0000767 ++m_Iterator;
768 m_AxisIndex = static_cast<unsigned int>(*m_Iterator) % m_AxisFactor;
769 return *this;
770 }
771
772 PerAxisIterator& operator+=(const unsigned int increment) override
773 {
Narumol Prangnawaratac2770a2020-04-01 16:51:23 +0100774 ARMNN_ASSERT(m_Iterator);
Keith Davis5236e1d2019-11-04 08:58:33 +0000775 m_Iterator += increment;
776 m_AxisIndex = static_cast<unsigned int>(*m_Iterator) % m_AxisFactor;
777 return *this;
778 }
779
780 PerAxisIterator& operator-=(const unsigned int decrement) override
781 {
Narumol Prangnawaratac2770a2020-04-01 16:51:23 +0100782 ARMNN_ASSERT(m_Iterator);
Keith Davis5236e1d2019-11-04 08:58:33 +0000783 m_Iterator -= decrement;
784 m_AxisIndex = static_cast<unsigned int>(*m_Iterator) % m_AxisFactor;
785 return *this;
786 }
787
788 PerAxisIterator& operator[](const unsigned int index) override
789 {
Narumol Prangnawaratac2770a2020-04-01 16:51:23 +0100790 ARMNN_ASSERT(m_Iterator);
Keith Davis5236e1d2019-11-04 08:58:33 +0000791 m_Iterator = m_Start + index;
792 m_AxisIndex = static_cast<unsigned int>(*m_Iterator) % m_AxisFactor;
793 return *this;
794 }
795
796 protected:
797 T* m_Iterator;
798 T* m_Start;
799 unsigned int m_AxisIndex;
800 unsigned int m_AxisFactor;
801};
802
803class QSymm8PerAxisDecoder : public PerAxisIterator<const int8_t, Decoder<float>>
804{
805public:
806 QSymm8PerAxisDecoder(const int8_t* data, const std::vector<float>& scale, unsigned int axisFactor)
Finn Williamsea8ce702020-09-29 19:54:00 +0100807 : PerAxisIterator(data, axisFactor), m_Scales(scale) {}
Keith Davis5236e1d2019-11-04 08:58:33 +0000808
809 float Get() const override
810 {
Finn Williamsea8ce702020-09-29 19:54:00 +0100811 return armnn::Dequantize(*m_Iterator, m_Scales[m_AxisIndex], 0);
Keith Davis5236e1d2019-11-04 08:58:33 +0000812 }
813
814 // Get scale of the current value
815 float GetScale() const
816 {
Finn Williamsea8ce702020-09-29 19:54:00 +0100817 return m_Scales[m_AxisIndex];
Keith Davis5236e1d2019-11-04 08:58:33 +0000818 }
819
Finn Williamsea8ce702020-09-29 19:54:00 +0100820 std::vector<float> DecodeTensor(const TensorShape &tensorShape,
821 const unsigned int channelMultiplier,
822 bool isDepthwise) override
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100823 {
Finn Williamsea8ce702020-09-29 19:54:00 +0100824 const uint32_t size = tensorShape.GetNumElements();
825 const uint32_t scaleSize = static_cast<uint32_t>(m_Scales.size());
826
827 const uint32_t stepSize = isDepthwise ?
828 tensorShape[2] * tensorShape[3] : tensorShape.GetNumElements() / tensorShape[0];
829
830 const uint32_t stepNum = size / (stepSize * channelMultiplier);
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100831 uint32_t scale;
832
833 std::vector<float> decodedTensor;
834 decodedTensor.reserve(size);
835
Finn Williamsea8ce702020-09-29 19:54:00 +0100836 // channelMultiplier is only used in depthwise convolutions and in other cases will have no effect
837 // stepSize is the length of a contiguous area sharing a quantization scale within a tensor
838 // stepNum is the number of those steps/blocks in the tensor
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100839 for (uint32_t mult = 0; mult < channelMultiplier; ++mult)
840 {
Finn Williamsea8ce702020-09-29 19:54:00 +0100841 for (uint32_t step = 0; step < stepNum; ++step)
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100842 {
Finn Williamsea8ce702020-09-29 19:54:00 +0100843 scale = (channelMultiplier * step + mult) % scaleSize;
844 for (uint32_t i = 0; i < stepSize; ++i)
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100845 {
Finn Williamsea8ce702020-09-29 19:54:00 +0100846 unsigned int index = mult * stepSize * channelMultiplier +
847 step * stepSize + i;
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100848 this->operator[](index);
Finn Williamsea8ce702020-09-29 19:54:00 +0100849 decodedTensor.emplace_back(armnn::Dequantize(*m_Iterator, m_Scales[scale], 0));
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100850 }
851 }
852 }
853 return decodedTensor;
854 }
855
Keith Davis5236e1d2019-11-04 08:58:33 +0000856private:
Finn Williamsea8ce702020-09-29 19:54:00 +0100857 std::vector<float> m_Scales;
Keith Davis5236e1d2019-11-04 08:58:33 +0000858};
859
860class QSymm8PerAxisEncoder : public PerAxisIterator<int8_t, Encoder<float>>
861{
862public:
863 QSymm8PerAxisEncoder(int8_t* data, const std::vector<float>& scale, unsigned int axisFactor)
864 : PerAxisIterator(data, axisFactor), m_Scale(scale) {}
865
866 void Set(float right)
867 {
868 *m_Iterator = armnn::Quantize<int8_t>(right, m_Scale[m_AxisIndex], 0);
869 }
870
871 float Get() const
872 {
873 return armnn::Dequantize(*m_Iterator, m_Scale[m_AxisIndex], 0);
874 }
875
876 // Get scale of the current value
877 float GetScale() const
878 {
879 return m_Scale[m_AxisIndex];
880 }
881
882private:
883 std::vector<float> m_Scale;
884};
885
Aron Virginas-Tarb67f9572019-11-04 15:00:19 +0000886class ScaledInt32PerAxisDecoder : public PerAxisIterator<const int32_t, Decoder<float>>
887{
888public:
889 ScaledInt32PerAxisDecoder(const int32_t* data, const std::vector<float>& scales, unsigned int axisFactor)
890 : PerAxisIterator(data, axisFactor), m_Scales(scales) {}
891
892 float Get() const override
893 {
894 return armnn::Dequantize(*m_Iterator, m_Scales[m_AxisIndex], 0);
895 }
896
897 // Get scale of the current value
898 float GetScale() const
899 {
900 return m_Scales[m_AxisIndex];
901 }
902
Finn Williamsea8ce702020-09-29 19:54:00 +0100903 std::vector<float> DecodeTensor(const TensorShape &tensorShape,
904 const unsigned int channelMultiplier,
905 bool isDepthwise) override
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100906 {
Finn Williamsea8ce702020-09-29 19:54:00 +0100907 const uint32_t size = tensorShape.GetNumElements();
908 const uint32_t scaleSize = static_cast<uint32_t>(m_Scales.size());
909
910 const uint32_t stepSize = isDepthwise ?
911 tensorShape[2] * tensorShape[3] : tensorShape.GetNumElements() / tensorShape[0];
912
913 const uint32_t stepNum = size / (stepSize * channelMultiplier);
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100914 uint32_t scale;
915
916 std::vector<float> decodedTensor;
917 decodedTensor.reserve(size);
918
Finn Williamsea8ce702020-09-29 19:54:00 +0100919 // channelMultiplier is only used in depthwise convolutions and in other cases will have no effect
920 // stepSize is the length of a contiguous area sharing a quantization scale within a tensor
921 // stepNum is the number of those steps/blocks in the tensor
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100922 for (uint32_t mult = 0; mult < channelMultiplier; ++mult)
923 {
Finn Williamsea8ce702020-09-29 19:54:00 +0100924 for (uint32_t step = 0; step < stepNum; ++step)
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100925 {
Finn Williamsea8ce702020-09-29 19:54:00 +0100926 scale = (channelMultiplier * step + mult) % scaleSize;
927 for (uint32_t i = 0; i < stepSize; ++i)
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100928 {
Finn Williamsea8ce702020-09-29 19:54:00 +0100929 unsigned int index = mult * stepSize * channelMultiplier +
930 step * stepSize + i;
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100931 this->operator[](index);
932 decodedTensor.emplace_back(armnn::Dequantize(*m_Iterator, m_Scales[scale], 0));
933 }
934 }
935 }
936 return decodedTensor;
937 }
938
Aron Virginas-Tarb67f9572019-11-04 15:00:19 +0000939private:
940 std::vector<float> m_Scales;
941};
942
943} // namespace armnn