ArmNN
 25.11
Loading...
Searching...
No Matches
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
17namespace armnn
18{
19
21{
22public:
23 /// Empty (invalid) constructor.
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.
116
117private:
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{
154public:
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
234private:
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
276using BindingPointInfo = std::pair<armnn::LayerBindingId, armnn::TensorInfo>;
277
278template<typename MemoryType>
280{
281public:
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
309protected:
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
316private:
317 TensorInfo m_Info;
318};
319
320/// A tensor defined by a TensorInfo (shape and data type) and a mutable backing store.
321class Tensor : public BaseTensor<void*>
322{
323public:
324 /// Brings in the constructors and assignment operator.
325 using BaseTensor<void*>::BaseTensor;
326};
327
328/// A tensor defined by a TensorInfo (shape and data type) and an immutable backing store.
329class ConstTensor : public BaseTensor<const void*>
330{
331public:
332 /// Brings in the constructors and assignment operator.
333 using BaseTensor<const void*>::BaseTensor;
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
394using InputTensors = std::vector<std::pair<LayerBindingId, class ConstTensor>>;
395using OutputTensors = std::vector<std::pair<LayerBindingId, class Tensor>>;
396
397} // namespace armnn
const TensorShape & GetShape() const
Definition Tensor.hpp:299
unsigned int GetNumDimensions() const
Definition Tensor.hpp:303
const TensorInfo & GetInfo() const
Definition Tensor.hpp:297
BaseTensor & operator=(const BaseTensor &)
Tensors are copyable.
Definition Tensor.cpp:548
unsigned int GetNumElements() const
Definition Tensor.hpp:305
MemoryType GetMemoryArea() const
Definition Tensor.hpp:307
MemoryType m_MemoryArea
Definition Tensor.hpp:314
~BaseTensor()
Protected destructor to stop users from making these (could still new one on the heap and then leak i...
Definition Tensor.hpp:312
unsigned int GetNumBytes() const
Definition Tensor.hpp:304
TensorInfo & GetInfo()
Definition Tensor.hpp:298
TensorShape & GetShape()
Definition Tensor.hpp:300
BaseTensor()
Empty (invalid) constructor.
Definition Tensor.cpp:528
DataType GetDataType() const
Definition Tensor.hpp:302
BaseTensor(const BaseTensor &other)
Tensors are copyable.
ConstTensor(const TensorInfo &info, MemoryType memoryArea)
ConstTensor constructed from TensorInfo and MemoryType template (a raw memory pointer).
Definition Tensor.hpp:384
ConstTensor(const Tensor &other)
ConstTensor implicitly constructed from non-const Tensor.
Definition Tensor.hpp:344
ConstTensor(const TensorInfo &info, const ContainerType< T, ContainerArgs... > &container)
Constructor from a backing container.
Definition Tensor.hpp:362
A tensor defined by a TensorInfo (shape and data type) and a mutable backing store.
Definition Tensor.hpp:322
float GetQuantizationScale() const
Definition Tensor.cpp:461
std::vector< TensorInfo >::difference_type DifferenceType
Definition Tensor.hpp:191
const TensorShape & GetShape() const
Definition Tensor.hpp:193
unsigned int GetNumDimensions() const
Definition Tensor.hpp:197
void SetQuantizationScales(const std::vector< float > &scales)
Definition Tensor.cpp:456
TensorInfo()
Empty (invalid) constructor.
Definition Tensor.cpp:341
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
bool operator!=(const TensorInfo &other) const
Definition Tensor.cpp:422
void SetQuantizationDim(const Optional< unsigned int > &quantizationDim)
Definition Tensor.cpp:503
bool operator==(const TensorInfo &other) const
Definition Tensor.cpp:414
void SetQuantizationOffset(int32_t offset)
Definition Tensor.cpp:493
void SetQuantizationScale(float scale)
Definition Tensor.cpp:477
void SetDataType(DataType type)
Definition Tensor.hpp:201
int32_t GetQuantizationOffset() const
Definition Tensor.cpp:482
bool IsQuantized() const
Definition Tensor.cpp:508
unsigned int GetNumElements() const
Definition Tensor.hpp:198
Optional< unsigned int > GetQuantizationDim() const
Definition Tensor.cpp:498
std::vector< float > GetQuantizationScales() const
Definition Tensor.cpp:451
void SetConstant(const bool IsConstant=true)
Marks the data corresponding to this tensor info as constant.
Definition Tensor.cpp:518
bool IsConstant() const
Definition Tensor.cpp:513
bool HasPerAxisQuantization() const
Definition Tensor.cpp:446
unsigned int GetNumBytes() const
Definition Tensor.cpp:427
void SetShape(const TensorShape &newShape)
Definition Tensor.hpp:195
TensorInfo & operator=(const TensorInfo &other)
Definition Tensor.cpp:405
TensorShape & GetShape()
Definition Tensor.hpp:194
DataType GetDataType() const
Definition Tensor.hpp:200
bool HasMultipleQuantizationScales() const
Definition Tensor.hpp:203
bool operator==(const TensorShape &other) const
Equality comparison operator.
Definition Tensor.cpp:160
TensorShape & operator=(const TensorShape &other)
Assignation function.
Definition Tensor.cpp:124
unsigned int GetNumDimensions() const
Function that returns the tensor rank.
Definition Tensor.cpp:174
bool IsAtLeastOneDimensionSpecified() const
Checks if there is at least one dimension specified.
Definition Tensor.cpp:257
bool GetDimensionSpecificity(unsigned int i) const
Gets information about if the dimension size has been specified or not.
Definition Tensor.cpp:211
Dimensionality GetDimensionality() const
Function that returns the tensor type.
Definition Tensor.hpp:92
unsigned int operator[](unsigned int i) const
Read only operator.
Definition Tensor.cpp:135
TensorShape()
Empty (invalid) constructor.
Definition Tensor.cpp:25
bool operator!=(const TensorShape &other) const
Inequality comparison operator.
Definition Tensor.cpp:169
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
unsigned int GetNumElements() const
Function that calculates the tensor elements by multiplying all dimension size which are Specified.
Definition Tensor.cpp:181
bool AreAllDimensionsSpecified() const
Checks if there is at least one dimension not specified.
Definition Tensor.cpp:241
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
Copyright (c) 2021 ARM Limited and Contributors.
std::pair< armnn::LayerBindingId, armnn::TensorInfo > BindingPointInfo
Definition Tensor.hpp:276
std::vector< std::pair< LayerBindingId, class ConstTensor > > InputTensors
Definition Tensor.hpp:394
Dimensionality
Definition Types.hpp:174
DataType
Definition Types.hpp:49
std::vector< std::pair< LayerBindingId, class Tensor > > OutputTensors
Definition Tensor.hpp:395
EmptyOptional is used to initialize the Optional class in case we want to have default value for an O...
Definition Optional.hpp:32