Compute Library
 21.11
TensorInfo.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2016-2021 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)
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 }
60 
62  : TensorInfo(TensorShape(), format)
63 {
64 }
65 
66 TensorInfo::TensorInfo(unsigned int width, unsigned int height, Format format)
67  : TensorInfo(TensorShape(width, height), format)
68 {
69 }
70 
72  : TensorInfo()
73 {
74  init(tensor_shape, format);
75 }
76 
78  : TensorInfo()
79 {
80  init(TensorShape(), num_channels, data_type);
81 }
82 
84  : TensorInfo()
85 {
86  init(tensor_shape, num_channels, data_type);
87 }
88 
90  : TensorInfo()
91 {
92  init(tensor_shape, num_channels, data_type);
93  _quantization_info = std::move(quantization_info);
94 }
95 
97  : TensorInfo()
98 {
99  init(tensor_shape, num_channels, data_type);
100  _data_layout = data_layout;
101 }
102 
104 {
105  init(TensorShape(), format);
106 }
107 
109 {
110  size_t num_channels = num_channels_from_format(format);
111  const DataType type = data_type_from_format(format);
112 
113  init(tensor_shape, num_channels, type);
114 
115  _format = format;
116 }
117 
120  size_t total_size_in_bytes)
121 {
122  size_t num_channels = num_channels_from_format(format);
123  const DataType type = data_type_from_format(format);
124 
125  init(tensor_shape, num_channels, type, strides_in_bytes, offset_first_element_in_bytes, total_size_in_bytes);
126 
127  _format = format;
128 }
129 
131 {
132  init(TensorShape(), num_channels, data_type);
133 }
134 
136 {
137  ARM_COMPUTE_ERROR_ON(num_channels == 0);
138 
139  _data_type = data_type;
140  _num_channels = num_channels;
141  _format = Format::UNKNOWN;
142 
143  set_tensor_shape(tensor_shape);
144 }
145 
148  size_t total_size_in_bytes)
149 {
150  ARM_COMPUTE_ERROR_ON(num_channels == 0);
151 
152  _data_type = data_type;
153  _num_channels = num_channels;
154  _format = Format::UNKNOWN;
155  _tensor_shape = tensor_shape;
156  _offset_first_element_in_bytes = offset_first_element_in_bytes;
157  _strides_in_bytes = strides_in_bytes;
158  _total_size = total_size_in_bytes;
159 
160  _valid_region = ValidRegion{ Coordinates(), _tensor_shape };
161 }
162 
164 {
165  const size_t num_channels = num_channels_from_format(format);
166  const DataType type = data_type_from_format(format);
167  size_t total_size = init_auto_padding(tensor_shape, num_channels, type);
168 
169  _format = format;
170 
171  return total_size;
172 }
173 
175 {
176  ARM_COMPUTE_ERROR_ON(num_channels == 0);
177 
178  _data_type = data_type;
179  _num_channels = num_channels;
180  _format = Format::UNKNOWN;
181  _tensor_shape = tensor_shape;
182 
183  _valid_region = ValidRegion{ Coordinates(), _tensor_shape };
184 
185  auto_padding();
186 
187  return _total_size;
188 }
189 
191 {
192  ARM_COMPUTE_ERROR_ON(!_is_resizable);
193 
194  // Some kernels compute 32 elements at the time, worst case scenario they
195  // will read 32 values after the last element
196  const size_t extra_pad_x = _tensor_shape.num_dimensions() < 1 ? 0 : 32;
197  const size_t pad_x = _tensor_shape.num_dimensions() < 1 ? 0 : 4;
198  const size_t pad_y = _tensor_shape.num_dimensions() < 2 ? 0 : 4;
199 
200  return extend_padding(PaddingSize(pad_y, pad_x + extra_pad_x, pad_y, pad_x));
201 }
202 
203 std::tuple<Strides, size_t, size_t> TensorInfo::calculate_padding_requirements(const PaddingSize &padding)
204 {
205  // Calculate resulting stride for the X, Y and Z dimension
206  const size_t stride_x = element_size();
207  const size_t stride_y = (padding.left + _tensor_shape[0] + padding.right) * stride_x;
208  const size_t stride_z = (padding.top + _tensor_shape[1] + padding.bottom) * stride_y;
209 
210  Strides required_strides;
211  size_t required_total_size = 0;
212  const size_t required_offset_first_element = padding.left * stride_x + padding.top * stride_y;
213 
214  switch(_tensor_shape.num_dimensions())
215  {
216  case 0:
217  {
218  if(_tensor_shape.total_size() > 0)
219  {
220  required_strides = Strides(stride_x, stride_x);
221  required_total_size = stride_z;
222  }
223  break;
224  }
225  case 1:
226  required_strides = compute_strides(*this, stride_x, stride_y);
227  required_total_size = stride_z;
228  break;
229  case 2:
230  required_strides = compute_strides(*this, stride_x, stride_y);
231  required_total_size = stride_z;
232  break;
233  default:
234  {
235  required_strides = compute_strides(*this, stride_x, stride_y, stride_z);
236 
237  const unsigned int idx_last_dimension = _tensor_shape.num_dimensions() - 1;
238 
239  required_total_size = static_cast<size_t>(_tensor_shape[idx_last_dimension]) * required_strides[idx_last_dimension];
240  break;
241  }
242  }
243 
244  return std::make_tuple(required_strides, required_offset_first_element, required_total_size);
245 }
246 
248 {
249  ARM_COMPUTE_ERROR_ON(!_is_resizable);
250 
251  bool updated = false;
252 
253  if(padding.top > _padding.top)
254  {
255  _padding.top = padding.top;
256  updated = true;
257  }
258 
259  if(padding.right > _padding.right)
260  {
261  _padding.right = padding.right;
262  updated = true;
263  }
264 
265  if(padding.bottom > _padding.bottom)
266  {
267  _padding.bottom = padding.bottom;
268  updated = true;
269  }
270 
271  if(padding.left > _padding.left)
272  {
273  _padding.left = padding.left;
274  updated = true;
275  }
276 
277  std::tie(_strides_in_bytes, _offset_first_element_in_bytes, _total_size) = calculate_padding_requirements(_padding);
278 
279  return updated;
280 }
281 
282 std::unique_ptr<ITensorInfo> TensorInfo::clone() const
283 {
284  return std::make_unique<TensorInfo>(*this);
285 }
286 
288 {
289  _data_type = data_type;
290  _format = Format::UNKNOWN;
291  return set_tensor_shape(tensor_shape()); // Force total size and strides to update
292 }
293 
295 {
296  _num_channels = num_channels;
297  _format = Format::UNKNOWN;
298  return *this;
299 }
300 
302 {
303  _format = format;
304 
305  if(_data_type == DataType::UNKNOWN)
306  {
307  _num_channels = num_channels_from_format(format);
308  _data_type = data_type_from_format(format);
309  }
310  else
311  {
312  ARM_COMPUTE_ERROR_ON(num_channels_from_format(format) != _num_channels);
313  ARM_COMPUTE_ERROR_ON(data_type_from_format(format) != _data_type);
314  }
315  return *this;
316 }
317 
319 {
320  _tensor_shape = shape;
321  _offset_first_element_in_bytes = 0;
322  _strides_in_bytes = compute_strides(*this);
323 
324  if(_tensor_shape.num_dimensions() == 0)
325  {
326  _total_size = _strides_in_bytes[0];
327  }
328  else
329  {
330  const unsigned int idx_last_dimension = _tensor_shape.num_dimensions() - 1;
331  _total_size = static_cast<size_t>(_tensor_shape[idx_last_dimension]) * _strides_in_bytes[idx_last_dimension];
332  }
333 
334  std::tie(_strides_in_bytes, _offset_first_element_in_bytes, _total_size) = calculate_padding_requirements(_padding);
335 
336  _valid_region = ValidRegion{ Coordinates(), _tensor_shape };
337  return *this;
338 }
339 
341 {
342  _dims_state = state;
343  return *this;
344 }
345 
347 {
348  _quantization_info = quantization_info;
349  return *this;
350 }
351 
353 {
354  _data_layout = data_layout;
355  return *this;
356 }
357 
359 {
360  _padding = PaddingSize();
361  if(((_format != Format::UNKNOWN) || (_data_type != DataType::UNKNOWN)) && _total_size != 0)
362  {
363  std::tie(_strides_in_bytes, _offset_first_element_in_bytes, _total_size) = calculate_padding_requirements(_padding);
364  }
365  return *this;
366 }
367 
369 {
371 
372  int32_t offset = _offset_first_element_in_bytes;
373 
374  for(size_t i = 0; i < _tensor_shape.num_dimensions(); ++i)
375  {
376  offset += pos[i] * _strides_in_bytes[i];
377  }
378 
379  return offset;
380 }
381 } // namespace arm_compute
ITensorInfo & set_format(Format format) override
Set the format of an already initialized tensor.
Definition: TensorInfo.cpp:301
__global uchar * offset(const Image *img, int x, int y)
Get the pointer position of a Image.
Definition: helpers.h:1069
unsigned int top
top of the border
Definition: Types.h:377
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:163
std::unique_ptr< ITensorInfo > clone() const override
Provide a clone of the current object of class T.
Definition: TensorInfo.cpp:282
Unknown CL kernel type.
Definition: CLTypes.h:81
Container for 2D border size.
Definition: Types.h:269
size_t num_channels() const override
The number of channels for each tensor element.
Definition: TensorInfo.h:230
ITensorInfo & reset_padding() override
Resets the padding settings of the tensor.
Definition: TensorInfo.cpp:358
DataLayout data_layout() const override
Get the data layout of the tensor.
Definition: TensorInfo.h:291
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:287
bool extend_padding(const PaddingSize &padding) override
Update the offset to the first element, the strides and the total size.
Definition: TensorInfo.cpp:247
ITensorInfo & set_data_type(DataType data_type) override
Set the data type to the specified value.
Definition: TensorInfo.cpp:287
#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
Store the tensor&#39;s metadata.
Definition: ITensorInfo.h:40
std::vector< int > TensorDimsState
Definition: ITensorInfo.h:43
unsigned int bottom
bottom of the border
Definition: Types.h:379
PaddingSize padding() const override
Padding of tensor.
Definition: TensorInfo.h:254
const Strides & strides_in_bytes() const override
The strides in bytes for accessing each dimension of the tensor.
Definition: TensorInfo.h:213
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:190
Copyright (c) 2017-2021 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:246
ITensorInfo & set_quantization_info(const QuantizationInfo &quantization_info) override
Set the quantization settings (scale and offset) of the tensor.
Definition: TensorInfo.cpp:346
DataType data_type() const override
Data type used for each element of the tensor.
Definition: TensorInfo.h:242
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:352
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:250
Coordinates of an item.
Definition: Coordinates.h:37
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:384
unsigned int left
left of the border
Definition: Types.h:380
ITensorInfo & set_num_channels(int num_channels) override
Set the number of channels to the specified value.
Definition: TensorInfo.cpp:294
virtual QuantizationInfo quantization_info() const =0
Get the quantization settings (scale and offset) of the tensor.
unsigned int right
right of the border
Definition: Types.h:378
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:103
Strides of an item in bytes.
Definition: Strides.h:37
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:340
virtual size_t total_size() const =0
Returns the total size of the tensor in bytes.
unsigned int num_dimensions() const
Returns the effective dimensionality of the tensor.
Definition: Dimensions.h:143
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:368
#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:217
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:318
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:184
const TensorShape & tensor_shape() const override
Size for each dimension of the tensor.
Definition: TensorInfo.h:234
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:222
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.