Compute Library
 20.02.1
TensorInfo.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2016-2019 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"
32 
33 using namespace arm_compute;
34 
36  : _total_size(0), _offset_first_element_in_bytes(0), _strides_in_bytes(), _num_channels(0), _tensor_shape(), _data_type(DataType::UNKNOWN), _format(Format::UNKNOWN), _is_resizable{ true }, _is_dynamic{ false },
37  _valid_region{ Coordinates(), _tensor_shape }, _padding{ 0 }, _quantization_info(), _data_layout(DataLayout::NCHW)
38 {
39 }
40 
42  : TensorInfo()
43 {
44  _total_size = info.total_size();
45  _offset_first_element_in_bytes = info.offset_first_element_in_bytes();
46  _strides_in_bytes = info.strides_in_bytes();
47  _num_channels = info.num_channels();
48  _tensor_shape = info.tensor_shape();
49  _data_type = info.data_type();
50  _format = info.format();
51  _is_resizable = info.is_resizable();
52  _is_dynamic = info.is_dynamic();
53  _valid_region = info.valid_region();
54  _padding = info.padding();
55  _quantization_info = info.quantization_info();
56  _data_layout = info.data_layout();
57 }
58 
60  : TensorInfo(TensorShape(), format)
61 {
62 }
63 
64 TensorInfo::TensorInfo(unsigned int width, unsigned int height, Format format)
65  : TensorInfo(TensorShape(width, height), format)
66 {
67 }
68 
69 TensorInfo::TensorInfo(const TensorShape &tensor_shape, Format format)
70  : TensorInfo()
71 {
73 }
74 
76  : TensorInfo()
77 {
79 }
80 
81 TensorInfo::TensorInfo(const TensorShape &tensor_shape, size_t num_channels, DataType data_type)
82  : TensorInfo()
83 {
85 }
86 
87 TensorInfo::TensorInfo(const TensorShape &tensor_shape, size_t num_channels, DataType data_type, QuantizationInfo quantization_info)
88  : TensorInfo()
89 {
91  _quantization_info = std::move(quantization_info);
92 }
93 
94 TensorInfo::TensorInfo(const TensorShape &tensor_shape, size_t num_channels, DataType data_type, DataLayout data_layout)
95  : TensorInfo()
96 {
98  _data_layout = data_layout;
99 }
100 
101 TensorInfo::TensorInfo(const HOGInfo &hog_info, unsigned int width, unsigned int height)
102  : TensorInfo()
103 {
104  init(hog_info, width, height);
105 }
106 
108 {
109  init(TensorShape(), format);
110 }
111 
112 void TensorInfo::init(const TensorShape &tensor_shape, Format format)
113 {
116 
118 
119  _format = format;
120 }
121 
122 void TensorInfo::init(const TensorShape &tensor_shape, Format format,
123  const Strides &strides_in_bytes, size_t offset_first_element_in_bytes,
124  size_t total_size_in_bytes)
125 {
128 
130 
131  _format = format;
132 }
133 
134 void TensorInfo::init(size_t num_channels, DataType data_type)
135 {
137 }
138 
139 void TensorInfo::init(const TensorShape &tensor_shape, size_t num_channels, DataType data_type)
140 {
142 
143  _data_type = data_type;
144  _num_channels = num_channels;
145  _format = Format::UNKNOWN;
146 
148 }
149 
150 void TensorInfo::init(const TensorShape &tensor_shape, size_t num_channels, DataType data_type,
151  const Strides &strides_in_bytes, size_t offset_first_element_in_bytes,
152  size_t total_size_in_bytes)
153 {
155 
156  _data_type = data_type;
157  _num_channels = num_channels;
158  _format = Format::UNKNOWN;
159  _tensor_shape = tensor_shape;
160  _offset_first_element_in_bytes = offset_first_element_in_bytes;
161  _strides_in_bytes = strides_in_bytes;
162  _total_size = total_size_in_bytes;
163 
164  _valid_region = ValidRegion{ Coordinates(), _tensor_shape };
165 }
166 
167 void TensorInfo::init(const HOGInfo &hog_info, unsigned int width, unsigned int height)
168 {
169  // Number of cells for each block
170  const Size2D num_cells_per_block = hog_info.num_cells_per_block();
171 
172  // Tensor Size = (Number of horizontal block positions) * (Number of vertical block positions)
173  const Size2D num_block_positions_per_img = hog_info.num_block_positions_per_image(Size2D(width, height));
174 
175  // Number of tensor channels = (Number of cells per block) * (Number of bins per cell)
176  const size_t num_channels = num_cells_per_block.area() * hog_info.num_bins();
177 
178  init(TensorShape(num_block_positions_per_img.width, num_block_positions_per_img.height), num_channels, DataType::F32);
179 }
180 
181 size_t TensorInfo::init_auto_padding(const TensorShape &tensor_shape, Format format)
182 {
186 
187  _format = format;
188 
189  return total_size;
190 }
191 
192 size_t TensorInfo::init_auto_padding(const TensorShape &tensor_shape, size_t num_channels, DataType data_type)
193 {
195 
196  _data_type = data_type;
197  _num_channels = num_channels;
198  _format = Format::UNKNOWN;
199  _tensor_shape = tensor_shape;
200 
201  _valid_region = ValidRegion{ Coordinates(), _tensor_shape };
202 
203  auto_padding();
204 
205  return _total_size;
206 }
207 
208 size_t TensorInfo::init_auto_padding(const HOGInfo &hog_info, unsigned int width, unsigned int height)
209 {
210  // Number of cells for each block
211  const Size2D num_cells_per_block = hog_info.num_cells_per_block();
212 
213  // Tensor Size = (Number of horizontal block positions) * (Number of vertical block positions)
214  const Size2D num_block_positions_per_img = hog_info.num_block_positions_per_image(Size2D(width, height));
215 
216  // Number of tensor channels = (Number of cells per block) * (Number of bins per cell)
217  const size_t num_channels = num_cells_per_block.area() * hog_info.num_bins();
218 
219  return init_auto_padding(TensorShape(num_block_positions_per_img.width, num_block_positions_per_img.height), num_channels, DataType::F32);
220 }
221 
223 {
224  ARM_COMPUTE_ERROR_ON(!_is_resizable);
225 
226  // Some kernels compute 32 elements at the time, worst case scenario they
227  // will read 32 values after the last element
228  const size_t extra_pad_x = _tensor_shape.num_dimensions() < 1 ? 0 : 32;
229  const size_t pad_x = _tensor_shape.num_dimensions() < 1 ? 0 : 4;
230  const size_t pad_y = _tensor_shape.num_dimensions() < 2 ? 0 : 4;
231 
232  return extend_padding(PaddingSize(pad_y, pad_x + extra_pad_x, pad_y, pad_x));
233 }
234 
235 std::tuple<Strides, size_t, size_t> TensorInfo::calculate_padding_requirements(const PaddingSize &padding)
236 {
237  // Calculate resulting stride for the X, Y and Z dimension
238  const size_t stride_x = element_size();
239  const size_t stride_y = (padding.left + _tensor_shape[0] + padding.right) * stride_x;
240  const size_t stride_z = (padding.top + _tensor_shape[1] + padding.bottom) * stride_y;
241 
242  Strides required_strides;
243  size_t required_total_size = 0;
244  const size_t required_offset_first_element = padding.left * stride_x + padding.top * stride_y;
245 
246  switch(_tensor_shape.num_dimensions())
247  {
248  case 0:
249  {
250  if(_tensor_shape.total_size() > 0)
251  {
252  required_strides = Strides(stride_x, stride_x);
253  required_total_size = stride_z;
254  }
255  break;
256  }
257  case 1:
258  required_strides = compute_strides(*this, stride_x, stride_y);
259  required_total_size = stride_z;
260  break;
261  case 2:
262  required_strides = compute_strides(*this, stride_x, stride_y);
263  required_total_size = stride_z;
264  break;
265  default:
266  {
267  required_strides = compute_strides(*this, stride_x, stride_y, stride_z);
268 
269  const unsigned int idx_last_dimension = _tensor_shape.num_dimensions() - 1;
270 
271  required_total_size = _tensor_shape[idx_last_dimension] * required_strides[idx_last_dimension];
272  break;
273  }
274  }
275 
276  return std::make_tuple(required_strides, required_offset_first_element, required_total_size);
277 }
278 
280 {
281  ARM_COMPUTE_ERROR_ON(!_is_resizable);
282 
283  bool updated = false;
284 
285  if(padding.top > _padding.top)
286  {
287  _padding.top = padding.top;
288  updated = true;
289  }
290 
291  if(padding.right > _padding.right)
292  {
293  _padding.right = padding.right;
294  updated = true;
295  }
296 
297  if(padding.bottom > _padding.bottom)
298  {
299  _padding.bottom = padding.bottom;
300  updated = true;
301  }
302 
303  if(padding.left > _padding.left)
304  {
305  _padding.left = padding.left;
306  updated = true;
307  }
308 
309  std::tie(_strides_in_bytes, _offset_first_element_in_bytes, _total_size) = calculate_padding_requirements(_padding);
310 
311  return updated;
312 }
313 
314 std::unique_ptr<ITensorInfo> TensorInfo::clone() const
315 {
316  return support::cpp14::make_unique<TensorInfo>(*this);
317 }
318 
320 {
321  _data_type = data_type;
322  _format = Format::UNKNOWN;
323  return set_tensor_shape(tensor_shape()); // Force total size and strides to update
324 }
325 
327 {
328  _num_channels = num_channels;
329  _format = Format::UNKNOWN;
330  return *this;
331 }
332 
334 {
335  _format = format;
336 
337  if(_data_type == DataType::UNKNOWN)
338  {
339  _num_channels = num_channels_from_format(format);
340  _data_type = data_type_from_format(format);
341  }
342  else
343  {
346  }
347  return *this;
348 }
349 
351 {
352  _tensor_shape = shape;
353  _offset_first_element_in_bytes = 0;
354  _strides_in_bytes = compute_strides(*this);
355 
356  if(_tensor_shape.num_dimensions() == 0)
357  {
358  _total_size = _strides_in_bytes[0];
359  }
360  else
361  {
362  const unsigned int idx_last_dimension = _tensor_shape.num_dimensions() - 1;
363  _total_size = _tensor_shape[idx_last_dimension] * _strides_in_bytes[idx_last_dimension];
364  }
365 
366  std::tie(_strides_in_bytes, _offset_first_element_in_bytes, _total_size) = calculate_padding_requirements(_padding);
367 
368  _valid_region = ValidRegion{ Coordinates(), _tensor_shape };
369  return *this;
370 }
371 
373 {
374  _quantization_info = quantization_info;
375  return *this;
376 }
377 
379 {
380  _data_layout = data_layout;
381  return *this;
382 }
383 
385 {
386  _padding = PaddingSize();
387  if(((_format != Format::UNKNOWN) || (_data_type != DataType::UNKNOWN)) && _total_size != 0)
388  {
389  std::tie(_strides_in_bytes, _offset_first_element_in_bytes, _total_size) = calculate_padding_requirements(_padding);
390  }
391  return *this;
392 }
393 
395 {
397 
398  int32_t offset = _offset_first_element_in_bytes;
399 
400  for(size_t i = 0; i < _tensor_shape.num_dimensions(); ++i)
401  {
402  offset += pos[i] * _strides_in_bytes[i];
403  }
404 
405  return offset;
406 }
ITensorInfo & set_format(Format format) override
Set the format of an already initialized tensor.
Definition: TensorInfo.cpp:333
__global uchar * offset(const Image *img, int x, int y)
Get the pointer position of a Image.
Definition: helpers.h:510
unsigned int top
top of the border
Definition: Types.h:349
size_t num_bins() const
The number of histogram bins for each cell.
Definition: HOGInfo.cpp:111
size_t init_auto_padding(const HOGInfo &hog_info, unsigned int width, unsigned int height)
Initialize the metadata structure for the given HOG's metadata.
Definition: TensorInfo.cpp:208
Shape of a tensor.
Definition: TensorShape.h:39
const DataLayout data_layout
Definition: Im2Col.cpp:146
size_t init_auto_padding(const TensorShape &tensor_shape, Format format)
Initialize the metadata structure for the given tensor shape and single-plane format,...
Definition: TensorInfo.cpp:181
std::unique_ptr< ITensorInfo > clone() const override
Provide a clone of the current object of class T.
Definition: TensorInfo.cpp:314
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:257
ITensorInfo & reset_padding() override
Resets the padding settings of the tensor.
Definition: TensorInfo.cpp:384
DataLayout data_layout() const override
Get the data layout of the tensor.
Definition: TensorInfo.h:315
Store the HOG'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:279
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:319
#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:482
Store the tensor's metadata.
Definition: ITensorInfo.h:40
unsigned int bottom
bottom of the border
Definition: Types.h:351
PaddingSize padding() const override
Padding of tensor.
Definition: TensorInfo.h:277
const Strides & strides_in_bytes() const override
The strides in bytes for accessing each dimension of the tensor.
Definition: TensorInfo.h:240
bool auto_padding() override
Update the offset to the first element and the strides to automatically computed values.
Definition: TensorInfo.cpp:222
Copyright (c) 2017-2020 ARM Limited.
size_t height
Height of the image region or rectangle.
Definition: Size2D.h:93
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: Helpers.h:535
Format format() const override
Colour format of the image.
Definition: TensorInfo.h:269
ITensorInfo & set_quantization_info(const QuantizationInfo &quantization_info) override
Set the quantization settings (scale and offset) of the tensor.
Definition: TensorInfo.cpp:372
DataType data_type() const override
Data type used for each element of the tensor.
Definition: TensorInfo.h:265
Quantization information.
ITensorInfo & set_data_layout(const DataLayout &data_layout) override
Set the data layout of the tensor.
Definition: TensorInfo.cpp:378
Format
Image colour formats.
Definition: Types.h:53
#define ARM_COMPUTE_ERROR_ON_COORDINATES_DIMENSIONS_GTE(p, md)
Definition: Validate.h:244
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:273
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:171
BorderSize PaddingSize
Container for 2D padding size.
Definition: Types.h:356
unsigned int left
left of the border
Definition: Types.h:352
ITensorInfo & set_num_channels(int num_channels) override
Set the number of channels to the specified value.
Definition: TensorInfo.cpp:326
unsigned int right
right of the border
Definition: Types.h:350
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:107
Strides of an item in bytes.
Definition: Strides.h:37
size_t width
Width of the image region or rectangle.
Definition: Size2D.h:92
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:122
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:394
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:244
Store the tensor'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:350
TensorInfo()
Default constructor.
Definition: TensorInfo.cpp:35
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:261
DataType
Available data types.
Definition: Types.h:75
DataLayout
[DataLayout enum definition]
Definition: Types.h:117
size_t element_size() const override
Element size in bytes calculated as data_size() * num_channels()
Definition: TensorInfo.h:249
size_t area() const
The area of the image or rectangle calculated as (width * height)
Definition: Size2D.h:53