Compute Library
 23.05
TensorInfo.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2016-2023 Arm Limited.
3  *
4  * SPDX-License-Identifier: MIT
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and associated documentation files (the "Software"), to
8  * deal in the Software without restriction, including without limitation the
9  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10  * sell copies of the Software, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in all
14  * copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22  * SOFTWARE.
23  */
25 
26 #include "arm_compute/core/Error.h"
30 #include "src/core/helpers/Utils.h"
31 
32 #include <memory>
33 
34 namespace arm_compute
35 {
37  : _total_size(0), _offset_first_element_in_bytes(0), _strides_in_bytes(), _num_channels(0), _tensor_shape(), _dims_state(), _data_type(DataType::UNKNOWN), _format(Format::UNKNOWN), _is_resizable{ true },
38  _valid_region{ Coordinates(), _tensor_shape }, _padding{ 0 }, _quantization_info(), _data_layout(DataLayout::NCHW), _are_values_constant(true), _id(invalid_tensor_id), _lock_paddings(false)
39 {
40 }
41 
43  : TensorInfo()
44 {
45  _total_size = info.total_size();
46  _offset_first_element_in_bytes = info.offset_first_element_in_bytes();
47  _strides_in_bytes = info.strides_in_bytes();
48  _num_channels = info.num_channels();
49  _tensor_shape = info.tensor_shape();
50  _dims_state = info.tensor_dims_state();
51  _data_type = info.data_type();
52  _format = info.format();
53  _is_resizable = info.is_resizable();
54  _valid_region = info.valid_region();
55  _padding = info.padding();
56  _quantization_info = info.quantization_info();
57  _data_layout = info.data_layout();
58  _are_values_constant = info.are_values_constant();
59  _id = info.id();
60  _lock_paddings = info.lock_paddings();
61 }
62 
64  : TensorInfo()
65 {
66  _total_size = info.total_size();
67  _offset_first_element_in_bytes = info.offset_first_element_in_bytes();
68  _strides_in_bytes = info.strides_in_bytes();
69  _num_channels = info.num_channels();
70  _tensor_shape = info.tensor_shape();
71  _dims_state = info.tensor_dims_state();
72  _data_type = info.data_type();
73  _format = info.format();
74  _is_resizable = info.is_resizable();
75  _valid_region = info.valid_region();
76  _padding = info.padding();
77  _quantization_info = info.quantization_info();
78  _data_layout = info.data_layout();
79  _are_values_constant = info.are_values_constant();
80  _id = info.id();
81  _lock_paddings = false;
82 }
84  : TensorInfo(TensorShape(), format)
85 {
86 }
87 
88 TensorInfo::TensorInfo(unsigned int width, unsigned int height, Format format)
89  : TensorInfo(TensorShape(width, height), format)
90 {
91 }
92 
94  : TensorInfo()
95 {
96  init(tensor_shape, format);
97 }
98 
100  : TensorInfo()
101 {
102  init(TensorShape(), num_channels, data_type);
103 }
104 
106  : TensorInfo()
107 {
108  init(tensor_shape, num_channels, data_type);
109 }
110 
112  : TensorInfo()
113 {
114  init(tensor_shape, num_channels, data_type);
115  _quantization_info = std::move(quantization_info);
116 }
117 
119  : TensorInfo()
120 {
121  init(tensor_shape, num_channels, data_type);
122  _data_layout = data_layout;
123 }
124 
126 {
127  init(TensorShape(), format);
128 }
129 
131 {
132  size_t num_channels = num_channels_from_format(format);
133  const DataType type = data_type_from_format(format);
134 
135  init(tensor_shape, num_channels, type);
136 
137  _format = format;
138 }
139 
142  size_t total_size_in_bytes)
143 {
144  size_t num_channels = num_channels_from_format(format);
145  const DataType type = data_type_from_format(format);
146 
147  init(tensor_shape, num_channels, type, strides_in_bytes, offset_first_element_in_bytes, total_size_in_bytes);
148 
149  _format = format;
150 }
151 
153 {
154  init(TensorShape(), num_channels, data_type);
155 }
156 
158 {
159  ARM_COMPUTE_ERROR_ON(num_channels == 0);
160 
161  _data_type = data_type;
162  _num_channels = num_channels;
163  _format = Format::UNKNOWN;
164 
165  set_tensor_shape(tensor_shape);
166 }
167 
170  size_t total_size_in_bytes)
171 {
172  ARM_COMPUTE_ERROR_ON(num_channels == 0);
173 
174  _data_type = data_type;
175  _num_channels = num_channels;
176  _format = Format::UNKNOWN;
177  _tensor_shape = tensor_shape;
178  _offset_first_element_in_bytes = offset_first_element_in_bytes;
179  _strides_in_bytes = strides_in_bytes;
180  _total_size = total_size_in_bytes;
181 
182  _valid_region = ValidRegion{ Coordinates(), _tensor_shape };
183 }
184 
186 {
187  const size_t num_channels = num_channels_from_format(format);
188  const DataType type = data_type_from_format(format);
189  size_t total_size = init_auto_padding(tensor_shape, num_channels, type);
190 
191  _format = format;
192 
193  return total_size;
194 }
195 
197 {
198  ARM_COMPUTE_ERROR_ON(num_channels == 0);
199 
200  _data_type = data_type;
201  _num_channels = num_channels;
202  _format = Format::UNKNOWN;
203  _tensor_shape = tensor_shape;
204 
205  _valid_region = ValidRegion{ Coordinates(), _tensor_shape };
206 
207  auto_padding();
208 
209  return _total_size;
210 }
211 
213 {
214  ARM_COMPUTE_ERROR_ON(!_is_resizable);
215 
216  // Some kernels compute 32 elements at the time, worst case scenario they
217  // will read 32 values after the last element
218  const size_t extra_pad_x = _tensor_shape.num_dimensions() < 1 ? 0 : 32;
219  const size_t pad_x = _tensor_shape.num_dimensions() < 1 ? 0 : 4;
220  const size_t pad_y = _tensor_shape.num_dimensions() < 2 ? 0 : 4;
221 
222  return extend_padding(PaddingSize(pad_y, pad_x + extra_pad_x, pad_y, pad_x));
223 }
224 
225 std::tuple<Strides, size_t, size_t> TensorInfo::calculate_padding_requirements(const PaddingSize &padding)
226 {
227  // Calculate resulting stride for the X, Y and Z dimension
228  const size_t stride_x = element_size();
229  const size_t stride_y = (padding.left + _tensor_shape[0] + padding.right) * stride_x;
230  const size_t stride_z = (padding.top + _tensor_shape[1] + padding.bottom) * stride_y;
231 
232  Strides required_strides;
233  size_t required_total_size = 0;
234  const size_t required_offset_first_element = padding.left * stride_x + padding.top * stride_y;
235 
236  switch(_tensor_shape.num_dimensions())
237  {
238  case 0:
239  {
240  if(_tensor_shape.total_size() > 0)
241  {
242  required_strides = Strides(stride_x, stride_x);
243  required_total_size = stride_z;
244  }
245  break;
246  }
247  case 1:
248  required_strides = compute_strides(*this, stride_x, stride_y);
249  required_total_size = stride_z;
250  break;
251  case 2:
252  required_strides = compute_strides(*this, stride_x, stride_y);
253  required_total_size = stride_z;
254  break;
255  default:
256  {
257  required_strides = compute_strides(*this, stride_x, stride_y, stride_z);
258 
259  const unsigned int idx_last_dimension = _tensor_shape.num_dimensions() - 1;
260 
261  required_total_size = static_cast<size_t>(_tensor_shape[idx_last_dimension]) * required_strides[idx_last_dimension];
262  break;
263  }
264  }
265 
266  return std::make_tuple(required_strides, required_offset_first_element, required_total_size);
267 }
268 
270 {
271  _lock_paddings = flag;
272  return *this;
273 }
274 
276 {
277  return _lock_paddings;
278 }
279 
281 {
282  ARM_COMPUTE_ERROR_ON(_lock_paddings);
283  ARM_COMPUTE_ERROR_ON(!_is_resizable);
284 
285  bool updated = false;
286 
287  if(padding.top > _padding.top)
288  {
289  _padding.top = padding.top;
290  updated = true;
291  }
292 
293  if(padding.right > _padding.right)
294  {
295  _padding.right = padding.right;
296  updated = true;
297  }
298 
299  if(padding.bottom > _padding.bottom)
300  {
301  _padding.bottom = padding.bottom;
302  updated = true;
303  }
304 
305  if(padding.left > _padding.left)
306  {
307  _padding.left = padding.left;
308  updated = true;
309  }
310 
311  std::tie(_strides_in_bytes, _offset_first_element_in_bytes, _total_size) = calculate_padding_requirements(_padding);
312 
313  return updated;
314 }
315 
316 std::unique_ptr<ITensorInfo> TensorInfo::clone() const
317 {
318  return std::make_unique<TensorInfo>(*this);
319 }
320 
322 {
323  _data_type = data_type;
324  _format = Format::UNKNOWN;
325  return set_tensor_shape(tensor_shape()); // Force total size and strides to update
326 }
327 
329 {
330  _num_channels = num_channels;
331  _format = Format::UNKNOWN;
332  return *this;
333 }
334 
336 {
337  _format = format;
338 
339  if(_data_type == DataType::UNKNOWN)
340  {
341  _num_channels = num_channels_from_format(format);
342  _data_type = data_type_from_format(format);
343  }
344  else
345  {
346  ARM_COMPUTE_ERROR_ON(num_channels_from_format(format) != _num_channels);
347  ARM_COMPUTE_ERROR_ON(data_type_from_format(format) != _data_type);
348  }
349  return *this;
350 }
351 
353 {
354  _tensor_shape = shape;
355  _offset_first_element_in_bytes = 0;
356  _strides_in_bytes = compute_strides(*this);
357 
358  if(_tensor_shape.num_dimensions() == 0)
359  {
360  _total_size = _strides_in_bytes[0];
361  }
362  else
363  {
364  const unsigned int idx_last_dimension = _tensor_shape.num_dimensions() - 1;
365  _total_size = static_cast<size_t>(_tensor_shape[idx_last_dimension]) * _strides_in_bytes[idx_last_dimension];
366  }
367 
368  std::tie(_strides_in_bytes, _offset_first_element_in_bytes, _total_size) = calculate_padding_requirements(_padding);
369 
370  _valid_region = ValidRegion{ Coordinates(), _tensor_shape };
371  return *this;
372 }
373 
375 {
376  _dims_state = state;
377  return *this;
378 }
379 
381 {
382  _quantization_info = quantization_info;
383  return *this;
384 }
385 
387 {
388  _data_layout = data_layout;
389  return *this;
390 }
391 
393 {
394  _padding = PaddingSize();
395  if(((_format != Format::UNKNOWN) || (_data_type != DataType::UNKNOWN)) && _total_size != 0)
396  {
397  std::tie(_strides_in_bytes, _offset_first_element_in_bytes, _total_size) = calculate_padding_requirements(_padding);
398  }
399  return *this;
400 }
401 
403 {
405 
406  int32_t offset = _offset_first_element_in_bytes;
407 
408  for(size_t i = 0; i < _tensor_shape.num_dimensions(); ++i)
409  {
410  offset += pos[i] * _strides_in_bytes[i];
411  }
412 
413  return offset;
414 }
415 } // namespace arm_compute
ITensorInfo & set_format(Format format) override
Set the format of an already initialized tensor.
Definition: TensorInfo.cpp:335
__global uchar * offset(const Image *img, int x, int y)
Get the pointer position of a Image.
Definition: helpers.h:1110
unsigned int top
top of the border
Definition: Types.h:392
Shape of a tensor.
Definition: TensorShape.h:39
size_t init_auto_padding(const TensorShape &tensor_shape, Format format)
Initialize the metadata structure for the given tensor shape and single-plane format, (Padding is automatically calculated)
Definition: TensorInfo.cpp:185
std::unique_ptr< ITensorInfo > clone() const override
Provide a clone of the current object of class T.
Definition: TensorInfo.cpp:316
bool is_resizable() const override
Flag indicating whether the size of the tensor can be changed.
Definition: TensorInfo.h:264
Unknown CL kernel type.
Definition: CLTypes.h:82
Container for 2D border size.
Definition: Types.h:284
ValidRegion valid_region() const override
Valid region of the tensor.
Definition: TensorInfo.h:281
size_t num_channels() const override
The number of channels for each tensor element.
Definition: TensorInfo.h:232
ITensorInfo & reset_padding() override
Resets the padding settings of the tensor.
Definition: TensorInfo.cpp:392
DataLayout data_layout() const override
Get the data layout of the tensor.
Definition: TensorInfo.h:293
ITensorInfo & set_lock_paddings(bool flag) override
Set the lock paddings flag of the tensor.
Definition: TensorInfo.cpp:269
virtual DataType data_type() const =0
Data type used for each element of the tensor.
QuantizationInfo quantization_info() const override
Get the quantization settings (scale and offset) of the tensor.
Definition: TensorInfo.h:289
bool extend_padding(const PaddingSize &padding) override
Update the offset to the first element, the strides and the total size.
Definition: TensorInfo.cpp:280
ITensorInfo & set_data_type(DataType data_type) override
Set the data type to the specified value.
Definition: TensorInfo.cpp:321
#define ARM_COMPUTE_ERROR_ON(cond)
If the condition is true then an error message is printed and an exception thrown.
Definition: Error.h:466
size_t num_channels_from_format(Format format)
Return the number of channels for a given single-planar pixel format.
Definition: Utils.h:486
static constexpr Id invalid_tensor_id
An invalid tensor id within a domain.
Definition: ITensorInfo.h:51
Store the tensor&#39;s metadata.
Definition: ITensorInfo.h:43
std::vector< int > TensorDimsState
Definition: ITensorInfo.h:46
unsigned int bottom
bottom of the border
Definition: Types.h:394
PaddingSize padding() const override
Padding of tensor.
Definition: TensorInfo.h:256
const Strides & strides_in_bytes() const override
The strides in bytes for accessing each dimension of the tensor.
Definition: TensorInfo.h:215
decltype(strategy::transforms) typedef type
bool auto_padding() override
Update the offset to the first element and the strides to automatically computed values.
Definition: TensorInfo.cpp:212
Copyright (c) 2017-2023 Arm Limited.
Strides compute_strides(const ITensorInfo &info, T stride_x, Ts &&... fixed_strides)
Create a strides object based on the provided strides and the tensor dimensions.
Definition: Utils.h:41
virtual ValidRegion valid_region() const =0
Valid region of the tensor.
Format format() const override
Colour format of the image.
Definition: TensorInfo.h:248
ITensorInfo & set_quantization_info(const QuantizationInfo &quantization_info) override
Set the quantization settings (scale and offset) of the tensor.
Definition: TensorInfo.cpp:380
DataType data_type() const override
Data type used for each element of the tensor.
Definition: TensorInfo.h:244
virtual bool is_resizable() const =0
Flag indicating whether the size of the tensor can be changed.
Quantization information.
virtual Format format() const =0
Colour format of the image.
ITensorInfo & set_data_layout(const DataLayout &data_layout) override
Set the data layout of the tensor.
Definition: TensorInfo.cpp:386
virtual const TensorShape & tensor_shape() const =0
Size for each dimension of the tensor.
Format
Image colour formats.
Definition: Types.h:56
size_t total_size() const override
Returns the total size of the tensor in bytes.
Definition: TensorInfo.h:252
Coordinates of an item.
Definition: Coordinates.h:37
const TensorDimsState & tensor_dims_state() const override
State of each dimension of the tensor shape.
Definition: TensorInfo.h:240
size_t total_size() const
Collapses all dimensions to a single linear total size.
Definition: TensorShape.h:172
virtual bool are_values_constant() const =0
Flag indicating whether the values of the tensor are constant, meaning that they can change on kernel...
virtual PaddingSize padding() const =0
Padding of tensor.
BorderSize PaddingSize
Container for 2D padding size.
Definition: Types.h:399
unsigned int left
left of the border
Definition: Types.h:395
ITensorInfo & set_num_channels(int num_channels) override
Set the number of channels to the specified value.
Definition: TensorInfo.cpp:328
virtual QuantizationInfo quantization_info() const =0
Get the quantization settings (scale and offset) of the tensor.
bool are_values_constant() const override
Flag indicating whether the values of the tensor are constant, meaning that they can change on kernel...
Definition: TensorInfo.h:272
unsigned int right
right of the border
Definition: Types.h:393
virtual Id id() const =0
Get the workload tensor id of the tensor.
Num samples, channels, height, width.
DataType data_type_from_format(Format format)
Return the data type used by a given single-planar pixel format.
Definition: Utils.h:219
void init(Format format)
Initialize the tensor info with just a format.
Definition: TensorInfo.cpp:125
Strides of an item in bytes.
Definition: Strides.h:38
virtual size_t offset_first_element_in_bytes() const =0
The offset from the beginning of the memory allocation to the first element of the tensor...
ScaleKernelInfo info(interpolation_policy, default_border_mode, PixelValue(), sampling_policy, false)
ITensorInfo & set_tensor_dims_state(const TensorDimsState &state) override
Set the state for each dimension of the tensor.
Definition: TensorInfo.cpp:374
virtual size_t total_size() const =0
Returns the total size of the tensor in bytes.
bool lock_paddings() const override
Get the lock paddings flag value.
Definition: TensorInfo.cpp:275
unsigned int num_dimensions() const
Returns the effective dimensionality of the tensor.
Definition: Dimensions.h:143
ITensorInfo::Id id() const override
Get the workload tensor id of the tensor.
Definition: TensorInfo.h:302
int32_t offset_element_in_bytes(const Coordinates &pos) const override
The offset in bytes from the beginning of the memory allocation to access the element at position (x...
Definition: TensorInfo.cpp:402
virtual bool lock_paddings() const =0
Get the lock paddings flag value.
#define ARM_COMPUTE_ERROR_ON_COORDINATES_DIMENSIONS_GTE(p, md)
Definition: Validate.h:240
size_t offset_first_element_in_bytes() const override
The offset from the beginning of the memory allocation to the first element of the tensor...
Definition: TensorInfo.h:219
Store the tensor&#39;s metadata.
Definition: TensorInfo.h:43
ITensorInfo & set_tensor_shape(const TensorShape &shape) override
Set the shape of an already initialized tensor.
Definition: TensorInfo.cpp:352
TensorInfo()
Default constructor.
Definition: TensorInfo.cpp:36
virtual const Strides & strides_in_bytes() const =0
The strides in bytes for accessing each dimension of the tensor.
virtual const TensorDimsState & tensor_dims_state() const =0
State of each dimension of the tensor shape.
Container for valid region of a window.
Definition: Types.h:186
const TensorShape & tensor_shape() const override
Size for each dimension of the tensor.
Definition: TensorInfo.h:236
DataType
Available data types.
Definition: Types.h:79
DataLayout
[DataLayout enum definition]
Definition: Types.h:113
size_t element_size() const override
Element size in bytes calculated as data_size() * num_channels()
Definition: TensorInfo.h:224
virtual size_t num_channels() const =0
The number of channels for each tensor element.
virtual DataLayout data_layout() const =0
Get the data layout of the tensor.