Compute Library
 21.02
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"
31 #include "src/core/helpers/Utils.h"
32 
33 #include <memory>
34 
35 using namespace arm_compute;
36 
38  : _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 },
39  _valid_region{ Coordinates(), _tensor_shape }, _padding{ 0 }, _quantization_info(), _data_layout(DataLayout::NCHW)
40 {
41 }
42 
44  : TensorInfo()
45 {
46  _total_size = info.total_size();
47  _offset_first_element_in_bytes = info.offset_first_element_in_bytes();
48  _strides_in_bytes = info.strides_in_bytes();
49  _num_channels = info.num_channels();
50  _tensor_shape = info.tensor_shape();
51  _dims_state = info.tensor_dims_state();
52  _data_type = info.data_type();
53  _format = info.format();
54  _is_resizable = info.is_resizable();
55  _valid_region = info.valid_region();
56  _padding = info.padding();
57  _quantization_info = info.quantization_info();
58  _data_layout = info.data_layout();
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 
103 TensorInfo::TensorInfo(const HOGInfo &hog_info, unsigned int width, unsigned int height)
104  : TensorInfo()
105 {
106  init(hog_info, width, height);
107 }
108 
110 {
111  init(TensorShape(), format);
112 }
113 
115 {
116  size_t num_channels = num_channels_from_format(format);
117  const DataType type = data_type_from_format(format);
118 
119  init(tensor_shape, num_channels, type);
120 
121  _format = format;
122 }
123 
126  size_t total_size_in_bytes)
127 {
128  size_t num_channels = num_channels_from_format(format);
129  const DataType type = data_type_from_format(format);
130 
131  init(tensor_shape, num_channels, type, strides_in_bytes, offset_first_element_in_bytes, total_size_in_bytes);
132 
133  _format = format;
134 }
135 
137 {
138  init(TensorShape(), num_channels, data_type);
139 }
140 
142 {
143  ARM_COMPUTE_ERROR_ON(num_channels == 0);
144 
145  _data_type = data_type;
146  _num_channels = num_channels;
147  _format = Format::UNKNOWN;
148 
149  set_tensor_shape(tensor_shape);
150 }
151 
154  size_t total_size_in_bytes)
155 {
156  ARM_COMPUTE_ERROR_ON(num_channels == 0);
157 
158  _data_type = data_type;
159  _num_channels = num_channels;
160  _format = Format::UNKNOWN;
161  _tensor_shape = tensor_shape;
162  _offset_first_element_in_bytes = offset_first_element_in_bytes;
163  _strides_in_bytes = strides_in_bytes;
164  _total_size = total_size_in_bytes;
165 
166  _valid_region = ValidRegion{ Coordinates(), _tensor_shape };
167 }
168 
169 void TensorInfo::init(const HOGInfo &hog_info, unsigned int width, unsigned int height)
170 {
171  // Number of cells for each block
172  const Size2D num_cells_per_block = hog_info.num_cells_per_block();
173 
174  // Tensor Size = (Number of horizontal block positions) * (Number of vertical block positions)
175  const Size2D num_block_positions_per_img = hog_info.num_block_positions_per_image(Size2D(width, height));
176 
177  // Number of tensor channels = (Number of cells per block) * (Number of bins per cell)
178  const size_t num_channels = num_cells_per_block.area() * hog_info.num_bins();
179 
180  init(TensorShape(num_block_positions_per_img.width, num_block_positions_per_img.height), num_channels, DataType::F32);
181 }
182 
184 {
185  const size_t num_channels = num_channels_from_format(format);
186  const DataType type = data_type_from_format(format);
187  size_t total_size = init_auto_padding(tensor_shape, num_channels, type);
188 
189  _format = format;
190 
191  return total_size;
192 }
193 
195 {
196  ARM_COMPUTE_ERROR_ON(num_channels == 0);
197 
198  _data_type = data_type;
199  _num_channels = num_channels;
200  _format = Format::UNKNOWN;
201  _tensor_shape = tensor_shape;
202 
203  _valid_region = ValidRegion{ Coordinates(), _tensor_shape };
204 
205  auto_padding();
206 
207  return _total_size;
208 }
209 
210 size_t TensorInfo::init_auto_padding(const HOGInfo &hog_info, unsigned int width, unsigned int height)
211 {
212  // Number of cells for each block
213  const Size2D num_cells_per_block = hog_info.num_cells_per_block();
214 
215  // Tensor Size = (Number of horizontal block positions) * (Number of vertical block positions)
216  const Size2D num_block_positions_per_img = hog_info.num_block_positions_per_image(Size2D(width, height));
217 
218  // Number of tensor channels = (Number of cells per block) * (Number of bins per cell)
219  const size_t num_channels = num_cells_per_block.area() * hog_info.num_bins();
220 
221  return init_auto_padding(TensorShape(num_block_positions_per_img.width, num_block_positions_per_img.height), num_channels, DataType::F32);
222 }
223 
225 {
226  ARM_COMPUTE_ERROR_ON(!_is_resizable);
227 
228  // Some kernels compute 32 elements at the time, worst case scenario they
229  // will read 32 values after the last element
230  const size_t extra_pad_x = _tensor_shape.num_dimensions() < 1 ? 0 : 32;
231  const size_t pad_x = _tensor_shape.num_dimensions() < 1 ? 0 : 4;
232  const size_t pad_y = _tensor_shape.num_dimensions() < 2 ? 0 : 4;
233 
234  return extend_padding(PaddingSize(pad_y, pad_x + extra_pad_x, pad_y, pad_x));
235 }
236 
237 std::tuple<Strides, size_t, size_t> TensorInfo::calculate_padding_requirements(const PaddingSize &padding)
238 {
239  // Calculate resulting stride for the X, Y and Z dimension
240  const size_t stride_x = element_size();
241  const size_t stride_y = (padding.left + _tensor_shape[0] + padding.right) * stride_x;
242  const size_t stride_z = (padding.top + _tensor_shape[1] + padding.bottom) * stride_y;
243 
244  Strides required_strides;
245  size_t required_total_size = 0;
246  const size_t required_offset_first_element = padding.left * stride_x + padding.top * stride_y;
247 
248  switch(_tensor_shape.num_dimensions())
249  {
250  case 0:
251  {
252  if(_tensor_shape.total_size() > 0)
253  {
254  required_strides = Strides(stride_x, stride_x);
255  required_total_size = stride_z;
256  }
257  break;
258  }
259  case 1:
260  required_strides = compute_strides(*this, stride_x, stride_y);
261  required_total_size = stride_z;
262  break;
263  case 2:
264  required_strides = compute_strides(*this, stride_x, stride_y);
265  required_total_size = stride_z;
266  break;
267  default:
268  {
269  required_strides = compute_strides(*this, stride_x, stride_y, stride_z);
270 
271  const unsigned int idx_last_dimension = _tensor_shape.num_dimensions() - 1;
272 
273  required_total_size = static_cast<size_t>(_tensor_shape[idx_last_dimension]) * required_strides[idx_last_dimension];
274  break;
275  }
276  }
277 
278  return std::make_tuple(required_strides, required_offset_first_element, required_total_size);
279 }
280 
282 {
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 }
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:846
unsigned int top
top of the border
Definition: Types.h:375
size_t num_bins() const
The number of histogram bins for each cell.
Definition: HOGInfo.cpp:111
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:183
std::unique_ptr< ITensorInfo > clone() const override
Provide a clone of the current object of class T.
Definition: TensorInfo.cpp:316
Container for 2D border size.
Definition: Types.h:273
size_t num_channels() const override
The number of channels for each tensor element.
Definition: TensorInfo.h:258
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:315
virtual DataType data_type() const =0
Data type used for each element of the tensor.
Store the HOG&#39;s metadata.
Definition: HOGInfo.h:35
QuantizationInfo quantization_info() const override
Get the quantization settings (scale and offset) of the tensor.
Definition: TensorInfo.h:311
bool extend_padding(const PaddingSize &padding) override
Update the offset to the first element, the strides and the total size.
Definition: TensorInfo.cpp:281
1 channel, 1 F32 per channel
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
Store the tensor&#39;s metadata.
Definition: ITensorInfo.h:40
unsigned int bottom
bottom of the border
Definition: Types.h:377
PaddingSize padding() const override
Padding of tensor.
Definition: TensorInfo.h:282
const Strides & strides_in_bytes() const override
The strides in bytes for accessing each dimension of the tensor.
Definition: TensorInfo.h:241
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:224
Copyright (c) 2017-2021 Arm Limited.
size_t height
Height of the image region or rectangle.
Definition: Size2D.h:90
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:274
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:270
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:54
Size2D num_cells_per_block() const
Calculates the number of cells for each block.
Definition: HOGInfo.cpp:67
size_t total_size() const override
Returns the total size of the tensor in bytes.
Definition: TensorInfo.h:278
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 PaddingSize padding() const =0
Padding of tensor.
BorderSize PaddingSize
Container for 2D padding size.
Definition: Types.h:382
unsigned int left
left of the border
Definition: Types.h:378
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.
unsigned int right
right of the border
Definition: Types.h:376
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:109
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:374
virtual size_t total_size() const =0
Returns the total size of the tensor in bytes.
size_t width
Width of the image region or rectangle.
Definition: Size2D.h:89
Size2D num_block_positions_per_image(const Size2D &image_size) const
Calculates the number of block positions for the given image size.
Definition: HOGInfo.cpp:83
Class for specifying the size of an image or rectangle.
Definition: Size2D.h:34
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:402
#define ARM_COMPUTE_ERROR_ON_COORDINATES_DIMENSIONS_GTE(p, md)
Definition: Validate.h:244
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:245
Store the tensor&#39;s metadata.
Definition: TensorInfo.h:45
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:37
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:188
const TensorShape & tensor_shape() const override
Size for each dimension of the tensor.
Definition: TensorInfo.h:262
DataType
Available data types.
Definition: Types.h:77
DataLayout
[DataLayout enum definition]
Definition: Types.h:120
size_t element_size() const override
Element size in bytes calculated as data_size() * num_channels()
Definition: TensorInfo.h:250
virtual size_t num_channels() const =0
The number of channels for each tensor element.
size_t area() const
The area of the image or rectangle calculated as (width * height)
Definition: Size2D.h:53
virtual DataLayout data_layout() const =0
Get the data layout of the tensor.