ArmNN
 24.02
Tensor.hpp
Go to the documentation of this file.
1 //
2 // Copyright © 2017,2022-2024 Arm Ltd and Contributors. All rights reserved.
3 // SPDX-License-Identifier: MIT
4 //
5 #pragma once
6 
7 #include "Exceptions.hpp"
8 #include "Optional.hpp"
9 #include "Types.hpp"
10 
11 #include <stdint.h>
12 #include <array>
13 #include <initializer_list>
14 #include <vector>
15 #include <utility>
16 
17 namespace armnn
18 {
19 
21 {
22 public:
23  /// Empty (invalid) constructor.
24  TensorShape();
25 
26  /// Constructor for TensorShape
27  /// @param numDimensions - Tensor rank.
28  /// @param initDimensionsSpecificity (optional) - value to initialize the specificity of each dimension size.
29  explicit TensorShape(unsigned int numDimensions, bool initDimensionsSpecificity = true);
30 
31  /// Constructor for TensorShape
32  /// @param numDimensions - Tensor rank.
33  /// @param dimensionSizes - Size of each of dimension.
34  TensorShape(unsigned int numDimensions, const unsigned int* dimensionSizes);
35 
36  /// Constructor for TensorShape
37  /// @param dimensionSizeList - Size of each of dimension.
38  TensorShape(std::initializer_list<unsigned int> dimensionSizeList);
39 
40  /// Copy Constructor for TensorShape
41  /// @param other - TensorShape to copy from.
42  TensorShape(const TensorShape& other);
43 
44  /// Constructor for TensorShape
45  /// @param numDimensions - Tensor rank.
46  /// @param dimensionSizes - Size of each of dimension.
47  /// @param dimensionsSpecificity - Flags to indicate which dimension has its size specified.
48  TensorShape(unsigned int numDimensions, const unsigned int* dimensionSizes, const bool* dimensionsSpecificity);
49 
50  /// Constructor for TensorShape
51  /// @param dimensionSizeList - Size of each of dimension.
52  /// @param dimensionsSpecificityList - Flags to indicate which dimension size is specified.
53  TensorShape(std::initializer_list<unsigned int> dimensionSizeList,
54  std::initializer_list<bool> dimensionsSpecificityList);
55 
56  /// Constructor for TensorShape
57  /// @param dimensionality - Parameter to indicate if the Tensor is a Scalar, a Tensor of known dimensionality
58  /// or a Tensor of unknown dimensionality.
59  explicit TensorShape(Dimensionality dimensionality);
60 
61  /// Assignation function
62  /// @param other - TensorShape to copy from.
63  TensorShape& operator=(const TensorShape& other);
64 
65  /// Read only operator
66  /// @param i - Dimension index.
67  unsigned int operator[](unsigned int i) const;
68 
69  /// Read and write operator
70  /// @param i - Dimension index.
71  unsigned int& operator[](unsigned int i);
72 
73  /// Equality comparison operator
74  /// @param other - TensorShape to compare with.
75  bool operator==(const TensorShape& other) const;
76 
77  /// Inequality comparison operator
78  /// @param other - TensorShape to compare with.
79  bool operator!=(const TensorShape& other) const;
80 
81  /// Function that returns the tensor rank.
82  /// @return - Tensor rank.
83  unsigned int GetNumDimensions() const;
84 
85  /// Function that calculates the tensor elements by multiplying all dimension size which are Specified.
86  /// @return - Total number of elements in the tensor.
87  unsigned int GetNumElements() const;
88 
89  /// Function that returns the tensor type.
90  /// @return - Parameter to indicate if the Tensor is a scalar, a Tensor of known dimensionality or
91  /// a Tensor of unknown dimensionality
92  Dimensionality GetDimensionality() const { return m_Dimensionality; }
93 
94  /// Gets information about if the dimension size has been specified or not
95  /// @param i - Dimension index.
96  /// @return - Flag to indicate if the dimension "i" has a specified size.
97  bool GetDimensionSpecificity(unsigned int i) const;
98 
99  /// Sets the tensor rank and therefore the Dimensionality is set to Specified if it was not.
100  /// @param numDimensions - Tensor rank.
101  /// @param initDimensionsSpecificity (optional) - value to initialize the specificity of each dimension size.
102  void SetNumDimensions(unsigned int numDimensions, bool initDimensionsSpecificity = false);
103 
104  /// Sets the size of the indicated dimension and Specificity for that dimension is set to true.
105  /// @param i - Dimension index.
106  /// @param dimensionSize - size of one dimension.
107  void SetDimensionSize(unsigned int i, unsigned int dimensionSize);
108 
109  /// Checks if there is at least one dimension not specified. AND of all array elements.
110  /// @return - True when all dimension sizes are specified. False when at least one dimension size is not specified.
111  bool AreAllDimensionsSpecified() const;
112 
113  /// Checks if there is at least one dimension specified. OR of all array elements.
114  /// @return - True at least one dimension sizes is specified. False when all dimension sizes are not specified.
115  bool IsAtLeastOneDimensionSpecified() const;
116 
117 private:
118  /// Array of the dimension sizes.
119  std::array<unsigned int, MaxNumOfTensorDimensions> m_Dimensions{};
120 
121  /// Array of flags to indicate if the size of each of the dimensions is specified or not
122  std::array<bool, MaxNumOfTensorDimensions> m_DimensionsSpecificity = { {true} };
123 
124  /// Tensor rank
125  unsigned int m_NumDimensions{};
126 
127  /// Tensor type: Specified, NotSpecified or Scalar.
128  Dimensionality m_Dimensionality = Dimensionality::Specified;
129 
130  /// Checks if the dimension index given is within range.
131  /// @param i - Dimension index.
132  void CheckDimensionIndex(unsigned int i) const;
133 
134  /// Checks if the tensor rank given is within range.
135  /// @param numDimensions - Tensor rank.
136  static void CheckValidNumDimensions(unsigned int numDimensions) ;
137 
138  /// Checks if the size of the dimension index given is specified.
139  /// @param i - Dimension index.
140  void CheckDimensionSpecified(unsigned int i) const;
141 
142  /// Checks if this is a scalar.
143  void CheckScalar() const;
144 
145  /// Checks if the number of dimensions is unknown, i.e. rank is unspecified.
146  void CheckUnspecifiedNumDimensions() const;
147 
148  /// Checks if the number of dimensions is known, i.e. rank is specified.
149  void CheckSpecifiedNumDimensions() const;
150 };
151 
153 {
154 public:
155  /// Empty (invalid) constructor.
156  TensorInfo();
157 
158  TensorInfo(const TensorShape& shape,
159  DataType dataType,
160  float quantizationScale = 1.0f,
161  int32_t quantizationOffset = 0,
162  bool isConstant = false);
163 
164  TensorInfo(unsigned int numDimensions,
165  const unsigned int* dimensionSizes,
166  DataType dataType,
167  float quantizationScale = 1.0f,
168  int32_t quantizationOffset = 0,
169  bool isConstant = false);
170 
171  TensorInfo(const TensorShape& shape,
172  DataType dataType,
173  const std::vector<float>& quantizationScales,
174  unsigned int quantizationDim,
175  bool isConstant = false);
176 
177  TensorInfo(unsigned int numDimensions,
178  const unsigned int* dimensionSizes,
179  DataType dataType,
180  const std::vector<float>& quantizationScales,
181  unsigned int quantizationDim,
182  bool isConstant = false);
183 
184  TensorInfo(const TensorInfo& other);
185 
186  TensorInfo& operator=(const TensorInfo& other);
187 
188  bool operator==(const TensorInfo& other) const;
189  bool operator!=(const TensorInfo& other) const;
190 
191  using DifferenceType = std::vector<TensorInfo>::difference_type;
192 
193  const TensorShape& GetShape() const { return m_Shape; }
194  TensorShape& GetShape() { return m_Shape; }
195  void SetShape(const TensorShape& newShape) { m_Shape = newShape; }
196 
197  unsigned int GetNumDimensions() const { return m_Shape.GetNumDimensions(); }
198  unsigned int GetNumElements() const { return m_Shape.GetNumElements(); }
199 
200  DataType GetDataType() const { return m_DataType; }
201  void SetDataType(DataType type) { m_DataType = type; }
202 
203  bool HasMultipleQuantizationScales() const { return m_Quantization.m_Scales.size() > 1; }
204 
205  bool HasPerAxisQuantization() const;
206 
207  std::vector<float> GetQuantizationScales() const;
208  void SetQuantizationScales(const std::vector<float>& scales);
209 
210  float GetQuantizationScale() const;
211  void SetQuantizationScale(float scale);
212 
213  int32_t GetQuantizationOffset() const;
214  void SetQuantizationOffset(int32_t offset);
215 
217  void SetQuantizationDim(const Optional<unsigned int>& quantizationDim);
218 
219  bool IsQuantized() const;
220 
221  bool IsConstant() const;
222 
223  /// Marks the data corresponding to this tensor info as constant.
224  ///
225  /// @details: This can allow further optimization on execution
226  /// @Note: The user has to ensure that the underlying data actually is constant.
227  void SetConstant(const bool IsConstant=true);
228 
229  /// Check that the types are the same and, if quantize, that the quantization parameters are the same.
230  bool IsTypeSpaceMatch(const TensorInfo& other) const;
231 
232  unsigned int GetNumBytes() const;
233 
234 private:
235  TensorShape m_Shape;
236  DataType m_DataType;
237  bool m_IsConstant;
238 
239  /// Vectors of scale and offset are used for per-axis quantization.
240  struct Quantization
241  {
242  Quantization()
243  : m_Scales{}
244  , m_Offset(EmptyOptional())
245  , m_QuantizationDim(EmptyOptional()) {}
246 
247  Quantization(const Quantization& other)
248  : m_Scales(other.m_Scales)
249  , m_Offset(other.m_Offset)
250  , m_QuantizationDim(other.m_QuantizationDim) {}
251 
252  bool operator==(const Quantization& other) const
253  {
254  return ((m_Scales == other.m_Scales) && (m_Offset == other.m_Offset) &&
255  (m_QuantizationDim == other.m_QuantizationDim));
256  }
257 
258  Quantization& operator=(const Quantization& other)
259  {
260  if(this != &other)
261  {
262  m_Scales = other.m_Scales;
263  m_Offset = other.m_Offset;
264  m_QuantizationDim = other.m_QuantizationDim;
265  }
266  return *this;
267  }
268 
269  std::vector<float> m_Scales;
270  Optional<int32_t> m_Offset;
271  Optional<unsigned int> m_QuantizationDim;
272 
273  } m_Quantization;
274 };
275 
276 using BindingPointInfo = std::pair<armnn::LayerBindingId, armnn::TensorInfo>;
277 
278 template<typename MemoryType>
280 {
281 public:
282  /// Empty (invalid) constructor.
283  BaseTensor();
284 
285  /// Constructor from a raw memory pointer.
286  /// @param memoryArea - Region of CPU-addressable memory where tensor data will be stored. Must be valid while
287  /// workloads are on the fly. Tensor instances do not claim ownership of referenced memory regions, that is,
288  /// no attempt will be made by ArmNN to free these memory regions automatically.
289  BaseTensor(const TensorInfo& info, MemoryType memoryArea);
290 
291  /// Tensors are copyable.
292  BaseTensor(const BaseTensor& other);
293 
294  /// Tensors are copyable.
296 
297  const TensorInfo& GetInfo() const { return m_Info; }
298  TensorInfo& GetInfo() { return m_Info; }
299  const TensorShape& GetShape() const { return m_Info.GetShape(); }
300  TensorShape& GetShape() { return m_Info.GetShape(); }
301 
302  DataType GetDataType() const { return m_Info.GetDataType(); }
303  unsigned int GetNumDimensions() const { return m_Info.GetNumDimensions(); }
304  unsigned int GetNumBytes() const { return m_Info.GetNumBytes(); }
305  unsigned int GetNumElements() const { return m_Info.GetNumElements(); }
306 
307  MemoryType GetMemoryArea() const { return m_MemoryArea; }
308 
309 protected:
310  /// Protected destructor to stop users from making these
311  /// (could still new one on the heap and then leak it...)
313 
314  MemoryType m_MemoryArea;
315 
316 private:
317  TensorInfo m_Info;
318 };
319 
320 /// A tensor defined by a TensorInfo (shape and data type) and a mutable backing store.
321 class Tensor : public BaseTensor<void*>
322 {
323 public:
324  /// Brings in the constructors and assignment operator.
326 };
327 
328 /// A tensor defined by a TensorInfo (shape and data type) and an immutable backing store.
329 class ConstTensor : public BaseTensor<const void*>
330 {
331 public:
332  /// Brings in the constructors and assignment operator.
334  ConstTensor() : BaseTensor<const void*>()
335  {
336  this->GetInfo().SetConstant();
337  }
338 
339  /// ConstTensor implicitly constructed from non-const Tensor.
340  ///
341  /// @param other - reference to a constant Tensor.
342  ///
343  /// @throws InvalidArgumentException when Tensor parameter TensorInfo is non-constant.
344  ConstTensor(const Tensor& other) : BaseTensor<const void*>(other.GetInfo(), other.GetMemoryArea())
345  {
346  if (!this->GetInfo().IsConstant())
347  {
348  throw InvalidArgumentException("Invalid attempt to construct ConstTensor "
349  "from Tensor due to non-constant TensorInfo");
350  }
351  }
352 
353  /// Constructor from a backing container.
354  ///
355  /// @param container - An stl-like container type which implements data() and size() methods.
356  /// Presence of data() and size() is a strong indicator of the continuous memory layout of the container,
357  /// which is a requirement for Tensor data. Tensor instances do not claim ownership of referenced memory regions,
358  /// that is, no attempt will be made by ArmNN to free these memory regions automatically.
359  ///
360  /// @throws InvalidArgumentException when isConstant parameter of input TensorInfo is false.
361  template < template<typename, typename...> class ContainerType, typename T, typename...ContainerArgs >
362  ConstTensor(const TensorInfo& info, const ContainerType<T, ContainerArgs...>& container)
363  : BaseTensor<const void*>(info, container.data())
364  {
365  if (!this->GetInfo().IsConstant())
366  {
367  throw InvalidArgumentException("Invalid attempt to construct ConstTensor from non-constant TensorInfo.");
368  }
369  if (container.size() * sizeof(T) != info.GetNumBytes())
370  {
371  throw InvalidArgumentException("Container size is not correct");
372  }
373  }
374 
375  /// ConstTensor constructed from TensorInfo and MemoryType template (a raw memory pointer).
376  ///
377  /// @param info - reference to a constant TensorInfo.
378  /// @param memoryArea - Region of CPU-addressable memory where tensor data will be stored. Must be valid while
379  /// workloads are on the fly. Tensor instances do not claim ownership of referenced memory regions, that is,
380  /// no attempt will be made by ArmNN to free these memory regions automatically.
381  ///
382  /// @throws InvalidArgumentException when TensorInfo isConstant parameter is false.
383  template<typename MemoryType>
384  ConstTensor(const TensorInfo& info, MemoryType memoryArea)
385  : BaseTensor<const void*>(info, memoryArea)
386  {
387  if (!this->GetInfo().IsConstant())
388  {
389  throw InvalidArgumentException("Invalid attempt to construct ConstTensor from non-constant TensorInfo.");
390  }
391  }
392 };
393 
394 using InputTensors = std::vector<std::pair<LayerBindingId, class ConstTensor>>;
395 using OutputTensors = std::vector<std::pair<LayerBindingId, class Tensor>>;
396 
397 } // namespace armnn
armnn::ConstTensor::ConstTensor
ConstTensor()
Definition: Tensor.hpp:334
armnn::BindingPointInfo
std::pair< armnn::LayerBindingId, armnn::TensorInfo > BindingPointInfo
Definition: Tensor.hpp:276
armnn::TensorShape::SetNumDimensions
void SetNumDimensions(unsigned int numDimensions, bool initDimensionsSpecificity=false)
Sets the tensor rank and therefore the Dimensionality is set to Specified if it was not.
Definition: Tensor.cpp:219
armnn::TensorInfo::SetQuantizationDim
void SetQuantizationDim(const Optional< unsigned int > &quantizationDim)
Definition: Tensor.cpp:499
armnn::Tensor
A tensor defined by a TensorInfo (shape and data type) and a mutable backing store.
Definition: Tensor.hpp:321
armnn::TensorInfo::GetNumElements
unsigned int GetNumElements() const
Definition: Tensor.hpp:198
armnn::BaseTensor::GetNumDimensions
unsigned int GetNumDimensions() const
Definition: Tensor.hpp:303
armnn::BaseTensor::GetMemoryArea
MemoryType GetMemoryArea() const
Definition: Tensor.hpp:307
armnn::TensorInfo::GetNumBytes
unsigned int GetNumBytes() const
Definition: Tensor.cpp:427
armnn::Optional< unsigned int >
armnn::InputTensors
std::vector< std::pair< LayerBindingId, class ConstTensor > > InputTensors
Definition: Tensor.hpp:394
armnn::TensorInfo::GetQuantizationScales
std::vector< float > GetQuantizationScales() const
Definition: Tensor.cpp:451
armnn::TensorShape::GetDimensionSpecificity
bool GetDimensionSpecificity(unsigned int i) const
Gets information about if the dimension size has been specified or not.
Definition: Tensor.cpp:211
armnn::TensorInfo::GetQuantizationScale
float GetQuantizationScale() const
Definition: Tensor.cpp:461
armnn::TensorInfo
Definition: Tensor.hpp:152
armnn::BaseTensor::GetNumBytes
unsigned int GetNumBytes() const
Definition: Tensor.hpp:304
armnn::TensorInfo::SetDataType
void SetDataType(DataType type)
Definition: Tensor.hpp:201
armnn::TensorInfo::GetNumDimensions
unsigned int GetNumDimensions() const
Definition: Tensor.hpp:197
armnn::TensorShape::AreAllDimensionsSpecified
bool AreAllDimensionsSpecified() const
Checks if there is at least one dimension not specified.
Definition: Tensor.cpp:241
armnn::BaseTensor::m_MemoryArea
MemoryType m_MemoryArea
Definition: Tensor.hpp:314
armnn::BaseTensor::GetNumElements
unsigned int GetNumElements() const
Definition: Tensor.hpp:305
armnn::OutputTensors
std::vector< std::pair< LayerBindingId, class Tensor > > OutputTensors
Definition: Tensor.hpp:395
armnn::TensorShape::operator[]
unsigned int operator[](unsigned int i) const
Read only operator.
Definition: Tensor.cpp:135
armnn::TensorInfo::HasPerAxisQuantization
bool HasPerAxisQuantization() const
Definition: Tensor.cpp:446
armnn::TensorInfo::IsConstant
bool IsConstant() const
Definition: Tensor.cpp:509
armnn::BaseTensor::operator=
BaseTensor & operator=(const BaseTensor &)
Tensors are copyable.
Definition: Tensor.cpp:544
armnn::TensorInfo::DifferenceType
std::vector< TensorInfo >::difference_type DifferenceType
Definition: Tensor.hpp:191
armnn::BaseTensor::GetDataType
DataType GetDataType() const
Definition: Tensor.hpp:302
armnn::TensorShape::operator=
TensorShape & operator=(const TensorShape &other)
Assignation function.
Definition: Tensor.cpp:124
armnn::TensorShape::SetDimensionSize
void SetDimensionSize(unsigned int i, unsigned int dimensionSize)
Sets the size of the indicated dimension and Specificity for that dimension is set to true.
Definition: Tensor.cpp:232
armnn::Dimensionality
Dimensionality
Definition: Types.hpp:172
armnn::TensorShape
Definition: Tensor.hpp:20
Optional.hpp
armnn::TensorInfo::SetQuantizationScale
void SetQuantizationScale(float scale)
Definition: Tensor.cpp:473
armnn::TensorInfo::SetQuantizationScales
void SetQuantizationScales(const std::vector< float > &scales)
Definition: Tensor.cpp:456
armnn::ConstTensor::ConstTensor
ConstTensor(const TensorInfo &info, MemoryType memoryArea)
ConstTensor constructed from TensorInfo and MemoryType template (a raw memory pointer).
Definition: Tensor.hpp:384
armnn::TensorShape::IsAtLeastOneDimensionSpecified
bool IsAtLeastOneDimensionSpecified() const
Checks if there is at least one dimension specified.
Definition: Tensor.cpp:257
armnn::TensorShape::GetNumDimensions
unsigned int GetNumDimensions() const
Function that returns the tensor rank.
Definition: Tensor.cpp:174
armnn::BaseTensor::BaseTensor
BaseTensor()
Empty (invalid) constructor.
Definition: Tensor.cpp:524
armnn::TensorInfo::GetQuantizationDim
Optional< unsigned int > GetQuantizationDim() const
Definition: Tensor.cpp:494
armnn::TensorInfo::HasMultipleQuantizationScales
bool HasMultipleQuantizationScales() const
Definition: Tensor.hpp:203
armnn::DataType
DataType
Definition: Types.hpp:48
armnn::TensorInfo::IsQuantized
bool IsQuantized() const
Definition: Tensor.cpp:504
armnn::BaseTensor::~BaseTensor
~BaseTensor()
Protected destructor to stop users from making these (could still new one on the heap and then leak i...
Definition: Tensor.hpp:312
armnn::TensorInfo::IsTypeSpaceMatch
bool IsTypeSpaceMatch(const TensorInfo &other) const
Check that the types are the same and, if quantize, that the quantization parameters are the same.
Definition: Tensor.cpp:432
armnn::TensorInfo::operator==
bool operator==(const TensorInfo &other) const
Definition: Tensor.cpp:414
armnn::InvalidArgumentException
Definition: Exceptions.hpp:80
armnn::TensorInfo::GetShape
TensorShape & GetShape()
Definition: Tensor.hpp:194
armnn::TensorInfo::TensorInfo
TensorInfo()
Empty (invalid) constructor.
Definition: Tensor.cpp:341
armnn::BaseTensor::GetShape
const TensorShape & GetShape() const
Definition: Tensor.hpp:299
armnn::TensorShape::operator!=
bool operator!=(const TensorShape &other) const
Inequality comparison operator.
Definition: Tensor.cpp:169
armnn::BaseTensor
Definition: Tensor.hpp:279
armnn::BaseTensor::GetInfo
const TensorInfo & GetInfo() const
Definition: Tensor.hpp:297
armnn::BoostLogSeverityMapping::info
@ info
armnn::TensorInfo::operator!=
bool operator!=(const TensorInfo &other) const
Definition: Tensor.cpp:422
armnn::TensorInfo::GetDataType
DataType GetDataType() const
Definition: Tensor.hpp:200
armnn::TensorInfo::operator=
TensorInfo & operator=(const TensorInfo &other)
Definition: Tensor.cpp:405
armnn::BaseTensor::GetShape
TensorShape & GetShape()
Definition: Tensor.hpp:300
armnn::TensorInfo::SetQuantizationOffset
void SetQuantizationOffset(int32_t offset)
Definition: Tensor.cpp:489
armnn::Dimensionality::Specified
@ Specified
armnn::TensorInfo::GetShape
const TensorShape & GetShape() const
Definition: Tensor.hpp:193
armnn::ConstTensor::ConstTensor
ConstTensor(const Tensor &other)
ConstTensor implicitly constructed from non-const Tensor.
Definition: Tensor.hpp:344
armnn::TensorInfo::SetShape
void SetShape(const TensorShape &newShape)
Definition: Tensor.hpp:195
Exceptions.hpp
armnn
Copyright (c) 2021 ARM Limited and Contributors.
Definition: 01_00_quick_start.dox:6
Types.hpp
armnn::ConstTensor
A tensor defined by a TensorInfo (shape and data type) and an immutable backing store.
Definition: Tensor.hpp:329
armnn::TensorShape::operator==
bool operator==(const TensorShape &other) const
Equality comparison operator.
Definition: Tensor.cpp:160
armnn::TensorInfo::SetConstant
void SetConstant(const bool IsConstant=true)
Marks the data corresponding to this tensor info as constant.
Definition: Tensor.cpp:514
armnn::TensorInfo::GetQuantizationOffset
int32_t GetQuantizationOffset() const
Definition: Tensor.cpp:478
armnn::TensorShape::GetDimensionality
Dimensionality GetDimensionality() const
Function that returns the tensor type.
Definition: Tensor.hpp:92
armnn::TensorShape::GetNumElements
unsigned int GetNumElements() const
Function that calculates the tensor elements by multiplying all dimension size which are Specified.
Definition: Tensor.cpp:181
armnn::TensorShape::TensorShape
TensorShape()
Empty (invalid) constructor.
Definition: Tensor.cpp:25
armnn::ConstTensor::ConstTensor
ConstTensor(const TensorInfo &info, const ContainerType< T, ContainerArgs... > &container)
Constructor from a backing container.
Definition: Tensor.hpp:362
armnn::BaseTensor::GetInfo
TensorInfo & GetInfo()
Definition: Tensor.hpp:298