ArmNN
 20.08
BaseIterator.hpp
Go to the documentation of this file.
1 //
2 // Copyright © 2017 Arm Ltd. All rights reserved.
3 // SPDX-License-Identifier: MIT
4 //
5 
6 #pragma once
7 
8 #include <armnn/TypesUtils.hpp>
12 
13 #include <ResolveType.hpp>
14 
15 namespace armnn
16 {
17 
19 {
20 public:
22 
23  virtual ~BaseIterator() {}
24 
25  virtual BaseIterator& SetIndex(unsigned int index, unsigned int axisIndex = 0) = 0;
26 
27  virtual BaseIterator& operator++() = 0;
28 
29  virtual BaseIterator& operator+=(const unsigned int increment) = 0;
30 
31  virtual BaseIterator& operator-=(const unsigned int increment) = 0;
32 
33  virtual BaseIterator& operator[](const unsigned int index) = 0;
34 };
35 
36 template<typename IType>
37 class Decoder : public BaseIterator
38 {
39 public:
40  Decoder() {}
41 
42  virtual ~Decoder() {}
43 
44  virtual void Reset(void*) = 0;
45 
46  virtual IType Get() const = 0;
47 };
48 
49 template<typename IType>
50 class Encoder : public BaseIterator
51 {
52 public:
53  Encoder() {}
54 
55  virtual ~Encoder() {}
56 
57  virtual void Reset(void*) = 0;
58 
59  virtual void Set(IType right) = 0;
60 
61  virtual IType Get() const = 0;
62 };
63 
64 template<typename T, typename Base>
65 class TypedIterator : public Base
66 {
67 public:
68  TypedIterator(T* data = nullptr)
69  : m_Iterator(data), m_Start(data)
70  {}
71 
72  void Reset(void* data) override
73  {
74  m_Iterator = reinterpret_cast<T*>(data);
75  m_Start = m_Iterator;
76  }
77 
79  {
80  ARMNN_ASSERT(m_Iterator);
81  ++m_Iterator;
82  return *this;
83  }
84 
85  TypedIterator& operator+=(const unsigned int increment) override
86  {
87  ARMNN_ASSERT(m_Iterator);
88  m_Iterator += increment;
89  return *this;
90  }
91 
92  TypedIterator& operator-=(const unsigned int increment) override
93  {
94  ARMNN_ASSERT(m_Iterator);
95  m_Iterator -= increment;
96  return *this;
97  }
98 
99  TypedIterator& operator[](const unsigned int index) override
100  {
101  ARMNN_ASSERT(m_Iterator);
102  m_Iterator = m_Start + index;
103  return *this;
104  }
105 
106  TypedIterator& SetIndex(unsigned int index, unsigned int axisIndex = 0) override
107  {
108  IgnoreUnused(axisIndex);
109  ARMNN_ASSERT(m_Iterator);
110  m_Iterator = m_Start + index;
111  return *this;
112  }
113 
114 protected:
117 };
118 
119 class QASymm8Decoder : public TypedIterator<const uint8_t, Decoder<float>>
120 {
121 public:
122  QASymm8Decoder(const uint8_t* data, const float scale, const int32_t offset)
123  : TypedIterator(data), m_Scale(scale), m_Offset(offset) {}
124 
125  QASymm8Decoder(const float scale, const int32_t offset)
126  : QASymm8Decoder(nullptr, scale, offset) {}
127 
128  float Get() const override
129  {
130  return armnn::Dequantize(*m_Iterator, m_Scale, m_Offset);
131  }
132 
133 private:
134  const float m_Scale;
135  const int32_t m_Offset;
136 };
137 
138 class QASymmS8Decoder : public TypedIterator<const int8_t, Decoder<float>>
139 {
140 public:
141  QASymmS8Decoder(const int8_t* data, const float scale, const int32_t offset)
142  : TypedIterator(data), m_Scale(scale), m_Offset(offset) {}
143 
144  QASymmS8Decoder(const float scale, const int32_t offset)
145  : QASymmS8Decoder(nullptr, scale, offset) {}
146 
147  float Get() const override
148  {
149  return armnn::Dequantize(*m_Iterator, m_Scale, m_Offset);
150  }
151 
152 private:
153  const float m_Scale;
154  const int32_t m_Offset;
155 };
156 
157 class QSymmS8Decoder : public TypedIterator<const int8_t, Decoder<float>>
158 {
159 public:
160  QSymmS8Decoder(const int8_t* data, const float scale, const int32_t offset)
161  : TypedIterator(data), m_Scale(scale), m_Offset(offset) {}
162 
163  QSymmS8Decoder(const float scale, const int32_t offset)
164  : QSymmS8Decoder(nullptr, scale, offset) {}
165 
166  float Get() const override
167  {
168  return armnn::Dequantize(*m_Iterator, m_Scale, m_Offset);
169  }
170 
171 private:
172  const float m_Scale;
173  const int32_t m_Offset;
174 };
175 
176 class QSymm16Decoder : public TypedIterator<const int16_t, Decoder<float>>
177 {
178 public:
179  QSymm16Decoder(const int16_t* data, const float scale, const int32_t offset)
180  : TypedIterator(data), m_Scale(scale), m_Offset(offset) {}
181 
182  QSymm16Decoder(const float scale, const int32_t offset)
183  : QSymm16Decoder(nullptr, scale, offset) {}
184 
185  float Get() const override
186  {
187  return armnn::Dequantize(*m_Iterator, m_Scale, m_Offset);
188  }
189 
190 private:
191  const float m_Scale;
192  const int32_t m_Offset;
193 };
194 
195 class BFloat16Decoder : public TypedIterator<const BFloat16, Decoder<float>>
196 {
197 public:
199  : TypedIterator(data) {}
200 
202  : BFloat16Decoder(nullptr) {}
203 
204  float Get() const override
205  {
206  float val = 0.f;
208  return val;
209  }
210 };
211 
212 class Float16Decoder : public TypedIterator<const Half, Decoder<float>>
213 {
214 public:
215  Float16Decoder(const Half* data)
216  : TypedIterator(data) {}
217 
219  : Float16Decoder(nullptr) {}
220 
221  float Get() const override
222  {
223  float val = 0.f;
225  return val;
226  }
227 };
228 
229 class Float32Decoder : public TypedIterator<const float, Decoder<float>>
230 {
231 public:
232  Float32Decoder(const float* data)
233  : TypedIterator(data) {}
234 
236  : Float32Decoder(nullptr) {}
237 
238  float Get() const override
239  {
240  return *m_Iterator;
241  }
242 };
243 
244 class ScaledInt32Decoder : public TypedIterator<const int32_t, Decoder<float>>
245 {
246 public:
247  ScaledInt32Decoder(const int32_t* data, const float scale)
248  : TypedIterator(data), m_Scale(scale) {}
249 
250  ScaledInt32Decoder(const float scale)
251  : ScaledInt32Decoder(nullptr, scale) {}
252 
253  float Get() const override
254  {
255  return static_cast<float>(*m_Iterator) * m_Scale;
256  }
257 
258 private:
259  const float m_Scale;
260 };
261 
262 class Int32Decoder : public TypedIterator<const int32_t, Decoder<float>>
263 {
264 public:
265  Int32Decoder(const int32_t* data)
266  : TypedIterator(data) {}
267 
269  : Int32Decoder(nullptr) {}
270 
271  float Get() const override
272  {
273  return static_cast<float>(*m_Iterator);
274  }
275 };
276 
277 class Int32ToInt32tDecoder : public TypedIterator<const int32_t, Decoder<int32_t>>
278 {
279 public:
280  Int32ToInt32tDecoder(const int32_t* data)
281  : TypedIterator(data){}
282 
284  : Int32ToInt32tDecoder(nullptr) {}
285 
286  int32_t Get() const override
287  {
288  return *m_Iterator;
289  }
290 };
291 
292 class BooleanDecoder : public TypedIterator<const uint8_t, Decoder<float>>
293 {
294 public:
295  BooleanDecoder(const uint8_t* data)
296  : TypedIterator(data) {}
297 
299  : BooleanDecoder(nullptr) {}
300 
301  float Get() const override
302  {
303  return *m_Iterator;
304  }
305 
306 };
307 
308 class QASymm8Encoder : public TypedIterator<uint8_t, Encoder<float>>
309 {
310 public:
311  QASymm8Encoder(uint8_t* data, const float scale, const int32_t offset)
312  : TypedIterator(data), m_Scale(scale), m_Offset(offset) {}
313 
314  QASymm8Encoder(const float scale, const int32_t offset)
315  : QASymm8Encoder(nullptr, scale, offset) {}
316 
317  void Set(float right) override
318  {
319  *m_Iterator = armnn::Quantize<uint8_t>(right, m_Scale, m_Offset);
320  }
321 
322  float Get() const override
323  {
324  return armnn::Dequantize(*m_Iterator, m_Scale, m_Offset);
325  }
326 
327 private:
328  const float m_Scale;
329  const int32_t m_Offset;
330 };
331 
332 class QASymmS8Encoder : public TypedIterator<int8_t, Encoder<float>>
333 {
334 public:
335  QASymmS8Encoder(int8_t* data, const float scale, const int32_t offset)
336  : TypedIterator(data), m_Scale(scale), m_Offset(offset) {}
337 
338  QASymmS8Encoder(const float scale, const int32_t offset)
339  : QASymmS8Encoder(nullptr, scale, offset) {}
340 
341  void Set(float right) override
342  {
343  *m_Iterator = armnn::Quantize<int8_t>(right, m_Scale, m_Offset);
344  }
345 
346  float Get() const override
347  {
348  return armnn::Dequantize(*m_Iterator, m_Scale, m_Offset);
349  }
350 
351 private:
352  const float m_Scale;
353  const int32_t m_Offset;
354 };
355 
356 class QSymmS8Encoder : public TypedIterator<int8_t, Encoder<float>>
357 {
358 public:
359  QSymmS8Encoder(int8_t* data, const float scale, const int32_t offset)
360  : TypedIterator(data), m_Scale(scale), m_Offset(offset) {}
361 
362  QSymmS8Encoder(const float scale, const int32_t offset)
363  : QSymmS8Encoder(nullptr, scale, offset) {}
364 
365  void Set(float right) override
366  {
367  *m_Iterator = armnn::Quantize<int8_t>(right, m_Scale, m_Offset);
368  }
369 
370  float Get() const override
371  {
372  return armnn::Dequantize(*m_Iterator, m_Scale, m_Offset);
373  }
374 
375 private:
376  const float m_Scale;
377  const int32_t m_Offset;
378 };
379 
380 class QSymm16Encoder : public TypedIterator<int16_t, Encoder<float>>
381 {
382 public:
383  QSymm16Encoder(int16_t* data, const float scale, const int32_t offset)
384  : TypedIterator(data), m_Scale(scale), m_Offset(offset) {}
385 
386  QSymm16Encoder(const float scale, const int32_t offset)
387  : QSymm16Encoder(nullptr, scale, offset) {}
388 
389  void Set(float right) override
390  {
391  *m_Iterator = armnn::Quantize<int16_t>(right, m_Scale, m_Offset);
392  }
393 
394  float Get() const override
395  {
396  return armnn::Dequantize(*m_Iterator, m_Scale, m_Offset);
397  }
398 
399 private:
400  const float m_Scale;
401  const int32_t m_Offset;
402 };
403 
404 class BFloat16Encoder : public TypedIterator<armnn::BFloat16, Encoder<float>>
405 {
406 public:
408  : TypedIterator(data) {}
409 
411  : BFloat16Encoder(nullptr) {}
412 
413  void Set(float right) override
414  {
416  }
417 
418  float Get() const override
419  {
420  float val = 0.f;
422  return val;
423  }
424 };
425 
426 class Float16Encoder : public TypedIterator<Half, Encoder<float>>
427 {
428 public:
430  : TypedIterator(data) {}
431 
433  : Float16Encoder(nullptr) {}
434 
435  void Set(float right) override
436  {
438  }
439 
440  float Get() const override
441  {
442  float val = 0.f;
444  return val;
445  }
446 };
447 
448 class Float32Encoder : public TypedIterator<float, Encoder<float>>
449 {
450 public:
451  Float32Encoder(float* data)
452  : TypedIterator(data) {}
453 
455  : Float32Encoder(nullptr) {}
456 
457  void Set(float right) override
458  {
459  *m_Iterator = right;
460  }
461 
462  float Get() const override
463  {
464  return *m_Iterator;
465  }
466 };
467 
468 class Int32Encoder : public TypedIterator<int32_t, Encoder<float>>
469 {
470 public:
471  Int32Encoder(int32_t* data)
472  : TypedIterator(data) {}
473 
475  : Int32Encoder(nullptr) {}
476 
477  void Set(float right) override
478  {
479  *m_Iterator = static_cast<int32_t>(right);
480  }
481 
482  float Get() const override
483  {
484  return static_cast<float>(*m_Iterator);
485  }
486 };
487 
488 class Int32ToInt32tEncoder : public TypedIterator<int32_t, Encoder<int32_t>>
489 {
490 public:
491  Int32ToInt32tEncoder(int32_t* data)
492  : TypedIterator(data){}
493 
495  : Int32ToInt32tEncoder(nullptr) {}
496 
497  void Set(int32_t right) override
498  {
499  *m_Iterator = right;
500  }
501 
502  int32_t Get() const override
503  {
504  return *m_Iterator;
505  }
506 };
507 
508 class BooleanEncoder : public TypedIterator<uint8_t, Encoder<bool>>
509 {
510 public:
511  BooleanEncoder(uint8_t* data)
512  : TypedIterator(data) {}
513 
515  : BooleanEncoder(nullptr) {}
516 
517  void Set(bool right) override
518  {
519  *m_Iterator = right;
520  }
521 
522  bool Get() const override
523  {
524  return *m_Iterator;
525  }
526 };
527 
528 // PerAxisIterator for per-axis quantization
529 template<typename T, typename Base>
530 class PerAxisIterator : public Base
531 {
532 public:
533  // axisFactor is used to calculate axisIndex
534  PerAxisIterator(T* data = nullptr, unsigned int axisFactor = 0)
535  : m_Iterator(data), m_Start(data), m_AxisIndex(0), m_AxisFactor(axisFactor)
536  {}
537 
538  // This should be called to set index for per-axis Encoder/Decoder
539  PerAxisIterator& SetIndex(unsigned int index, unsigned int axisIndex) override
540  {
541  ARMNN_ASSERT(m_Iterator);
542  m_Iterator = m_Start + index;
543  m_AxisIndex = axisIndex;
544  return *this;
545  }
546 
547  void Reset(void* data) override
548  {
549  m_Iterator = reinterpret_cast<T*>(data);
550  m_Start = m_Iterator;
551  m_AxisIndex = 0;
552  }
553 
555  {
556  ARMNN_ASSERT(m_Iterator);
557  ++m_Iterator;
558  m_AxisIndex = static_cast<unsigned int>(*m_Iterator) % m_AxisFactor;
559  return *this;
560  }
561 
562  PerAxisIterator& operator+=(const unsigned int increment) override
563  {
564  ARMNN_ASSERT(m_Iterator);
565  m_Iterator += increment;
566  m_AxisIndex = static_cast<unsigned int>(*m_Iterator) % m_AxisFactor;
567  return *this;
568  }
569 
570  PerAxisIterator& operator-=(const unsigned int decrement) override
571  {
572  ARMNN_ASSERT(m_Iterator);
573  m_Iterator -= decrement;
574  m_AxisIndex = static_cast<unsigned int>(*m_Iterator) % m_AxisFactor;
575  return *this;
576  }
577 
578  PerAxisIterator& operator[](const unsigned int index) override
579  {
580  ARMNN_ASSERT(m_Iterator);
581  m_Iterator = m_Start + index;
582  m_AxisIndex = static_cast<unsigned int>(*m_Iterator) % m_AxisFactor;
583  return *this;
584  }
585 
586  protected:
589  unsigned int m_AxisIndex;
590  unsigned int m_AxisFactor;
591 };
592 
593 class QSymm8PerAxisDecoder : public PerAxisIterator<const int8_t, Decoder<float>>
594 {
595 public:
596  QSymm8PerAxisDecoder(const int8_t* data, const std::vector<float>& scale, unsigned int axisFactor)
597  : PerAxisIterator(data, axisFactor), m_Scale(scale) {}
598 
599  float Get() const override
600  {
601  return armnn::Dequantize(*m_Iterator, m_Scale[m_AxisIndex], 0);
602  }
603 
604  // Get scale of the current value
605  float GetScale() const
606  {
607  return m_Scale[m_AxisIndex];
608  }
609 
610 private:
611  std::vector<float> m_Scale;
612 };
613 
614 class QSymm8PerAxisEncoder : public PerAxisIterator<int8_t, Encoder<float>>
615 {
616 public:
617  QSymm8PerAxisEncoder(int8_t* data, const std::vector<float>& scale, unsigned int axisFactor)
618  : PerAxisIterator(data, axisFactor), m_Scale(scale) {}
619 
620  void Set(float right)
621  {
622  *m_Iterator = armnn::Quantize<int8_t>(right, m_Scale[m_AxisIndex], 0);
623  }
624 
625  float Get() const
626  {
627  return armnn::Dequantize(*m_Iterator, m_Scale[m_AxisIndex], 0);
628  }
629 
630  // Get scale of the current value
631  float GetScale() const
632  {
633  return m_Scale[m_AxisIndex];
634  }
635 
636 private:
637  std::vector<float> m_Scale;
638 };
639 
640 class ScaledInt32PerAxisDecoder : public PerAxisIterator<const int32_t, Decoder<float>>
641 {
642 public:
643  ScaledInt32PerAxisDecoder(const int32_t* data, const std::vector<float>& scales, unsigned int axisFactor)
644  : PerAxisIterator(data, axisFactor), m_Scales(scales) {}
645 
646  float Get() const override
647  {
648  return armnn::Dequantize(*m_Iterator, m_Scales[m_AxisIndex], 0);
649  }
650 
651  // Get scale of the current value
652  float GetScale() const
653  {
654  return m_Scales[m_AxisIndex];
655  }
656 
657 private:
658  std::vector<float> m_Scales;
659 };
660 
661 } // namespace armnn
PerAxisIterator & operator++() override
Float32Decoder(const float *data)
QSymm8PerAxisDecoder(const int8_t *data, const std::vector< float > &scale, unsigned int axisFactor)
void Set(float right) override
ScaledInt32Decoder(const float scale)
void Set(int32_t right) override
BFloat16Decoder(const BFloat16 *data)
PerAxisIterator(T *data=nullptr, unsigned int axisFactor=0)
virtual BaseIterator & operator-=(const unsigned int increment)=0
float Get() const override
PerAxisIterator & operator[](const unsigned int index) override
QSymmS8Decoder(const float scale, const int32_t offset)
float Get() const override
QSymm16Encoder(const float scale, const int32_t offset)
static void ConvertBFloat16ToFloat32(const void *srcBFloat16Buffer, size_t numElements, float *dstFloat32Buffer)
void Reset(void *data) override
Int32ToInt32tEncoder(int32_t *data)
void Set(float right) override
ScaledInt32Decoder(const int32_t *data, const float scale)
int32_t Get() const override
QSymm16Decoder(const int16_t *data, const float scale, const int32_t offset)
void Set(bool right) override
float Get() const override
QSymmS8Encoder(int8_t *data, const float scale, const int32_t offset)
ScaledInt32PerAxisDecoder(const int32_t *data, const std::vector< float > &scales, unsigned int axisFactor)
float Get() const override
BFloat16Encoder(armnn::BFloat16 *data)
void Set(float right) override
QSymmS8Decoder(const int8_t *data, const float scale, const int32_t offset)
Copyright (c) 2020 ARM Limited.
void IgnoreUnused(Ts &&...)
float Get() const override
void Set(float right) override
float Get() const override
float Get() const override
QASymmS8Decoder(const int8_t *data, const float scale, const int32_t offset)
float Get() const override
Int32Decoder(const int32_t *data)
float Get() const override
virtual BaseIterator & operator[](const unsigned int index)=0
TypedIterator & operator[](const unsigned int index) override
QASymmS8Decoder(const float scale, const int32_t offset)
QASymm8Encoder(const float scale, const int32_t offset)
static void ConvertFloat32To16(const float *srcFloat32Buffer, size_t numElements, void *dstFloat16Buffer)
Converts a buffer of FP32 values to FP16, and stores in the given dstFloat16Buffer.
float Get() const override
QSymmS8Encoder(const float scale, const int32_t offset)
Int32Encoder(int32_t *data)
void Set(float right) override
void Reset(void *data) override
virtual ~Decoder()
virtual BaseIterator & operator++()=0
#define ARMNN_ASSERT(COND)
Definition: Assert.hpp:14
float Get() const override
QASymm8Encoder(uint8_t *data, const float scale, const int32_t offset)
float Get() const override
static void ConvertFloat16To32(const void *srcFloat16Buffer, size_t numElements, float *dstFloat32Buffer)
int32_t Get() const override
BooleanEncoder(uint8_t *data)
float Get() const override
float Get() const override
float Get() const override
Float16Encoder(Half *data)
QSymm8PerAxisEncoder(int8_t *data, const std::vector< float > &scale, unsigned int axisFactor)
QASymm8Decoder(const float scale, const int32_t offset)
Int32ToInt32tDecoder(const int32_t *data)
TypedIterator & operator++() override
Float16Decoder(const Half *data)
virtual BaseIterator & SetIndex(unsigned int index, unsigned int axisIndex=0)=0
float Get() const override
float Get() const override
PerAxisIterator & SetIndex(unsigned int index, unsigned int axisIndex) override
QASymmS8Encoder(const float scale, const int32_t offset)
PerAxisIterator & operator-=(const unsigned int decrement) override
virtual BaseIterator & operator+=(const unsigned int increment)=0
static void ConvertFloat32ToBFloat16(const float *srcFloat32Buffer, size_t numElements, void *dstBFloat16Buffer)
void Set(float right) override
QSymm16Decoder(const float scale, const int32_t offset)
Float32Encoder(float *data)
float Get() const override
QASymm8Decoder(const uint8_t *data, const float scale, const int32_t offset)
TypedIterator & operator+=(const unsigned int increment) override
virtual ~Encoder()
float Get() const override
QSymm16Encoder(int16_t *data, const float scale, const int32_t offset)
PerAxisIterator & operator+=(const unsigned int increment) override
void Set(float right) override
half_float::half Half
Definition: Half.hpp:16
QASymmS8Encoder(int8_t *data, const float scale, const int32_t offset)
BooleanDecoder(const uint8_t *data)
TypedIterator & SetIndex(unsigned int index, unsigned int axisIndex=0) override
TypedIterator & operator-=(const unsigned int increment) override
TypedIterator(T *data=nullptr)
void Set(float right) override
bool Get() const override
float Get() const override