blob: 0165ec7c7a288fa9a9f00b94e60689e26249a857 [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
48 virtual std::vector<float> DecodeTensor(uint32_t size,
49 uint32_t channelStep = 1,
50 uint32_t channelMultiplier = 1) = 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
Aron Virginas-Tar5edc8812019-11-05 18:00:21 +0000110 TypedIterator& SetIndex(unsigned int index, unsigned int axisIndex = 0) override
111 {
Jan Eilers8eb25602020-03-09 12:13:48 +0000112 IgnoreUnused(axisIndex);
Narumol Prangnawaratac2770a2020-04-01 16:51:23 +0100113 ARMNN_ASSERT(m_Iterator);
Aron Virginas-Tar5edc8812019-11-05 18:00:21 +0000114 m_Iterator = m_Start + index;
115 return *this;
116 }
117
Nattapat Chaimanowongeb2b3292019-05-07 12:02:30 +0100118protected:
Sadik Armagan2e6dc3a2019-04-03 17:48:18 +0100119 T* m_Iterator;
Francis Murtagh43aec582019-05-27 12:14:10 +0100120 T* m_Start;
Sadik Armagan2e6dc3a2019-04-03 17:48:18 +0100121};
122
Derek Lambertif30f7d32019-04-09 10:25:02 +0100123class QASymm8Decoder : public TypedIterator<const uint8_t, Decoder<float>>
Sadik Armagan2e6dc3a2019-04-03 17:48:18 +0100124{
125public:
126 QASymm8Decoder(const uint8_t* data, const float scale, const int32_t offset)
127 : TypedIterator(data), m_Scale(scale), m_Offset(offset) {}
128
Matthew Benthamc394a6d2019-06-24 12:51:25 +0100129 QASymm8Decoder(const float scale, const int32_t offset)
130 : QASymm8Decoder(nullptr, scale, offset) {}
131
Sadik Armagan2e6dc3a2019-04-03 17:48:18 +0100132 float Get() const override
133 {
134 return armnn::Dequantize(*m_Iterator, m_Scale, m_Offset);
135 }
136
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100137 std::vector<float> DecodeTensor(uint32_t size, uint32_t channelStepSize, uint32_t channelMultiplier) override
138 {
139 IgnoreUnused(channelStepSize, channelMultiplier);
140
141 std::vector<float> decodedTensor;
142 decodedTensor.reserve(size);
143
144 for (uint32_t i = 0; i < size; ++i)
145 {
146 this->operator[](i);
147 decodedTensor.emplace_back(armnn::Dequantize(*m_Iterator, m_Scale, m_Offset));
148 }
149
150 return decodedTensor;
151 }
152
Sadik Armagan2e6dc3a2019-04-03 17:48:18 +0100153private:
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100154
Sadik Armagan2e6dc3a2019-04-03 17:48:18 +0100155 const float m_Scale;
156 const int32_t m_Offset;
157};
158
Ryan OShea9add1202020-02-07 10:06:33 +0000159class QASymmS8Decoder : public TypedIterator<const int8_t, Decoder<float>>
160{
161public:
162 QASymmS8Decoder(const int8_t* data, const float scale, const int32_t offset)
163 : TypedIterator(data), m_Scale(scale), m_Offset(offset) {}
164
165 QASymmS8Decoder(const float scale, const int32_t offset)
166 : QASymmS8Decoder(nullptr, scale, offset) {}
167
168 float Get() const override
169 {
170 return armnn::Dequantize(*m_Iterator, m_Scale, m_Offset);
171 }
172
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100173 std::vector<float> DecodeTensor(uint32_t size, uint32_t channelStepSize, uint32_t channelMultiplier) override
174 {
175 IgnoreUnused(channelStepSize, channelMultiplier);
176
177 std::vector<float> decodedTensor;
178 decodedTensor.reserve(size);
179
180 for (uint32_t i = 0; i < size; ++i)
181 {
182 this->operator[](i);
183 decodedTensor.emplace_back(armnn::Dequantize(*m_Iterator, m_Scale, m_Offset));
184 }
185
186 return decodedTensor;
187 }
188
Ryan OShea9add1202020-02-07 10:06:33 +0000189private:
190 const float m_Scale;
191 const int32_t m_Offset;
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100192
Ryan OShea9add1202020-02-07 10:06:33 +0000193};
194
Finn Williamsfd271062019-12-04 14:27:27 +0000195class QSymmS8Decoder : public TypedIterator<const int8_t, Decoder<float>>
196{
197public:
198 QSymmS8Decoder(const int8_t* data, const float scale, const int32_t offset)
199 : TypedIterator(data), m_Scale(scale), m_Offset(offset) {}
200
201 QSymmS8Decoder(const float scale, const int32_t offset)
202 : QSymmS8Decoder(nullptr, scale, offset) {}
203
204 float Get() const override
205 {
206 return armnn::Dequantize(*m_Iterator, m_Scale, m_Offset);
207 }
208
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100209 std::vector<float> DecodeTensor(uint32_t size, uint32_t channelStepSize, uint32_t channelMultiplier) override
210 {
211 IgnoreUnused(channelStepSize, channelMultiplier);
212
213 std::vector<float> decodedTensor;
214 decodedTensor.reserve(size);
215
216 for (uint32_t i = 0; i < size; ++i)
217 {
218 this->operator[](i);
219 decodedTensor.emplace_back(armnn::Dequantize(*m_Iterator, m_Scale, m_Offset));
220 }
221
222 return decodedTensor;
223 }
224
Finn Williamsfd271062019-12-04 14:27:27 +0000225private:
226 const float m_Scale;
227 const int32_t m_Offset;
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100228
Finn Williamsfd271062019-12-04 14:27:27 +0000229};
230
Derek Lambertif30f7d32019-04-09 10:25:02 +0100231class QSymm16Decoder : public TypedIterator<const int16_t, Decoder<float>>
Sadik Armagan2999a022019-04-09 14:20:12 +0100232{
233public:
234 QSymm16Decoder(const int16_t* data, const float scale, const int32_t offset)
235 : TypedIterator(data), m_Scale(scale), m_Offset(offset) {}
236
Matthew Benthamc394a6d2019-06-24 12:51:25 +0100237 QSymm16Decoder(const float scale, const int32_t offset)
238 : QSymm16Decoder(nullptr, scale, offset) {}
239
Sadik Armagan2999a022019-04-09 14:20:12 +0100240 float Get() const override
241 {
242 return armnn::Dequantize(*m_Iterator, m_Scale, m_Offset);
243 }
244
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100245
246
247 std::vector<float> DecodeTensor(uint32_t size, uint32_t channelStepSize, uint32_t channelMultiplier) override
248 {
249 IgnoreUnused(channelStepSize, channelMultiplier);
250
251 std::vector<float> decodedTensor;
252 decodedTensor.reserve(size);
253
254 for (uint32_t i = 0; i < size; ++i)
255 {
256 this->operator[](i);
257 decodedTensor.emplace_back(armnn::Dequantize(*m_Iterator, m_Scale, m_Offset));
258 }
259
260 return decodedTensor;
261 }
262
Sadik Armagan2999a022019-04-09 14:20:12 +0100263private:
264 const float m_Scale;
265 const int32_t m_Offset;
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100266
Sadik Armagan2999a022019-04-09 14:20:12 +0100267};
268
Narumol Prangnawarat88325222020-03-06 14:45:57 +0000269class BFloat16Decoder : public TypedIterator<const BFloat16, Decoder<float>>
270{
271public:
272 BFloat16Decoder(const BFloat16* data)
273 : TypedIterator(data) {}
274
275 BFloat16Decoder()
276 : BFloat16Decoder(nullptr) {}
277
278 float Get() const override
279 {
280 float val = 0.f;
281 armnnUtils::FloatingPointConverter::ConvertBFloat16ToFloat32(m_Iterator, 1, &val);
282 return val;
283 }
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100284
285 std::vector<float> DecodeTensor(uint32_t size, uint32_t channelStepSize, uint32_t channelMultiplier) override
286 {
287 IgnoreUnused(channelStepSize, channelMultiplier);
288
289 std::vector<float> decodedTensor;
290 decodedTensor.reserve(size);
291
292 for (uint32_t i = 0; i < size; ++i)
293 {
294 this->operator[](i);
295
296 float val = 0.f;
297 armnnUtils::FloatingPointConverter::ConvertBFloat16ToFloat32(m_Iterator, 1, &val);
298 decodedTensor.emplace_back(val);
299 }
300
301 return decodedTensor;
302 }
303
Narumol Prangnawarat88325222020-03-06 14:45:57 +0000304};
305
Matthew Jacksone69c3992019-09-09 14:31:21 +0100306class Float16Decoder : public TypedIterator<const Half, Decoder<float>>
Sadik Armagan2e6dc3a2019-04-03 17:48:18 +0100307{
308public:
Matthew Jacksone69c3992019-09-09 14:31:21 +0100309 Float16Decoder(const Half* data)
Sadik Armagan2e6dc3a2019-04-03 17:48:18 +0100310 : TypedIterator(data) {}
311
Matthew Jacksone69c3992019-09-09 14:31:21 +0100312 Float16Decoder()
313 : Float16Decoder(nullptr) {}
314
315 float Get() const override
316 {
317 float val = 0.f;
318 armnnUtils::FloatingPointConverter::ConvertFloat16To32(m_Iterator, 1, &val);
319 return val;
320 }
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100321
322 std::vector<float> DecodeTensor(uint32_t size, uint32_t channelStepSize, uint32_t channelMultiplier) override
323 {
324 IgnoreUnused(channelStepSize, channelMultiplier);
325
326 std::vector<float> decodedTensor;
327 decodedTensor.reserve(size);
328
329 for (uint32_t i = 0; i < size; ++i)
330 {
331 float val = 0.f;
332 this->operator[](i);
333 armnnUtils::FloatingPointConverter::ConvertFloat16To32(m_Iterator, 1, &val);
334 decodedTensor.emplace_back(val);
335 }
336
337 return decodedTensor;
338 }
339
340
Matthew Jacksone69c3992019-09-09 14:31:21 +0100341};
342
343class Float32Decoder : public TypedIterator<const float, Decoder<float>>
344{
345public:
346 Float32Decoder(const float* data)
347 : TypedIterator(data) {}
348
349 Float32Decoder()
350 : Float32Decoder(nullptr) {}
Matthew Benthamc394a6d2019-06-24 12:51:25 +0100351
Derek Lambertif30f7d32019-04-09 10:25:02 +0100352 float Get() const override
Sadik Armagan2e6dc3a2019-04-03 17:48:18 +0100353 {
Derek Lambertif30f7d32019-04-09 10:25:02 +0100354 return *m_Iterator;
Sadik Armagan2e6dc3a2019-04-03 17:48:18 +0100355 }
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100356 std::vector<float> DecodeTensor(uint32_t size, uint32_t channelStepSize, uint32_t channelMultiplier) override
357 {
358 IgnoreUnused(channelStepSize, channelMultiplier);
359 std::vector<float> decodedTensor;
360
361 decodedTensor.reserve(size);
362 decodedTensor.assign(m_Start, m_Start + size);
363
364 return decodedTensor;
365 }
Sadik Armagan2e6dc3a2019-04-03 17:48:18 +0100366};
367
Mike Kelly9b398322019-05-22 17:21:49 +0100368class ScaledInt32Decoder : public TypedIterator<const int32_t, Decoder<float>>
369{
370public:
371 ScaledInt32Decoder(const int32_t* data, const float scale)
372 : TypedIterator(data), m_Scale(scale) {}
373
Matthew Benthamc394a6d2019-06-24 12:51:25 +0100374 ScaledInt32Decoder(const float scale)
375 : ScaledInt32Decoder(nullptr, scale) {}
376
Mike Kelly9b398322019-05-22 17:21:49 +0100377 float Get() const override
378 {
379 return static_cast<float>(*m_Iterator) * m_Scale;
380 }
381
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100382 std::vector<float> DecodeTensor(uint32_t size, uint32_t channelStepSize, uint32_t channelMultiplier) override
383 {
384 IgnoreUnused(channelStepSize, channelMultiplier);
385
386 std::vector<float> decodedTensor;
387 decodedTensor.reserve(size);
388
389 for (uint32_t i = 0; i < size; ++i)
390 {
391 this->operator[](i);
392 decodedTensor.emplace_back(static_cast<float>(*m_Iterator) * m_Scale);
393 }
394
395 return decodedTensor;
396 }
397
Mike Kelly9b398322019-05-22 17:21:49 +0100398private:
399 const float m_Scale;
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100400
Mike Kelly9b398322019-05-22 17:21:49 +0100401};
402
Aron Virginas-Tar198ee402019-08-02 18:54:28 +0100403class Int32Decoder : public TypedIterator<const int32_t, Decoder<float>>
404{
405public:
406 Int32Decoder(const int32_t* data)
407 : TypedIterator(data) {}
408
409 Int32Decoder()
410 : Int32Decoder(nullptr) {}
411
412 float Get() const override
413 {
414 return static_cast<float>(*m_Iterator);
415 }
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100416
417 std::vector<float> DecodeTensor(uint32_t size, uint32_t channelStepSize, uint32_t channelMultiplier) override
418 {
419 IgnoreUnused(channelStepSize, channelMultiplier);
420
421 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 Williamsb9dcfe62020-09-17 15:58:31 +0100447
448 std::vector<float> DecodeTensor(uint32_t size, uint32_t channelStepSize, uint32_t channelMultiplier) override
449 {
450 IgnoreUnused(channelStepSize, channelMultiplier);
451
452 std::vector<float> decodedTensor;
453 decodedTensor.reserve(size);
454
455 for (uint32_t i = 0; i < size; ++i)
456 {
457 this->operator[](i);
458 decodedTensor.emplace_back(*m_Iterator);
459 }
460
461 return decodedTensor;
462 }
Finn Williamscbd2c232020-06-22 15:58:32 +0100463};
464
Sadik Armaganb60dd242020-03-19 13:53:16 +0000465class BooleanDecoder : public TypedIterator<const uint8_t, Decoder<float>>
466{
467public:
468 BooleanDecoder(const uint8_t* data)
469 : TypedIterator(data) {}
470
471 BooleanDecoder()
472 : BooleanDecoder(nullptr) {}
473
474 float Get() const override
475 {
476 return *m_Iterator;
477 }
478
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100479 std::vector<float> DecodeTensor(uint32_t size, uint32_t channelStepSize, uint32_t channelMultiplier) override
480 {
481 IgnoreUnused(channelStepSize, channelMultiplier);
482
483 std::vector<float> decodedTensor;
484 decodedTensor.reserve(size);
485
486 for (uint32_t i = 0; i < size; ++i)
487 {
488 this->operator[](i);
489 decodedTensor.emplace_back(*m_Iterator);
490 }
491
492 return decodedTensor;
493 }
Sadik Armaganb60dd242020-03-19 13:53:16 +0000494};
495
Derek Lambertif30f7d32019-04-09 10:25:02 +0100496class QASymm8Encoder : public TypedIterator<uint8_t, Encoder<float>>
Sadik Armagan2e6dc3a2019-04-03 17:48:18 +0100497{
498public:
499 QASymm8Encoder(uint8_t* data, const float scale, const int32_t offset)
500 : TypedIterator(data), m_Scale(scale), m_Offset(offset) {}
501
Matthew Benthamc394a6d2019-06-24 12:51:25 +0100502 QASymm8Encoder(const float scale, const int32_t offset)
503 : QASymm8Encoder(nullptr, scale, offset) {}
504
Derek Lambertif30f7d32019-04-09 10:25:02 +0100505 void Set(float right) override
Sadik Armagan2e6dc3a2019-04-03 17:48:18 +0100506 {
507 *m_Iterator = armnn::Quantize<uint8_t>(right, m_Scale, m_Offset);
508 }
509
Nattapat Chaimanowongeb2b3292019-05-07 12:02:30 +0100510 float Get() const override
511 {
512 return armnn::Dequantize(*m_Iterator, m_Scale, m_Offset);
513 }
514
Sadik Armagan2e6dc3a2019-04-03 17:48:18 +0100515private:
516 const float m_Scale;
517 const int32_t m_Offset;
518};
519
Ryan OShea9add1202020-02-07 10:06:33 +0000520class QASymmS8Encoder : public TypedIterator<int8_t, Encoder<float>>
521{
522public:
523 QASymmS8Encoder(int8_t* data, const float scale, const int32_t offset)
524 : TypedIterator(data), m_Scale(scale), m_Offset(offset) {}
525
526 QASymmS8Encoder(const float scale, const int32_t offset)
527 : QASymmS8Encoder(nullptr, scale, offset) {}
528
529 void Set(float right) override
530 {
531 *m_Iterator = armnn::Quantize<int8_t>(right, m_Scale, m_Offset);
532 }
533
534 float Get() const override
535 {
536 return armnn::Dequantize(*m_Iterator, m_Scale, m_Offset);
537 }
538
539private:
540 const float m_Scale;
541 const int32_t m_Offset;
542};
543
Finn Williamsfd271062019-12-04 14:27:27 +0000544class QSymmS8Encoder : public TypedIterator<int8_t, Encoder<float>>
545{
546public:
547 QSymmS8Encoder(int8_t* data, const float scale, const int32_t offset)
548 : TypedIterator(data), m_Scale(scale), m_Offset(offset) {}
549
550 QSymmS8Encoder(const float scale, const int32_t offset)
551 : QSymmS8Encoder(nullptr, scale, offset) {}
552
553 void Set(float right) override
554 {
555 *m_Iterator = armnn::Quantize<int8_t>(right, m_Scale, m_Offset);
556 }
557
558 float Get() const override
559 {
560 return armnn::Dequantize(*m_Iterator, m_Scale, m_Offset);
561 }
562
563private:
564 const float m_Scale;
565 const int32_t m_Offset;
566};
567
Derek Lambertif30f7d32019-04-09 10:25:02 +0100568class QSymm16Encoder : public TypedIterator<int16_t, Encoder<float>>
569{
570public:
571 QSymm16Encoder(int16_t* data, const float scale, const int32_t offset)
572 : TypedIterator(data), m_Scale(scale), m_Offset(offset) {}
573
Matthew Benthamc394a6d2019-06-24 12:51:25 +0100574 QSymm16Encoder(const float scale, const int32_t offset)
575 : QSymm16Encoder(nullptr, scale, offset) {}
576
Derek Lambertif30f7d32019-04-09 10:25:02 +0100577 void Set(float right) override
578 {
579 *m_Iterator = armnn::Quantize<int16_t>(right, m_Scale, m_Offset);
580 }
581
Nattapat Chaimanowongeb2b3292019-05-07 12:02:30 +0100582 float Get() const override
583 {
584 return armnn::Dequantize(*m_Iterator, m_Scale, m_Offset);
585 }
586
Derek Lambertif30f7d32019-04-09 10:25:02 +0100587private:
588 const float m_Scale;
589 const int32_t m_Offset;
590};
591
Narumol Prangnawarat88325222020-03-06 14:45:57 +0000592class BFloat16Encoder : public TypedIterator<armnn::BFloat16, Encoder<float>>
593{
594public:
595 BFloat16Encoder(armnn::BFloat16* data)
596 : TypedIterator(data) {}
597
598 BFloat16Encoder()
599 : BFloat16Encoder(nullptr) {}
600
601 void Set(float right) override
602 {
603 armnnUtils::FloatingPointConverter::ConvertFloat32ToBFloat16(&right, 1, m_Iterator);
604 }
605
606 float Get() const override
607 {
608 float val = 0.f;
609 armnnUtils::FloatingPointConverter::ConvertBFloat16ToFloat32(m_Iterator, 1, &val);
610 return val;
611 }
612};
613
Matthew Jacksone69c3992019-09-09 14:31:21 +0100614class Float16Encoder : public TypedIterator<Half, Encoder<float>>
Derek Lambertif30f7d32019-04-09 10:25:02 +0100615{
616public:
Matthew Jacksone69c3992019-09-09 14:31:21 +0100617 Float16Encoder(Half* data)
Derek Lambertif30f7d32019-04-09 10:25:02 +0100618 : TypedIterator(data) {}
619
Matthew Jacksone69c3992019-09-09 14:31:21 +0100620 Float16Encoder()
621 : Float16Encoder(nullptr) {}
622
623 void Set(float right) override
624 {
625 armnnUtils::FloatingPointConverter::ConvertFloat32To16(&right, 1, m_Iterator);
626 }
627
628 float Get() const override
629 {
630 float val = 0.f;
631 armnnUtils::FloatingPointConverter::ConvertFloat16To32(m_Iterator, 1, &val);
632 return val;
633 }
634};
635
636class Float32Encoder : public TypedIterator<float, Encoder<float>>
637{
638public:
639 Float32Encoder(float* data)
640 : TypedIterator(data) {}
641
642 Float32Encoder()
643 : Float32Encoder(nullptr) {}
Matthew Benthamc394a6d2019-06-24 12:51:25 +0100644
Derek Lambertif30f7d32019-04-09 10:25:02 +0100645 void Set(float right) override
646 {
647 *m_Iterator = right;
648 }
Nattapat Chaimanowongeb2b3292019-05-07 12:02:30 +0100649
650 float Get() const override
651 {
652 return *m_Iterator;
653 }
Derek Lambertif30f7d32019-04-09 10:25:02 +0100654};
655
Aron Virginas-Tar198ee402019-08-02 18:54:28 +0100656class Int32Encoder : public TypedIterator<int32_t, Encoder<float>>
657{
658public:
659 Int32Encoder(int32_t* data)
660 : TypedIterator(data) {}
661
662 Int32Encoder()
663 : Int32Encoder(nullptr) {}
664
665 void Set(float right) override
666 {
667 *m_Iterator = static_cast<int32_t>(right);
668 }
669
670 float Get() const override
671 {
672 return static_cast<float>(*m_Iterator);
673 }
674};
675
Finn Williamscbd2c232020-06-22 15:58:32 +0100676class Int32ToInt32tEncoder : public TypedIterator<int32_t, Encoder<int32_t>>
677{
678public:
679 Int32ToInt32tEncoder(int32_t* data)
680 : TypedIterator(data){}
681
682 Int32ToInt32tEncoder()
683 : Int32ToInt32tEncoder(nullptr) {}
684
685 void Set(int32_t right) override
686 {
687 *m_Iterator = right;
688 }
689
690 int32_t Get() const override
691 {
692 return *m_Iterator;
693 }
694};
695
Derek Lambertif30f7d32019-04-09 10:25:02 +0100696class BooleanEncoder : public TypedIterator<uint8_t, Encoder<bool>>
Sadik Armagan2e6dc3a2019-04-03 17:48:18 +0100697{
698public:
699 BooleanEncoder(uint8_t* data)
700 : TypedIterator(data) {}
701
Matthew Benthamc394a6d2019-06-24 12:51:25 +0100702 BooleanEncoder()
703 : BooleanEncoder(nullptr) {}
704
Sadik Armagan2e6dc3a2019-04-03 17:48:18 +0100705 void Set(bool right) override
706 {
707 *m_Iterator = right;
708 }
Nattapat Chaimanowongeb2b3292019-05-07 12:02:30 +0100709
710 bool Get() const override
711 {
712 return *m_Iterator;
713 }
Sadik Armagan2e6dc3a2019-04-03 17:48:18 +0100714};
715
Keith Davis5236e1d2019-11-04 08:58:33 +0000716// PerAxisIterator for per-axis quantization
717template<typename T, typename Base>
718class PerAxisIterator : public Base
719{
720public:
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100721 // axisFactor is used to calculate channelStep
Keith Davis5236e1d2019-11-04 08:58:33 +0000722 PerAxisIterator(T* data = nullptr, unsigned int axisFactor = 0)
723 : m_Iterator(data), m_Start(data), m_AxisIndex(0), m_AxisFactor(axisFactor)
724 {}
725
726 // This should be called to set index for per-axis Encoder/Decoder
Aron Virginas-Tar5edc8812019-11-05 18:00:21 +0000727 PerAxisIterator& SetIndex(unsigned int index, unsigned int axisIndex) override
Keith Davis5236e1d2019-11-04 08:58:33 +0000728 {
Narumol Prangnawaratac2770a2020-04-01 16:51:23 +0100729 ARMNN_ASSERT(m_Iterator);
Keith Davis5236e1d2019-11-04 08:58:33 +0000730 m_Iterator = m_Start + index;
731 m_AxisIndex = axisIndex;
732 return *this;
733 }
734
735 void Reset(void* data) override
736 {
737 m_Iterator = reinterpret_cast<T*>(data);
738 m_Start = m_Iterator;
739 m_AxisIndex = 0;
740 }
741
742 PerAxisIterator& operator++() override
743 {
Narumol Prangnawaratac2770a2020-04-01 16:51:23 +0100744 ARMNN_ASSERT(m_Iterator);
Keith Davis5236e1d2019-11-04 08:58:33 +0000745 ++m_Iterator;
746 m_AxisIndex = static_cast<unsigned int>(*m_Iterator) % m_AxisFactor;
747 return *this;
748 }
749
750 PerAxisIterator& operator+=(const unsigned int increment) override
751 {
Narumol Prangnawaratac2770a2020-04-01 16:51:23 +0100752 ARMNN_ASSERT(m_Iterator);
Keith Davis5236e1d2019-11-04 08:58:33 +0000753 m_Iterator += increment;
754 m_AxisIndex = static_cast<unsigned int>(*m_Iterator) % m_AxisFactor;
755 return *this;
756 }
757
758 PerAxisIterator& operator-=(const unsigned int decrement) override
759 {
Narumol Prangnawaratac2770a2020-04-01 16:51:23 +0100760 ARMNN_ASSERT(m_Iterator);
Keith Davis5236e1d2019-11-04 08:58:33 +0000761 m_Iterator -= decrement;
762 m_AxisIndex = static_cast<unsigned int>(*m_Iterator) % m_AxisFactor;
763 return *this;
764 }
765
766 PerAxisIterator& operator[](const unsigned int index) override
767 {
Narumol Prangnawaratac2770a2020-04-01 16:51:23 +0100768 ARMNN_ASSERT(m_Iterator);
Keith Davis5236e1d2019-11-04 08:58:33 +0000769 m_Iterator = m_Start + index;
770 m_AxisIndex = static_cast<unsigned int>(*m_Iterator) % m_AxisFactor;
771 return *this;
772 }
773
774 protected:
775 T* m_Iterator;
776 T* m_Start;
777 unsigned int m_AxisIndex;
778 unsigned int m_AxisFactor;
779};
780
781class QSymm8PerAxisDecoder : public PerAxisIterator<const int8_t, Decoder<float>>
782{
783public:
784 QSymm8PerAxisDecoder(const int8_t* data, const std::vector<float>& scale, unsigned int axisFactor)
785 : PerAxisIterator(data, axisFactor), m_Scale(scale) {}
786
787 float Get() const override
788 {
789 return armnn::Dequantize(*m_Iterator, m_Scale[m_AxisIndex], 0);
790 }
791
792 // Get scale of the current value
793 float GetScale() const
794 {
795 return m_Scale[m_AxisIndex];
796 }
797
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100798 std::vector<float> DecodeTensor(uint32_t size, uint32_t channelStepSize, uint32_t channelMultiplier) override
799 {
800 uint32_t channels = static_cast<uint32_t>(m_Scale.size());
801 uint32_t channelSteps = size / (channelStepSize * channelMultiplier);
802 uint32_t scale;
803
804 std::vector<float> decodedTensor;
805 decodedTensor.reserve(size);
806
807 // channelMultiplier is only used in depthwise convolutions and in other cases will cancel out
808 // channelStepSize is the length of a contiguous section of a channel within a tensor
809 // channelSteps is the number of those steps/blocks in the tensor
810 for (uint32_t mult = 0; mult < channelMultiplier; ++mult)
811 {
812 for (uint32_t channelStep = 0; channelStep < channelSteps; ++channelStep)
813 {
814 scale = (channelMultiplier * channelStep + mult) % channels;
815 for (uint32_t i = 0; i < channelStepSize; ++i)
816 {
817 unsigned int index = mult * channelStepSize * channelMultiplier +
818 channelStep * channelStepSize + i;
819 this->operator[](index);
820 decodedTensor.emplace_back(armnn::Dequantize(*m_Iterator, m_Scale[scale], 0));
821 }
822 }
823 }
824 return decodedTensor;
825 }
826
Keith Davis5236e1d2019-11-04 08:58:33 +0000827private:
828 std::vector<float> m_Scale;
829};
830
831class QSymm8PerAxisEncoder : public PerAxisIterator<int8_t, Encoder<float>>
832{
833public:
834 QSymm8PerAxisEncoder(int8_t* data, const std::vector<float>& scale, unsigned int axisFactor)
835 : PerAxisIterator(data, axisFactor), m_Scale(scale) {}
836
837 void Set(float right)
838 {
839 *m_Iterator = armnn::Quantize<int8_t>(right, m_Scale[m_AxisIndex], 0);
840 }
841
842 float Get() const
843 {
844 return armnn::Dequantize(*m_Iterator, m_Scale[m_AxisIndex], 0);
845 }
846
847 // Get scale of the current value
848 float GetScale() const
849 {
850 return m_Scale[m_AxisIndex];
851 }
852
853private:
854 std::vector<float> m_Scale;
855};
856
Aron Virginas-Tarb67f9572019-11-04 15:00:19 +0000857class ScaledInt32PerAxisDecoder : public PerAxisIterator<const int32_t, Decoder<float>>
858{
859public:
860 ScaledInt32PerAxisDecoder(const int32_t* data, const std::vector<float>& scales, unsigned int axisFactor)
861 : PerAxisIterator(data, axisFactor), m_Scales(scales) {}
862
863 float Get() const override
864 {
865 return armnn::Dequantize(*m_Iterator, m_Scales[m_AxisIndex], 0);
866 }
867
868 // Get scale of the current value
869 float GetScale() const
870 {
871 return m_Scales[m_AxisIndex];
872 }
873
Finn Williamsb9dcfe62020-09-17 15:58:31 +0100874 std::vector<float> DecodeTensor(uint32_t size, uint32_t channelStepSize, uint32_t channelMultiplier) override
875 {
876 uint32_t channels = static_cast<uint32_t>(m_Scales.size());
877 uint32_t channelSteps = size / (channelStepSize * channelMultiplier);
878 uint32_t scale;
879
880 std::vector<float> decodedTensor;
881 decodedTensor.reserve(size);
882
883 // channelMultiplier is only used in depthwise convolutions and in other cases will cancel out
884 // channelStepSize is the length of a contiguous section of a channel within a tensor
885 // channelSteps is the number of those steps/blocks in the tensor
886 for (uint32_t mult = 0; mult < channelMultiplier; ++mult)
887 {
888 for (uint32_t channelStep = 0; channelStep < channelSteps; ++channelStep)
889 {
890 scale = (channelMultiplier * channelStep + mult) % channels;
891 for (uint32_t i = 0; i < channelStepSize; ++i)
892 {
893 unsigned int index = mult * channelStepSize * channelMultiplier +
894 channelStep * channelStepSize + i;
895 this->operator[](index);
896 decodedTensor.emplace_back(armnn::Dequantize(*m_Iterator, m_Scales[scale], 0));
897 }
898 }
899 }
900 return decodedTensor;
901 }
902
Aron Virginas-Tarb67f9572019-11-04 15:00:19 +0000903private:
904 std::vector<float> m_Scales;
905};
906
907} // namespace armnn