ArmNN  NotReleased
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 
9 #include <armnn/TypesUtils.hpp>
11 
12 #include <ResolveType.hpp>
13 
14 #include <boost/assert.hpp>
15 #include <boost/core/ignore_unused.hpp>
16 
17 namespace armnn
18 {
19 
21 {
22 public:
24 
25  virtual ~BaseIterator() {}
26 
27  virtual BaseIterator& SetIndex(unsigned int index, unsigned int axisIndex = 0) = 0;
28 
29  virtual BaseIterator& operator++() = 0;
30 
31  virtual BaseIterator& operator+=(const unsigned int increment) = 0;
32 
33  virtual BaseIterator& operator-=(const unsigned int increment) = 0;
34 
35  virtual BaseIterator& operator[](const unsigned int index) = 0;
36 };
37 
38 template<typename IType>
39 class Decoder : public BaseIterator
40 {
41 public:
42  Decoder() {}
43 
44  virtual ~Decoder() {}
45 
46  virtual void Reset(void*) = 0;
47 
48  virtual IType Get() const = 0;
49 };
50 
51 template<typename IType>
52 class Encoder : public BaseIterator
53 {
54 public:
55  Encoder() {}
56 
57  virtual ~Encoder() {}
58 
59  virtual void Reset(void*) = 0;
60 
61  virtual void Set(IType right) = 0;
62 
63  virtual IType Get() const = 0;
64 };
65 
66 template<typename T, typename Base>
67 class TypedIterator : public Base
68 {
69 public:
70  TypedIterator(T* data = nullptr)
71  : m_Iterator(data), m_Start(data)
72  {}
73 
74  void Reset(void* data) override
75  {
76  m_Iterator = reinterpret_cast<T*>(data);
77  m_Start = m_Iterator;
78  }
79 
81  {
82  BOOST_ASSERT(m_Iterator);
83  ++m_Iterator;
84  return *this;
85  }
86 
87  TypedIterator& operator+=(const unsigned int increment) override
88  {
89  BOOST_ASSERT(m_Iterator);
90  m_Iterator += increment;
91  return *this;
92  }
93 
94  TypedIterator& operator-=(const unsigned int increment) override
95  {
96  BOOST_ASSERT(m_Iterator);
97  m_Iterator -= increment;
98  return *this;
99  }
100 
101  TypedIterator& operator[](const unsigned int index) override
102  {
103  BOOST_ASSERT(m_Iterator);
104  m_Iterator = m_Start + index;
105  return *this;
106  }
107 
108  TypedIterator& SetIndex(unsigned int index, unsigned int axisIndex = 0) override
109  {
110  boost::ignore_unused(axisIndex);
111  BOOST_ASSERT(m_Iterator);
112  m_Iterator = m_Start + index;
113  return *this;
114  }
115 
116 protected:
119 };
120 
121 class QASymm8Decoder : public TypedIterator<const uint8_t, Decoder<float>>
122 {
123 public:
124  QASymm8Decoder(const uint8_t* data, const float scale, const int32_t offset)
125  : TypedIterator(data), m_Scale(scale), m_Offset(offset) {}
126 
127  QASymm8Decoder(const float scale, const int32_t offset)
128  : QASymm8Decoder(nullptr, scale, offset) {}
129 
130  float Get() const override
131  {
132  return armnn::Dequantize(*m_Iterator, m_Scale, m_Offset);
133  }
134 
135 private:
136  const float m_Scale;
137  const int32_t m_Offset;
138 };
139 
140 class QASymmS8Decoder : public TypedIterator<const int8_t, Decoder<float>>
141 {
142 public:
143  QASymmS8Decoder(const int8_t* data, const float scale, const int32_t offset)
144  : TypedIterator(data), m_Scale(scale), m_Offset(offset) {}
145 
146  QASymmS8Decoder(const float scale, const int32_t offset)
147  : QASymmS8Decoder(nullptr, scale, offset) {}
148 
149  float Get() const override
150  {
151  return armnn::Dequantize(*m_Iterator, m_Scale, m_Offset);
152  }
153 
154 private:
155  const float m_Scale;
156  const int32_t m_Offset;
157 };
158 
159 class QSymmS8Decoder : public TypedIterator<const int8_t, Decoder<float>>
160 {
161 public:
162  QSymmS8Decoder(const int8_t* data, const float scale, const int32_t offset)
163  : TypedIterator(data), m_Scale(scale), m_Offset(offset) {}
164 
165  QSymmS8Decoder(const float scale, const int32_t offset)
166  : QSymmS8Decoder(nullptr, scale, offset) {}
167 
168  float Get() const override
169  {
170  return armnn::Dequantize(*m_Iterator, m_Scale, m_Offset);
171  }
172 
173 private:
174  const float m_Scale;
175  const int32_t m_Offset;
176 };
177 
178 class QSymm16Decoder : public TypedIterator<const int16_t, Decoder<float>>
179 {
180 public:
181  QSymm16Decoder(const int16_t* data, const float scale, const int32_t offset)
182  : TypedIterator(data), m_Scale(scale), m_Offset(offset) {}
183 
184  QSymm16Decoder(const float scale, const int32_t offset)
185  : QSymm16Decoder(nullptr, scale, offset) {}
186 
187  float Get() const override
188  {
189  return armnn::Dequantize(*m_Iterator, m_Scale, m_Offset);
190  }
191 
192 private:
193  const float m_Scale;
194  const int32_t m_Offset;
195 };
196 
197 class Float16Decoder : public TypedIterator<const Half, Decoder<float>>
198 {
199 public:
200  Float16Decoder(const Half* data)
201  : TypedIterator(data) {}
202 
204  : Float16Decoder(nullptr) {}
205 
206  float Get() const override
207  {
208  float val = 0.f;
210  return val;
211  }
212 };
213 
214 class Float32Decoder : public TypedIterator<const float, Decoder<float>>
215 {
216 public:
217  Float32Decoder(const float* data)
218  : TypedIterator(data) {}
219 
221  : Float32Decoder(nullptr) {}
222 
223  float Get() const override
224  {
225  return *m_Iterator;
226  }
227 };
228 
229 class ScaledInt32Decoder : public TypedIterator<const int32_t, Decoder<float>>
230 {
231 public:
232  ScaledInt32Decoder(const int32_t* data, const float scale)
233  : TypedIterator(data), m_Scale(scale) {}
234 
235  ScaledInt32Decoder(const float scale)
236  : ScaledInt32Decoder(nullptr, scale) {}
237 
238  float Get() const override
239  {
240  return static_cast<float>(*m_Iterator) * m_Scale;
241  }
242 
243 private:
244  const float m_Scale;
245 };
246 
247 class Int32Decoder : public TypedIterator<const int32_t, Decoder<float>>
248 {
249 public:
250  Int32Decoder(const int32_t* data)
251  : TypedIterator(data) {}
252 
254  : Int32Decoder(nullptr) {}
255 
256  float Get() const override
257  {
258  return static_cast<float>(*m_Iterator);
259  }
260 };
261 
262 class QASymm8Encoder : public TypedIterator<uint8_t, Encoder<float>>
263 {
264 public:
265  QASymm8Encoder(uint8_t* data, const float scale, const int32_t offset)
266  : TypedIterator(data), m_Scale(scale), m_Offset(offset) {}
267 
268  QASymm8Encoder(const float scale, const int32_t offset)
269  : QASymm8Encoder(nullptr, scale, offset) {}
270 
271  void Set(float right) override
272  {
273  *m_Iterator = armnn::Quantize<uint8_t>(right, m_Scale, m_Offset);
274  }
275 
276  float Get() const override
277  {
278  return armnn::Dequantize(*m_Iterator, m_Scale, m_Offset);
279  }
280 
281 private:
282  const float m_Scale;
283  const int32_t m_Offset;
284 };
285 
286 class QASymmS8Encoder : public TypedIterator<int8_t, Encoder<float>>
287 {
288 public:
289  QASymmS8Encoder(int8_t* data, const float scale, const int32_t offset)
290  : TypedIterator(data), m_Scale(scale), m_Offset(offset) {}
291 
292  QASymmS8Encoder(const float scale, const int32_t offset)
293  : QASymmS8Encoder(nullptr, scale, offset) {}
294 
295  void Set(float right) override
296  {
297  *m_Iterator = armnn::Quantize<int8_t>(right, m_Scale, m_Offset);
298  }
299 
300  float Get() const override
301  {
302  return armnn::Dequantize(*m_Iterator, m_Scale, m_Offset);
303  }
304 
305 private:
306  const float m_Scale;
307  const int32_t m_Offset;
308 };
309 
310 class QSymmS8Encoder : public TypedIterator<int8_t, Encoder<float>>
311 {
312 public:
313  QSymmS8Encoder(int8_t* data, const float scale, const int32_t offset)
314  : TypedIterator(data), m_Scale(scale), m_Offset(offset) {}
315 
316  QSymmS8Encoder(const float scale, const int32_t offset)
317  : QSymmS8Encoder(nullptr, scale, offset) {}
318 
319  void Set(float right) override
320  {
321  *m_Iterator = armnn::Quantize<int8_t>(right, m_Scale, m_Offset);
322  }
323 
324  float Get() const override
325  {
326  return armnn::Dequantize(*m_Iterator, m_Scale, m_Offset);
327  }
328 
329 private:
330  const float m_Scale;
331  const int32_t m_Offset;
332 };
333 
334 class QSymm16Encoder : public TypedIterator<int16_t, Encoder<float>>
335 {
336 public:
337  QSymm16Encoder(int16_t* data, const float scale, const int32_t offset)
338  : TypedIterator(data), m_Scale(scale), m_Offset(offset) {}
339 
340  QSymm16Encoder(const float scale, const int32_t offset)
341  : QSymm16Encoder(nullptr, scale, offset) {}
342 
343  void Set(float right) override
344  {
345  *m_Iterator = armnn::Quantize<int16_t>(right, m_Scale, m_Offset);
346  }
347 
348  float Get() const override
349  {
350  return armnn::Dequantize(*m_Iterator, m_Scale, m_Offset);
351  }
352 
353 private:
354  const float m_Scale;
355  const int32_t m_Offset;
356 };
357 
358 class Float16Encoder : public TypedIterator<Half, Encoder<float>>
359 {
360 public:
362  : TypedIterator(data) {}
363 
365  : Float16Encoder(nullptr) {}
366 
367  void Set(float right) override
368  {
370  }
371 
372  float Get() const override
373  {
374  float val = 0.f;
376  return val;
377  }
378 };
379 
380 class Float32Encoder : public TypedIterator<float, Encoder<float>>
381 {
382 public:
383  Float32Encoder(float* data)
384  : TypedIterator(data) {}
385 
387  : Float32Encoder(nullptr) {}
388 
389  void Set(float right) override
390  {
391  *m_Iterator = right;
392  }
393 
394  float Get() const override
395  {
396  return *m_Iterator;
397  }
398 };
399 
400 class Int32Encoder : public TypedIterator<int32_t, Encoder<float>>
401 {
402 public:
403  Int32Encoder(int32_t* data)
404  : TypedIterator(data) {}
405 
407  : Int32Encoder(nullptr) {}
408 
409  void Set(float right) override
410  {
411  *m_Iterator = static_cast<int32_t>(right);
412  }
413 
414  float Get() const override
415  {
416  return static_cast<float>(*m_Iterator);
417  }
418 };
419 
420 class BooleanEncoder : public TypedIterator<uint8_t, Encoder<bool>>
421 {
422 public:
423  BooleanEncoder(uint8_t* data)
424  : TypedIterator(data) {}
425 
427  : BooleanEncoder(nullptr) {}
428 
429  void Set(bool right) override
430  {
431  *m_Iterator = right;
432  }
433 
434  bool Get() const override
435  {
436  return *m_Iterator;
437  }
438 };
439 
440 // PerAxisIterator for per-axis quantization
441 template<typename T, typename Base>
442 class PerAxisIterator : public Base
443 {
444 public:
445  // axisFactor is used to calculate axisIndex
446  PerAxisIterator(T* data = nullptr, unsigned int axisFactor = 0)
447  : m_Iterator(data), m_Start(data), m_AxisIndex(0), m_AxisFactor(axisFactor)
448  {}
449 
450  // This should be called to set index for per-axis Encoder/Decoder
451  PerAxisIterator& SetIndex(unsigned int index, unsigned int axisIndex) override
452  {
453  BOOST_ASSERT(m_Iterator);
454  m_Iterator = m_Start + index;
455  m_AxisIndex = axisIndex;
456  return *this;
457  }
458 
459  void Reset(void* data) override
460  {
461  m_Iterator = reinterpret_cast<T*>(data);
462  m_Start = m_Iterator;
463  m_AxisIndex = 0;
464  }
465 
467  {
468  BOOST_ASSERT(m_Iterator);
469  ++m_Iterator;
470  m_AxisIndex = static_cast<unsigned int>(*m_Iterator) % m_AxisFactor;
471  return *this;
472  }
473 
474  PerAxisIterator& operator+=(const unsigned int increment) override
475  {
476  BOOST_ASSERT(m_Iterator);
477  m_Iterator += increment;
478  m_AxisIndex = static_cast<unsigned int>(*m_Iterator) % m_AxisFactor;
479  return *this;
480  }
481 
482  PerAxisIterator& operator-=(const unsigned int decrement) override
483  {
484  BOOST_ASSERT(m_Iterator);
485  m_Iterator -= decrement;
486  m_AxisIndex = static_cast<unsigned int>(*m_Iterator) % m_AxisFactor;
487  return *this;
488  }
489 
490  PerAxisIterator& operator[](const unsigned int index) override
491  {
492  BOOST_ASSERT(m_Iterator);
493  m_Iterator = m_Start + index;
494  m_AxisIndex = static_cast<unsigned int>(*m_Iterator) % m_AxisFactor;
495  return *this;
496  }
497 
498  protected:
501  unsigned int m_AxisIndex;
502  unsigned int m_AxisFactor;
503 };
504 
505 class QSymm8PerAxisDecoder : public PerAxisIterator<const int8_t, Decoder<float>>
506 {
507 public:
508  QSymm8PerAxisDecoder(const int8_t* data, const std::vector<float>& scale, unsigned int axisFactor)
509  : PerAxisIterator(data, axisFactor), m_Scale(scale) {}
510 
511  float Get() const override
512  {
513  return armnn::Dequantize(*m_Iterator, m_Scale[m_AxisIndex], 0);
514  }
515 
516  // Get scale of the current value
517  float GetScale() const
518  {
519  return m_Scale[m_AxisIndex];
520  }
521 
522 private:
523  std::vector<float> m_Scale;
524 };
525 
526 class QSymm8PerAxisEncoder : public PerAxisIterator<int8_t, Encoder<float>>
527 {
528 public:
529  QSymm8PerAxisEncoder(int8_t* data, const std::vector<float>& scale, unsigned int axisFactor)
530  : PerAxisIterator(data, axisFactor), m_Scale(scale) {}
531 
532  void Set(float right)
533  {
534  *m_Iterator = armnn::Quantize<int8_t>(right, m_Scale[m_AxisIndex], 0);
535  }
536 
537  float Get() const
538  {
539  return armnn::Dequantize(*m_Iterator, m_Scale[m_AxisIndex], 0);
540  }
541 
542  // Get scale of the current value
543  float GetScale() const
544  {
545  return m_Scale[m_AxisIndex];
546  }
547 
548 private:
549  std::vector<float> m_Scale;
550 };
551 
552 class ScaledInt32PerAxisDecoder : public PerAxisIterator<const int32_t, Decoder<float>>
553 {
554 public:
555  ScaledInt32PerAxisDecoder(const int32_t* data, const std::vector<float>& scales, unsigned int axisFactor)
556  : PerAxisIterator(data, axisFactor), m_Scales(scales) {}
557 
558  float Get() const override
559  {
560  return armnn::Dequantize(*m_Iterator, m_Scales[m_AxisIndex], 0);
561  }
562 
563  // Get scale of the current value
564  float GetScale() const
565  {
566  return m_Scales[m_AxisIndex];
567  }
568 
569 private:
570  std::vector<float> m_Scales;
571 };
572 
573 } // namespace armnn
PerAxisIterator & operator+=(const unsigned int increment) override
QASymmS8Decoder(const float scale, const int32_t offset)
BooleanEncoder(uint8_t *data)
float Get() const override
void Set(float right) override
QSymmS8Decoder(const float scale, const int32_t offset)
half_float::half Half
Definition: Half.hpp:16
QASymmS8Decoder(const int8_t *data, const float scale, const int32_t offset)
Float32Encoder(float *data)
ScaledInt32Decoder(const float scale)
QASymm8Encoder(const float scale, const int32_t offset)
void Reset(void *data) override
Float32Decoder(const float *data)
TypedIterator & operator[](const unsigned int index) override
TypedIterator & SetIndex(unsigned int index, unsigned int axisIndex=0) override
virtual BaseIterator & operator++()=0
PerAxisIterator & SetIndex(unsigned int index, unsigned int axisIndex) override
void Set(float right) override
void Set(float right) override
virtual ~Decoder()
void Set(float right) override
float Get() const override
float Get() const override
float Get() const override
float Get() const override
void Set(bool right) override
QSymm16Decoder(const float scale, const int32_t offset)
QSymm8PerAxisEncoder(int8_t *data, const std::vector< float > &scale, unsigned int axisFactor)
QASymmS8Encoder(const float scale, const int32_t offset)
TypedIterator(T *data=nullptr)
bool Get() const override
QASymm8Encoder(uint8_t *data, const float scale, const int32_t offset)
static void ConvertFloat16To32(const void *srcFloat16Buffer, size_t numElements, float *dstFloat32Buffer)
virtual BaseIterator & SetIndex(unsigned int index, unsigned int axisIndex=0)=0
QASymm8Decoder(const float scale, const int32_t offset)
TypedIterator & operator-=(const unsigned int increment) override
float Get() const override
static void ConvertFloat32To16(const float *srcFloat32Buffer, size_t numElements, void *dstFloat16Buffer)
QSymmS8Encoder(int8_t *data, const float scale, const int32_t offset)
float Get() const override
void Set(float right) override
virtual ~Encoder()
virtual BaseIterator & operator+=(const unsigned int increment)=0
QSymm16Decoder(const int16_t *data, const float scale, const int32_t offset)
PerAxisIterator & operator++() override
void Set(float right) override
Float16Decoder(const Half *data)
ScaledInt32PerAxisDecoder(const int32_t *data, const std::vector< float > &scales, unsigned int axisFactor)
QSymm8PerAxisDecoder(const int8_t *data, const std::vector< float > &scale, unsigned int axisFactor)
QASymm8Decoder(const uint8_t *data, const float scale, const int32_t offset)
float Get() const override
void Reset(void *data) override
Float16Encoder(Half *data)
float Get() const override
float Get() const override
float Get() const override
QSymmS8Decoder(const int8_t *data, const float scale, const int32_t offset)
Int32Encoder(int32_t *data)
QSymmS8Encoder(const float scale, const int32_t offset)
TypedIterator & operator++() override
PerAxisIterator & operator[](const unsigned int index) override
PerAxisIterator & operator-=(const unsigned int decrement) override
float Get() const override
void Set(float right) override
virtual BaseIterator & operator[](const unsigned int index)=0
QSymm16Encoder(const float scale, const int32_t offset)
float Get() const override
float Get() const override
QASymmS8Encoder(int8_t *data, const float scale, const int32_t offset)
QSymm16Encoder(int16_t *data, const float scale, const int32_t offset)
float Get() const override
float Get() const override
Int32Decoder(const int32_t *data)
PerAxisIterator(T *data=nullptr, unsigned int axisFactor=0)
TypedIterator & operator+=(const unsigned int increment) override
virtual BaseIterator & operator-=(const unsigned int increment)=0
ScaledInt32Decoder(const int32_t *data, const float scale)
float Get() const override