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