blob: 73e24691d98a7825cdc46ffb4b27094b7b95bc9c [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
James Conroyaba90cd2020-11-06 16:28:18 +0000518class BooleanDecoderBool : public TypedIterator<const uint8_t, Decoder<bool>>
519{
520public:
521 BooleanDecoderBool(const uint8_t* data)
522 : TypedIterator(data) {}
523
524 BooleanDecoderBool()
525 : BooleanDecoderBool(nullptr) {}
526
527 bool Get() const override
528 {
529 return *m_Iterator;
530 }
531
532 std::vector<float> DecodeTensor(const TensorShape& tensorShape,
533 const unsigned int channelMultiplier,
534 const bool isDepthwise) override
535 {
536 IgnoreUnused(channelMultiplier, isDepthwise);
537
538 const unsigned int size = tensorShape.GetNumElements();
539 std::vector<float> decodedTensor;
540 decodedTensor.reserve(size);
541
542 for (uint32_t i = 0; i < size; ++i)
543 {
544 this->operator[](i);
545 decodedTensor.emplace_back(*m_Iterator);
546 }
547
548 return decodedTensor;
549 }
550};
551
Derek Lambertif30f7d32019-04-09 10:25:02 +0100552class QASymm8Encoder : public TypedIterator<uint8_t, Encoder<float>>
Sadik Armagan2e6dc3a2019-04-03 17:48:18 +0100553{
554public:
555 QASymm8Encoder(uint8_t* data, const float scale, const int32_t offset)
556 : TypedIterator(data), m_Scale(scale), m_Offset(offset) {}
557
Matthew Benthamc394a6d2019-06-24 12:51:25 +0100558 QASymm8Encoder(const float scale, const int32_t offset)
559 : QASymm8Encoder(nullptr, scale, offset) {}
560
Derek Lambertif30f7d32019-04-09 10:25:02 +0100561 void Set(float right) override
Sadik Armagan2e6dc3a2019-04-03 17:48:18 +0100562 {
563 *m_Iterator = armnn::Quantize<uint8_t>(right, m_Scale, m_Offset);
564 }
565
Nattapat Chaimanowongeb2b3292019-05-07 12:02:30 +0100566 float Get() const override
567 {
568 return armnn::Dequantize(*m_Iterator, m_Scale, m_Offset);
569 }
570
Sadik Armagan2e6dc3a2019-04-03 17:48:18 +0100571private:
572 const float m_Scale;
573 const int32_t m_Offset;
574};
575
Ryan OShea9add1202020-02-07 10:06:33 +0000576class QASymmS8Encoder : public TypedIterator<int8_t, Encoder<float>>
577{
578public:
579 QASymmS8Encoder(int8_t* data, const float scale, const int32_t offset)
580 : TypedIterator(data), m_Scale(scale), m_Offset(offset) {}
581
582 QASymmS8Encoder(const float scale, const int32_t offset)
583 : QASymmS8Encoder(nullptr, scale, offset) {}
584
585 void Set(float right) override
586 {
587 *m_Iterator = armnn::Quantize<int8_t>(right, m_Scale, m_Offset);
588 }
589
590 float Get() const override
591 {
592 return armnn::Dequantize(*m_Iterator, m_Scale, m_Offset);
593 }
594
595private:
596 const float m_Scale;
597 const int32_t m_Offset;
598};
599
Finn Williamsfd271062019-12-04 14:27:27 +0000600class QSymmS8Encoder : public TypedIterator<int8_t, Encoder<float>>
601{
602public:
603 QSymmS8Encoder(int8_t* data, const float scale, const int32_t offset)
604 : TypedIterator(data), m_Scale(scale), m_Offset(offset) {}
605
606 QSymmS8Encoder(const float scale, const int32_t offset)
607 : QSymmS8Encoder(nullptr, scale, offset) {}
608
609 void Set(float right) override
610 {
611 *m_Iterator = armnn::Quantize<int8_t>(right, m_Scale, m_Offset);
612 }
613
614 float Get() const override
615 {
616 return armnn::Dequantize(*m_Iterator, m_Scale, m_Offset);
617 }
618
619private:
620 const float m_Scale;
621 const int32_t m_Offset;
622};
623
Derek Lambertif30f7d32019-04-09 10:25:02 +0100624class QSymm16Encoder : public TypedIterator<int16_t, Encoder<float>>
625{
626public:
627 QSymm16Encoder(int16_t* data, const float scale, const int32_t offset)
628 : TypedIterator(data), m_Scale(scale), m_Offset(offset) {}
629
Matthew Benthamc394a6d2019-06-24 12:51:25 +0100630 QSymm16Encoder(const float scale, const int32_t offset)
631 : QSymm16Encoder(nullptr, scale, offset) {}
632
Derek Lambertif30f7d32019-04-09 10:25:02 +0100633 void Set(float right) override
634 {
635 *m_Iterator = armnn::Quantize<int16_t>(right, m_Scale, m_Offset);
636 }
637
Nattapat Chaimanowongeb2b3292019-05-07 12:02:30 +0100638 float Get() const override
639 {
640 return armnn::Dequantize(*m_Iterator, m_Scale, m_Offset);
641 }
642
Derek Lambertif30f7d32019-04-09 10:25:02 +0100643private:
644 const float m_Scale;
645 const int32_t m_Offset;
646};
647
Narumol Prangnawarat88325222020-03-06 14:45:57 +0000648class BFloat16Encoder : public TypedIterator<armnn::BFloat16, Encoder<float>>
649{
650public:
651 BFloat16Encoder(armnn::BFloat16* data)
652 : TypedIterator(data) {}
653
654 BFloat16Encoder()
655 : BFloat16Encoder(nullptr) {}
656
657 void Set(float right) override
658 {
659 armnnUtils::FloatingPointConverter::ConvertFloat32ToBFloat16(&right, 1, m_Iterator);
660 }
661
662 float Get() const override
663 {
664 float val = 0.f;
665 armnnUtils::FloatingPointConverter::ConvertBFloat16ToFloat32(m_Iterator, 1, &val);
666 return val;
667 }
668};
669
Matthew Jacksone69c3992019-09-09 14:31:21 +0100670class Float16Encoder : public TypedIterator<Half, Encoder<float>>
Derek Lambertif30f7d32019-04-09 10:25:02 +0100671{
672public:
Matthew Jacksone69c3992019-09-09 14:31:21 +0100673 Float16Encoder(Half* data)
Derek Lambertif30f7d32019-04-09 10:25:02 +0100674 : TypedIterator(data) {}
675
Matthew Jacksone69c3992019-09-09 14:31:21 +0100676 Float16Encoder()
677 : Float16Encoder(nullptr) {}
678
679 void Set(float right) override
680 {
681 armnnUtils::FloatingPointConverter::ConvertFloat32To16(&right, 1, m_Iterator);
682 }
683
684 float Get() const override
685 {
686 float val = 0.f;
687 armnnUtils::FloatingPointConverter::ConvertFloat16To32(m_Iterator, 1, &val);
688 return val;
689 }
690};
691
692class Float32Encoder : public TypedIterator<float, Encoder<float>>
693{
694public:
695 Float32Encoder(float* data)
696 : TypedIterator(data) {}
697
698 Float32Encoder()
699 : Float32Encoder(nullptr) {}
Matthew Benthamc394a6d2019-06-24 12:51:25 +0100700
Derek Lambertif30f7d32019-04-09 10:25:02 +0100701 void Set(float right) override
702 {
703 *m_Iterator = right;
704 }
Nattapat Chaimanowongeb2b3292019-05-07 12:02:30 +0100705
706 float Get() const override
707 {
708 return *m_Iterator;
709 }
Derek Lambertif30f7d32019-04-09 10:25:02 +0100710};
711
Aron Virginas-Tar198ee402019-08-02 18:54:28 +0100712class Int32Encoder : public TypedIterator<int32_t, Encoder<float>>
713{
714public:
715 Int32Encoder(int32_t* data)
716 : TypedIterator(data) {}
717
718 Int32Encoder()
719 : Int32Encoder(nullptr) {}
720
721 void Set(float right) override
722 {
723 *m_Iterator = static_cast<int32_t>(right);
724 }
725
726 float Get() const override
727 {
728 return static_cast<float>(*m_Iterator);
729 }
730};
731
Finn Williamscbd2c232020-06-22 15:58:32 +0100732class Int32ToInt32tEncoder : public TypedIterator<int32_t, Encoder<int32_t>>
733{
734public:
735 Int32ToInt32tEncoder(int32_t* data)
736 : TypedIterator(data){}
737
738 Int32ToInt32tEncoder()
739 : Int32ToInt32tEncoder(nullptr) {}
740
741 void Set(int32_t right) override
742 {
743 *m_Iterator = right;
744 }
745
746 int32_t Get() const override
747 {
748 return *m_Iterator;
749 }
750};
751
Derek Lambertif30f7d32019-04-09 10:25:02 +0100752class BooleanEncoder : public TypedIterator<uint8_t, Encoder<bool>>
Sadik Armagan2e6dc3a2019-04-03 17:48:18 +0100753{
754public:
755 BooleanEncoder(uint8_t* data)
756 : TypedIterator(data) {}
757
Matthew Benthamc394a6d2019-06-24 12:51:25 +0100758 BooleanEncoder()
759 : BooleanEncoder(nullptr) {}
760
Sadik Armagan2e6dc3a2019-04-03 17:48:18 +0100761 void Set(bool right) override
762 {
763 *m_Iterator = right;
764 }
Nattapat Chaimanowongeb2b3292019-05-07 12:02:30 +0100765
766 bool Get() const override
767 {
768 return *m_Iterator;
769 }
Sadik Armagan2e6dc3a2019-04-03 17:48:18 +0100770};
771
Keith Davis5236e1d2019-11-04 08:58:33 +0000772// PerAxisIterator for per-axis quantization
773template<typename T, typename Base>
774class PerAxisIterator : public Base
775{
776public:
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100777 // axisFactor is used to calculate channelStep
Keith Davis5236e1d2019-11-04 08:58:33 +0000778 PerAxisIterator(T* data = nullptr, unsigned int axisFactor = 0)
779 : m_Iterator(data), m_Start(data), m_AxisIndex(0), m_AxisFactor(axisFactor)
780 {}
781
782 // This should be called to set index for per-axis Encoder/Decoder
Aron Virginas-Tar5edc8812019-11-05 18:00:21 +0000783 PerAxisIterator& SetIndex(unsigned int index, unsigned int axisIndex) override
Keith Davis5236e1d2019-11-04 08:58:33 +0000784 {
Narumol Prangnawaratac2770a2020-04-01 16:51:23 +0100785 ARMNN_ASSERT(m_Iterator);
Keith Davis5236e1d2019-11-04 08:58:33 +0000786 m_Iterator = m_Start + index;
787 m_AxisIndex = axisIndex;
788 return *this;
789 }
790
791 void Reset(void* data) override
792 {
793 m_Iterator = reinterpret_cast<T*>(data);
794 m_Start = m_Iterator;
795 m_AxisIndex = 0;
796 }
797
798 PerAxisIterator& operator++() override
799 {
Narumol Prangnawaratac2770a2020-04-01 16:51:23 +0100800 ARMNN_ASSERT(m_Iterator);
Keith Davis5236e1d2019-11-04 08:58:33 +0000801 ++m_Iterator;
802 m_AxisIndex = static_cast<unsigned int>(*m_Iterator) % m_AxisFactor;
803 return *this;
804 }
805
806 PerAxisIterator& operator+=(const unsigned int increment) override
807 {
Narumol Prangnawaratac2770a2020-04-01 16:51:23 +0100808 ARMNN_ASSERT(m_Iterator);
Keith Davis5236e1d2019-11-04 08:58:33 +0000809 m_Iterator += increment;
810 m_AxisIndex = static_cast<unsigned int>(*m_Iterator) % m_AxisFactor;
811 return *this;
812 }
813
814 PerAxisIterator& operator-=(const unsigned int decrement) override
815 {
Narumol Prangnawaratac2770a2020-04-01 16:51:23 +0100816 ARMNN_ASSERT(m_Iterator);
Keith Davis5236e1d2019-11-04 08:58:33 +0000817 m_Iterator -= decrement;
818 m_AxisIndex = static_cast<unsigned int>(*m_Iterator) % m_AxisFactor;
819 return *this;
820 }
821
822 PerAxisIterator& operator[](const unsigned int index) override
823 {
Narumol Prangnawaratac2770a2020-04-01 16:51:23 +0100824 ARMNN_ASSERT(m_Iterator);
Keith Davis5236e1d2019-11-04 08:58:33 +0000825 m_Iterator = m_Start + index;
826 m_AxisIndex = static_cast<unsigned int>(*m_Iterator) % m_AxisFactor;
827 return *this;
828 }
829
830 protected:
831 T* m_Iterator;
832 T* m_Start;
833 unsigned int m_AxisIndex;
834 unsigned int m_AxisFactor;
835};
836
837class QSymm8PerAxisDecoder : public PerAxisIterator<const int8_t, Decoder<float>>
838{
839public:
840 QSymm8PerAxisDecoder(const int8_t* data, const std::vector<float>& scale, unsigned int axisFactor)
Finn Williamsea8ce702020-09-29 19:54:00 +0100841 : PerAxisIterator(data, axisFactor), m_Scales(scale) {}
Keith Davis5236e1d2019-11-04 08:58:33 +0000842
843 float Get() const override
844 {
Finn Williamsea8ce702020-09-29 19:54:00 +0100845 return armnn::Dequantize(*m_Iterator, m_Scales[m_AxisIndex], 0);
Keith Davis5236e1d2019-11-04 08:58:33 +0000846 }
847
848 // Get scale of the current value
849 float GetScale() const
850 {
Finn Williamsea8ce702020-09-29 19:54:00 +0100851 return m_Scales[m_AxisIndex];
Keith Davis5236e1d2019-11-04 08:58:33 +0000852 }
853
Finn Williamsea8ce702020-09-29 19:54:00 +0100854 std::vector<float> DecodeTensor(const TensorShape &tensorShape,
855 const unsigned int channelMultiplier,
856 bool isDepthwise) override
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100857 {
Finn Williamsea8ce702020-09-29 19:54:00 +0100858 const uint32_t size = tensorShape.GetNumElements();
859 const uint32_t scaleSize = static_cast<uint32_t>(m_Scales.size());
860
861 const uint32_t stepSize = isDepthwise ?
862 tensorShape[2] * tensorShape[3] : tensorShape.GetNumElements() / tensorShape[0];
863
864 const uint32_t stepNum = size / (stepSize * channelMultiplier);
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100865 uint32_t scale;
866
867 std::vector<float> decodedTensor;
868 decodedTensor.reserve(size);
869
Finn Williamsea8ce702020-09-29 19:54:00 +0100870 // channelMultiplier is only used in depthwise convolutions and in other cases will have no effect
871 // stepSize is the length of a contiguous area sharing a quantization scale within a tensor
872 // stepNum is the number of those steps/blocks in the tensor
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100873 for (uint32_t mult = 0; mult < channelMultiplier; ++mult)
874 {
Finn Williamsea8ce702020-09-29 19:54:00 +0100875 for (uint32_t step = 0; step < stepNum; ++step)
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100876 {
Finn Williamsea8ce702020-09-29 19:54:00 +0100877 scale = (channelMultiplier * step + mult) % scaleSize;
878 for (uint32_t i = 0; i < stepSize; ++i)
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100879 {
Finn Williamsea8ce702020-09-29 19:54:00 +0100880 unsigned int index = mult * stepSize * channelMultiplier +
881 step * stepSize + i;
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100882 this->operator[](index);
Finn Williamsea8ce702020-09-29 19:54:00 +0100883 decodedTensor.emplace_back(armnn::Dequantize(*m_Iterator, m_Scales[scale], 0));
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100884 }
885 }
886 }
887 return decodedTensor;
888 }
889
Keith Davis5236e1d2019-11-04 08:58:33 +0000890private:
Finn Williamsea8ce702020-09-29 19:54:00 +0100891 std::vector<float> m_Scales;
Keith Davis5236e1d2019-11-04 08:58:33 +0000892};
893
894class QSymm8PerAxisEncoder : public PerAxisIterator<int8_t, Encoder<float>>
895{
896public:
897 QSymm8PerAxisEncoder(int8_t* data, const std::vector<float>& scale, unsigned int axisFactor)
898 : PerAxisIterator(data, axisFactor), m_Scale(scale) {}
899
900 void Set(float right)
901 {
902 *m_Iterator = armnn::Quantize<int8_t>(right, m_Scale[m_AxisIndex], 0);
903 }
904
905 float Get() const
906 {
907 return armnn::Dequantize(*m_Iterator, m_Scale[m_AxisIndex], 0);
908 }
909
910 // Get scale of the current value
911 float GetScale() const
912 {
913 return m_Scale[m_AxisIndex];
914 }
915
916private:
917 std::vector<float> m_Scale;
918};
919
Aron Virginas-Tarb67f9572019-11-04 15:00:19 +0000920class ScaledInt32PerAxisDecoder : public PerAxisIterator<const int32_t, Decoder<float>>
921{
922public:
923 ScaledInt32PerAxisDecoder(const int32_t* data, const std::vector<float>& scales, unsigned int axisFactor)
924 : PerAxisIterator(data, axisFactor), m_Scales(scales) {}
925
926 float Get() const override
927 {
928 return armnn::Dequantize(*m_Iterator, m_Scales[m_AxisIndex], 0);
929 }
930
931 // Get scale of the current value
932 float GetScale() const
933 {
934 return m_Scales[m_AxisIndex];
935 }
936
Finn Williamsea8ce702020-09-29 19:54:00 +0100937 std::vector<float> DecodeTensor(const TensorShape &tensorShape,
938 const unsigned int channelMultiplier,
939 bool isDepthwise) override
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100940 {
Finn Williamsea8ce702020-09-29 19:54:00 +0100941 const uint32_t size = tensorShape.GetNumElements();
942 const uint32_t scaleSize = static_cast<uint32_t>(m_Scales.size());
943
944 const uint32_t stepSize = isDepthwise ?
945 tensorShape[2] * tensorShape[3] : tensorShape.GetNumElements() / tensorShape[0];
946
947 const uint32_t stepNum = size / (stepSize * channelMultiplier);
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100948 uint32_t scale;
949
950 std::vector<float> decodedTensor;
951 decodedTensor.reserve(size);
952
Finn Williamsea8ce702020-09-29 19:54:00 +0100953 // channelMultiplier is only used in depthwise convolutions and in other cases will have no effect
954 // stepSize is the length of a contiguous area sharing a quantization scale within a tensor
955 // stepNum is the number of those steps/blocks in the tensor
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100956 for (uint32_t mult = 0; mult < channelMultiplier; ++mult)
957 {
Finn Williamsea8ce702020-09-29 19:54:00 +0100958 for (uint32_t step = 0; step < stepNum; ++step)
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100959 {
Finn Williamsea8ce702020-09-29 19:54:00 +0100960 scale = (channelMultiplier * step + mult) % scaleSize;
961 for (uint32_t i = 0; i < stepSize; ++i)
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100962 {
Finn Williamsea8ce702020-09-29 19:54:00 +0100963 unsigned int index = mult * stepSize * channelMultiplier +
964 step * stepSize + i;
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100965 this->operator[](index);
966 decodedTensor.emplace_back(armnn::Dequantize(*m_Iterator, m_Scales[scale], 0));
967 }
968 }
969 }
970 return decodedTensor;
971 }
972
Aron Virginas-Tarb67f9572019-11-04 15:00:19 +0000973private:
974 std::vector<float> m_Scales;
975};
976
977} // namespace armnn