ArmNN
 20.05
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 BooleanDecoder : public TypedIterator<const uint8_t, Decoder<float>>
278 {
279 public:
280  BooleanDecoder(const uint8_t* data)
281  : TypedIterator(data) {}
282 
284  : BooleanDecoder(nullptr) {}
285 
286  float Get() const override
287  {
288  return *m_Iterator;
289  }
290 
291 };
292 
293 class QASymm8Encoder : public TypedIterator<uint8_t, Encoder<float>>
294 {
295 public:
296  QASymm8Encoder(uint8_t* data, const float scale, const int32_t offset)
297  : TypedIterator(data), m_Scale(scale), m_Offset(offset) {}
298 
299  QASymm8Encoder(const float scale, const int32_t offset)
300  : QASymm8Encoder(nullptr, scale, offset) {}
301 
302  void Set(float right) override
303  {
304  *m_Iterator = armnn::Quantize<uint8_t>(right, m_Scale, m_Offset);
305  }
306 
307  float Get() const override
308  {
309  return armnn::Dequantize(*m_Iterator, m_Scale, m_Offset);
310  }
311 
312 private:
313  const float m_Scale;
314  const int32_t m_Offset;
315 };
316 
317 class QASymmS8Encoder : public TypedIterator<int8_t, Encoder<float>>
318 {
319 public:
320  QASymmS8Encoder(int8_t* data, const float scale, const int32_t offset)
321  : TypedIterator(data), m_Scale(scale), m_Offset(offset) {}
322 
323  QASymmS8Encoder(const float scale, const int32_t offset)
324  : QASymmS8Encoder(nullptr, scale, offset) {}
325 
326  void Set(float right) override
327  {
328  *m_Iterator = armnn::Quantize<int8_t>(right, m_Scale, m_Offset);
329  }
330 
331  float Get() const override
332  {
333  return armnn::Dequantize(*m_Iterator, m_Scale, m_Offset);
334  }
335 
336 private:
337  const float m_Scale;
338  const int32_t m_Offset;
339 };
340 
341 class QSymmS8Encoder : public TypedIterator<int8_t, Encoder<float>>
342 {
343 public:
344  QSymmS8Encoder(int8_t* data, const float scale, const int32_t offset)
345  : TypedIterator(data), m_Scale(scale), m_Offset(offset) {}
346 
347  QSymmS8Encoder(const float scale, const int32_t offset)
348  : QSymmS8Encoder(nullptr, scale, offset) {}
349 
350  void Set(float right) override
351  {
352  *m_Iterator = armnn::Quantize<int8_t>(right, m_Scale, m_Offset);
353  }
354 
355  float Get() const override
356  {
357  return armnn::Dequantize(*m_Iterator, m_Scale, m_Offset);
358  }
359 
360 private:
361  const float m_Scale;
362  const int32_t m_Offset;
363 };
364 
365 class QSymm16Encoder : public TypedIterator<int16_t, Encoder<float>>
366 {
367 public:
368  QSymm16Encoder(int16_t* data, const float scale, const int32_t offset)
369  : TypedIterator(data), m_Scale(scale), m_Offset(offset) {}
370 
371  QSymm16Encoder(const float scale, const int32_t offset)
372  : QSymm16Encoder(nullptr, scale, offset) {}
373 
374  void Set(float right) override
375  {
376  *m_Iterator = armnn::Quantize<int16_t>(right, m_Scale, m_Offset);
377  }
378 
379  float Get() const override
380  {
381  return armnn::Dequantize(*m_Iterator, m_Scale, m_Offset);
382  }
383 
384 private:
385  const float m_Scale;
386  const int32_t m_Offset;
387 };
388 
389 class BFloat16Encoder : public TypedIterator<armnn::BFloat16, Encoder<float>>
390 {
391 public:
393  : TypedIterator(data) {}
394 
396  : BFloat16Encoder(nullptr) {}
397 
398  void Set(float right) override
399  {
401  }
402 
403  float Get() const override
404  {
405  float val = 0.f;
407  return val;
408  }
409 };
410 
411 class Float16Encoder : public TypedIterator<Half, Encoder<float>>
412 {
413 public:
415  : TypedIterator(data) {}
416 
418  : Float16Encoder(nullptr) {}
419 
420  void Set(float right) override
421  {
423  }
424 
425  float Get() const override
426  {
427  float val = 0.f;
429  return val;
430  }
431 };
432 
433 class Float32Encoder : public TypedIterator<float, Encoder<float>>
434 {
435 public:
436  Float32Encoder(float* data)
437  : TypedIterator(data) {}
438 
440  : Float32Encoder(nullptr) {}
441 
442  void Set(float right) override
443  {
444  *m_Iterator = right;
445  }
446 
447  float Get() const override
448  {
449  return *m_Iterator;
450  }
451 };
452 
453 class Int32Encoder : public TypedIterator<int32_t, Encoder<float>>
454 {
455 public:
456  Int32Encoder(int32_t* data)
457  : TypedIterator(data) {}
458 
460  : Int32Encoder(nullptr) {}
461 
462  void Set(float right) override
463  {
464  *m_Iterator = static_cast<int32_t>(right);
465  }
466 
467  float Get() const override
468  {
469  return static_cast<float>(*m_Iterator);
470  }
471 };
472 
473 class BooleanEncoder : public TypedIterator<uint8_t, Encoder<bool>>
474 {
475 public:
476  BooleanEncoder(uint8_t* data)
477  : TypedIterator(data) {}
478 
480  : BooleanEncoder(nullptr) {}
481 
482  void Set(bool right) override
483  {
484  *m_Iterator = right;
485  }
486 
487  bool Get() const override
488  {
489  return *m_Iterator;
490  }
491 };
492 
493 // PerAxisIterator for per-axis quantization
494 template<typename T, typename Base>
495 class PerAxisIterator : public Base
496 {
497 public:
498  // axisFactor is used to calculate axisIndex
499  PerAxisIterator(T* data = nullptr, unsigned int axisFactor = 0)
500  : m_Iterator(data), m_Start(data), m_AxisIndex(0), m_AxisFactor(axisFactor)
501  {}
502 
503  // This should be called to set index for per-axis Encoder/Decoder
504  PerAxisIterator& SetIndex(unsigned int index, unsigned int axisIndex) override
505  {
506  ARMNN_ASSERT(m_Iterator);
507  m_Iterator = m_Start + index;
508  m_AxisIndex = axisIndex;
509  return *this;
510  }
511 
512  void Reset(void* data) override
513  {
514  m_Iterator = reinterpret_cast<T*>(data);
515  m_Start = m_Iterator;
516  m_AxisIndex = 0;
517  }
518 
520  {
521  ARMNN_ASSERT(m_Iterator);
522  ++m_Iterator;
523  m_AxisIndex = static_cast<unsigned int>(*m_Iterator) % m_AxisFactor;
524  return *this;
525  }
526 
527  PerAxisIterator& operator+=(const unsigned int increment) override
528  {
529  ARMNN_ASSERT(m_Iterator);
530  m_Iterator += increment;
531  m_AxisIndex = static_cast<unsigned int>(*m_Iterator) % m_AxisFactor;
532  return *this;
533  }
534 
535  PerAxisIterator& operator-=(const unsigned int decrement) override
536  {
537  ARMNN_ASSERT(m_Iterator);
538  m_Iterator -= decrement;
539  m_AxisIndex = static_cast<unsigned int>(*m_Iterator) % m_AxisFactor;
540  return *this;
541  }
542 
543  PerAxisIterator& operator[](const unsigned int index) override
544  {
545  ARMNN_ASSERT(m_Iterator);
546  m_Iterator = m_Start + index;
547  m_AxisIndex = static_cast<unsigned int>(*m_Iterator) % m_AxisFactor;
548  return *this;
549  }
550 
551  protected:
554  unsigned int m_AxisIndex;
555  unsigned int m_AxisFactor;
556 };
557 
558 class QSymm8PerAxisDecoder : public PerAxisIterator<const int8_t, Decoder<float>>
559 {
560 public:
561  QSymm8PerAxisDecoder(const int8_t* data, const std::vector<float>& scale, unsigned int axisFactor)
562  : PerAxisIterator(data, axisFactor), m_Scale(scale) {}
563 
564  float Get() const override
565  {
566  return armnn::Dequantize(*m_Iterator, m_Scale[m_AxisIndex], 0);
567  }
568 
569  // Get scale of the current value
570  float GetScale() const
571  {
572  return m_Scale[m_AxisIndex];
573  }
574 
575 private:
576  std::vector<float> m_Scale;
577 };
578 
579 class QSymm8PerAxisEncoder : public PerAxisIterator<int8_t, Encoder<float>>
580 {
581 public:
582  QSymm8PerAxisEncoder(int8_t* data, const std::vector<float>& scale, unsigned int axisFactor)
583  : PerAxisIterator(data, axisFactor), m_Scale(scale) {}
584 
585  void Set(float right)
586  {
587  *m_Iterator = armnn::Quantize<int8_t>(right, m_Scale[m_AxisIndex], 0);
588  }
589 
590  float Get() const
591  {
592  return armnn::Dequantize(*m_Iterator, m_Scale[m_AxisIndex], 0);
593  }
594 
595  // Get scale of the current value
596  float GetScale() const
597  {
598  return m_Scale[m_AxisIndex];
599  }
600 
601 private:
602  std::vector<float> m_Scale;
603 };
604 
605 class ScaledInt32PerAxisDecoder : public PerAxisIterator<const int32_t, Decoder<float>>
606 {
607 public:
608  ScaledInt32PerAxisDecoder(const int32_t* data, const std::vector<float>& scales, unsigned int axisFactor)
609  : PerAxisIterator(data, axisFactor), m_Scales(scales) {}
610 
611  float Get() const override
612  {
613  return armnn::Dequantize(*m_Iterator, m_Scales[m_AxisIndex], 0);
614  }
615 
616  // Get scale of the current value
617  float GetScale() const
618  {
619  return m_Scales[m_AxisIndex];
620  }
621 
622 private:
623  std::vector<float> m_Scales;
624 };
625 
626 } // 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)
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
void Set(float right) override
ScaledInt32Decoder(const int32_t *data, const float scale)
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)
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)
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