blob: 31bddbde40d3215ad8041442137d50b51f238c68 [file] [log] [blame]
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001/*
Ramy Elgammald2d93612022-12-22 15:21:03 +00002 * Copyright (c) 2016-2023 Arm Limited.
Anthony Barbier6ff3b192017-09-04 18:44:23 +01003 *
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 */
24#include "arm_compute/core/TensorInfo.h"
25
26#include "arm_compute/core/Error.h"
Anthony Barbier6ff3b192017-09-04 18:44:23 +010027#include "arm_compute/core/Helpers.h"
Michel Iwaniec00633802017-10-12 14:14:15 +010028#include "arm_compute/core/TensorInfo.h"
Anthony Barbier6ff3b192017-09-04 18:44:23 +010029#include "arm_compute/core/Validate.h"
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +010030
Sang-Hoon Park68dd25f2020-10-19 16:00:11 +010031#include "src/core/helpers/Utils.h"
Georgios Pinitas40f51a62020-11-21 03:04:18 +000032
33#include <memory>
Anthony Barbier6ff3b192017-09-04 18:44:23 +010034
Giorgio Arena63e0beb2021-09-24 14:04:27 +010035namespace arm_compute
36{
Anthony Barbier6ff3b192017-09-04 18:44:23 +010037TensorInfo::TensorInfo()
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +010038 : _total_size(0),
39 _offset_first_element_in_bytes(0),
40 _strides_in_bytes(),
41 _num_channels(0),
42 _tensor_shape(),
43 _dims_state(),
44 _data_type(DataType::UNKNOWN),
45 _format(Format::UNKNOWN),
46 _is_resizable{true},
47 _valid_region{Coordinates(), _tensor_shape},
48 _padding{0},
49 _quantization_info(),
50 _data_layout(DataLayout::NCHW),
51 _are_values_constant(true),
52 _id(invalid_tensor_id),
53 _lock_paddings(false)
Anthony Barbier6ff3b192017-09-04 18:44:23 +010054{
55}
56
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +010057TensorInfo::TensorInfo(const ITensorInfo &info) : TensorInfo()
Anthony Barbier6ff3b192017-09-04 18:44:23 +010058{
59 _total_size = info.total_size();
Anthony Barbier6ff3b192017-09-04 18:44:23 +010060 _offset_first_element_in_bytes = info.offset_first_element_in_bytes();
61 _strides_in_bytes = info.strides_in_bytes();
62 _num_channels = info.num_channels();
63 _tensor_shape = info.tensor_shape();
Georgios Pinitasb14a0f02021-01-08 03:14:31 +000064 _dims_state = info.tensor_dims_state();
Anthony Barbier6ff3b192017-09-04 18:44:23 +010065 _data_type = info.data_type();
66 _format = info.format();
67 _is_resizable = info.is_resizable();
68 _valid_region = info.valid_region();
69 _padding = info.padding();
Georgios Pinitas30902ed2017-11-14 15:32:57 +000070 _quantization_info = info.quantization_info();
Isabella Gottardid17a6772018-02-27 17:41:55 +000071 _data_layout = info.data_layout();
Giorgio Arena63e0beb2021-09-24 14:04:27 +010072 _are_values_constant = info.are_values_constant();
SiCong Li5a2bc012023-01-12 12:54:49 +000073 _id = info.id();
Ramy Elgammald2d93612022-12-22 15:21:03 +000074 _lock_paddings = info.lock_paddings();
Anthony Barbier6ff3b192017-09-04 18:44:23 +010075}
76
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +010077TensorInfo::TensorInfo(const TensorInfo &info) : TensorInfo()
SiCong Lif44bbc52022-08-29 18:25:51 +010078{
79 _total_size = info.total_size();
80 _offset_first_element_in_bytes = info.offset_first_element_in_bytes();
81 _strides_in_bytes = info.strides_in_bytes();
82 _num_channels = info.num_channels();
83 _tensor_shape = info.tensor_shape();
84 _dims_state = info.tensor_dims_state();
85 _data_type = info.data_type();
86 _format = info.format();
87 _is_resizable = info.is_resizable();
88 _valid_region = info.valid_region();
89 _padding = info.padding();
90 _quantization_info = info.quantization_info();
91 _data_layout = info.data_layout();
92 _are_values_constant = info.are_values_constant();
SiCong Li5a2bc012023-01-12 12:54:49 +000093 _id = info.id();
Ramy Elgammald2d93612022-12-22 15:21:03 +000094 _lock_paddings = false;
SiCong Lif44bbc52022-08-29 18:25:51 +010095}
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +010096TensorInfo::TensorInfo(Format format) : TensorInfo(TensorShape(), format)
Anthony Barbier6ff3b192017-09-04 18:44:23 +010097{
98}
99
100TensorInfo::TensorInfo(unsigned int width, unsigned int height, Format format)
101 : TensorInfo(TensorShape(width, height), format)
102{
103}
104
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +0100105TensorInfo::TensorInfo(const TensorShape &tensor_shape, Format format) : TensorInfo()
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100106{
107 init(tensor_shape, format);
108}
109
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +0100110TensorInfo::TensorInfo(size_t num_channels, DataType data_type) : TensorInfo()
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100111{
Vidhya Sudhan Loganathan7485d5a2018-07-04 09:34:00 +0100112 init(TensorShape(), num_channels, data_type);
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100113}
114
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +0100115TensorInfo::TensorInfo(const TensorShape &tensor_shape, size_t num_channels, DataType data_type) : TensorInfo()
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100116{
Vidhya Sudhan Loganathan7485d5a2018-07-04 09:34:00 +0100117 init(tensor_shape, num_channels, data_type);
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100118}
119
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +0100120TensorInfo::TensorInfo(const TensorShape &tensor_shape,
121 size_t num_channels,
122 DataType data_type,
123 QuantizationInfo quantization_info)
Michel Iwaniec00633802017-10-12 14:14:15 +0100124 : TensorInfo()
125{
Vidhya Sudhan Loganathan7485d5a2018-07-04 09:34:00 +0100126 init(tensor_shape, num_channels, data_type);
Michalis Spyrou18574c12019-06-05 10:51:07 +0100127 _quantization_info = std::move(quantization_info);
Michel Iwaniec00633802017-10-12 14:14:15 +0100128}
129
Manuel Bottini581f1782019-11-13 17:24:43 +0000130TensorInfo::TensorInfo(const TensorShape &tensor_shape, size_t num_channels, DataType data_type, DataLayout data_layout)
131 : TensorInfo()
132{
133 init(tensor_shape, num_channels, data_type);
134 _data_layout = data_layout;
135}
136
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100137void TensorInfo::init(Format format)
138{
139 init(TensorShape(), format);
140}
141
142void TensorInfo::init(const TensorShape &tensor_shape, Format format)
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);
148
149 _format = format;
150}
151
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +0100152void TensorInfo::init(const TensorShape &tensor_shape,
153 Format format,
154 const Strides &strides_in_bytes,
155 size_t offset_first_element_in_bytes,
156 size_t total_size_in_bytes)
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100157{
158 size_t num_channels = num_channels_from_format(format);
159 const DataType type = data_type_from_format(format);
160
161 init(tensor_shape, num_channels, type, strides_in_bytes, offset_first_element_in_bytes, total_size_in_bytes);
162
163 _format = format;
164}
165
Vidhya Sudhan Loganathan7485d5a2018-07-04 09:34:00 +0100166void TensorInfo::init(size_t num_channels, DataType data_type)
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100167{
Vidhya Sudhan Loganathan7485d5a2018-07-04 09:34:00 +0100168 init(TensorShape(), num_channels, data_type);
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100169}
170
Vidhya Sudhan Loganathan7485d5a2018-07-04 09:34:00 +0100171void TensorInfo::init(const TensorShape &tensor_shape, size_t num_channels, DataType data_type)
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100172{
173 ARM_COMPUTE_ERROR_ON(num_channels == 0);
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100174
Vidhya Sudhan Loganathan7485d5a2018-07-04 09:34:00 +0100175 _data_type = data_type;
176 _num_channels = num_channels;
177 _format = Format::UNKNOWN;
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100178
179 set_tensor_shape(tensor_shape);
180}
181
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +0100182void TensorInfo::init(const TensorShape &tensor_shape,
183 size_t num_channels,
184 DataType data_type,
185 const Strides &strides_in_bytes,
186 size_t offset_first_element_in_bytes,
187 size_t total_size_in_bytes)
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100188{
189 ARM_COMPUTE_ERROR_ON(num_channels == 0);
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100190
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100191 _data_type = data_type;
192 _num_channels = num_channels;
193 _format = Format::UNKNOWN;
194 _tensor_shape = tensor_shape;
195 _offset_first_element_in_bytes = offset_first_element_in_bytes;
196 _strides_in_bytes = strides_in_bytes;
197 _total_size = total_size_in_bytes;
198
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +0100199 _valid_region = ValidRegion{Coordinates(), _tensor_shape};
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100200}
201
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100202size_t TensorInfo::init_auto_padding(const TensorShape &tensor_shape, Format format)
203{
204 const size_t num_channels = num_channels_from_format(format);
205 const DataType type = data_type_from_format(format);
206 size_t total_size = init_auto_padding(tensor_shape, num_channels, type);
207
208 _format = format;
209
210 return total_size;
211}
212
Vidhya Sudhan Loganathan7485d5a2018-07-04 09:34:00 +0100213size_t TensorInfo::init_auto_padding(const TensorShape &tensor_shape, size_t num_channels, DataType data_type)
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100214{
215 ARM_COMPUTE_ERROR_ON(num_channels == 0);
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100216
Vidhya Sudhan Loganathan7485d5a2018-07-04 09:34:00 +0100217 _data_type = data_type;
218 _num_channels = num_channels;
219 _format = Format::UNKNOWN;
220 _tensor_shape = tensor_shape;
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100221
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +0100222 _valid_region = ValidRegion{Coordinates(), _tensor_shape};
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100223
224 auto_padding();
225
226 return _total_size;
227}
228
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100229bool TensorInfo::auto_padding()
230{
231 ARM_COMPUTE_ERROR_ON(!_is_resizable);
232
233 // Some kernels compute 32 elements at the time, worst case scenario they
234 // will read 32 values after the last element
235 const size_t extra_pad_x = _tensor_shape.num_dimensions() < 1 ? 0 : 32;
236 const size_t pad_x = _tensor_shape.num_dimensions() < 1 ? 0 : 4;
237 const size_t pad_y = _tensor_shape.num_dimensions() < 2 ? 0 : 4;
238
239 return extend_padding(PaddingSize(pad_y, pad_x + extra_pad_x, pad_y, pad_x));
240}
241
242std::tuple<Strides, size_t, size_t> TensorInfo::calculate_padding_requirements(const PaddingSize &padding)
243{
244 // Calculate resulting stride for the X, Y and Z dimension
245 const size_t stride_x = element_size();
246 const size_t stride_y = (padding.left + _tensor_shape[0] + padding.right) * stride_x;
247 const size_t stride_z = (padding.top + _tensor_shape[1] + padding.bottom) * stride_y;
248
249 Strides required_strides;
250 size_t required_total_size = 0;
251 const size_t required_offset_first_element = padding.left * stride_x + padding.top * stride_y;
252
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +0100253 switch (_tensor_shape.num_dimensions())
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100254 {
255 case 0:
256 {
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +0100257 if (_tensor_shape.total_size() > 0)
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100258 {
Gian Marco Iodiceee94f6a2017-09-11 17:38:02 +0100259 required_strides = Strides(stride_x, stride_x);
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100260 required_total_size = stride_z;
261 }
262 break;
263 }
264 case 1:
Gian Marco Iodiceee94f6a2017-09-11 17:38:02 +0100265 required_strides = compute_strides(*this, stride_x, stride_y);
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100266 required_total_size = stride_z;
267 break;
268 case 2:
269 required_strides = compute_strides(*this, stride_x, stride_y);
270 required_total_size = stride_z;
271 break;
272 default:
273 {
274 required_strides = compute_strides(*this, stride_x, stride_y, stride_z);
275
276 const unsigned int idx_last_dimension = _tensor_shape.num_dimensions() - 1;
277
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +0100278 required_total_size =
279 static_cast<size_t>(_tensor_shape[idx_last_dimension]) * required_strides[idx_last_dimension];
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100280 break;
281 }
282 }
283
284 return std::make_tuple(required_strides, required_offset_first_element, required_total_size);
285}
286
Ramy Elgammald2d93612022-12-22 15:21:03 +0000287ITensorInfo &TensorInfo::set_lock_paddings(bool flag)
288{
289 _lock_paddings = flag;
290 return *this;
291}
292
293bool TensorInfo::lock_paddings() const
294{
295 return _lock_paddings;
296}
297
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100298bool TensorInfo::extend_padding(const PaddingSize &padding)
299{
Ramy Elgammald2d93612022-12-22 15:21:03 +0000300 ARM_COMPUTE_ERROR_ON(_lock_paddings);
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100301 ARM_COMPUTE_ERROR_ON(!_is_resizable);
302
303 bool updated = false;
304
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +0100305 if (padding.top > _padding.top)
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100306 {
307 _padding.top = padding.top;
308 updated = true;
309 }
310
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +0100311 if (padding.right > _padding.right)
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100312 {
313 _padding.right = padding.right;
314 updated = true;
315 }
316
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +0100317 if (padding.bottom > _padding.bottom)
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100318 {
319 _padding.bottom = padding.bottom;
320 updated = true;
321 }
322
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +0100323 if (padding.left > _padding.left)
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100324 {
325 _padding.left = padding.left;
326 updated = true;
327 }
328
329 std::tie(_strides_in_bytes, _offset_first_element_in_bytes, _total_size) = calculate_padding_requirements(_padding);
330
331 return updated;
332}
333
Georgios Pinitas283c1792017-11-10 18:14:06 +0000334std::unique_ptr<ITensorInfo> TensorInfo::clone() const
335{
Georgios Pinitas40f51a62020-11-21 03:04:18 +0000336 return std::make_unique<TensorInfo>(*this);
Georgios Pinitas283c1792017-11-10 18:14:06 +0000337}
338
339ITensorInfo &TensorInfo::set_data_type(DataType data_type)
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100340{
341 _data_type = data_type;
342 _format = Format::UNKNOWN;
Giorgio Arenabb54e4e2018-04-05 17:20:34 +0100343 return set_tensor_shape(tensor_shape()); // Force total size and strides to update
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100344}
345
Georgios Pinitas283c1792017-11-10 18:14:06 +0000346ITensorInfo &TensorInfo::set_num_channels(int num_channels)
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100347{
348 _num_channels = num_channels;
349 _format = Format::UNKNOWN;
Georgios Pinitas283c1792017-11-10 18:14:06 +0000350 return *this;
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100351}
352
Georgios Pinitas283c1792017-11-10 18:14:06 +0000353ITensorInfo &TensorInfo::set_format(Format format)
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100354{
355 _format = format;
356
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +0100357 if (_data_type == DataType::UNKNOWN)
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100358 {
359 _num_channels = num_channels_from_format(format);
360 _data_type = data_type_from_format(format);
361 }
362 else
363 {
364 ARM_COMPUTE_ERROR_ON(num_channels_from_format(format) != _num_channels);
365 ARM_COMPUTE_ERROR_ON(data_type_from_format(format) != _data_type);
366 }
Georgios Pinitas283c1792017-11-10 18:14:06 +0000367 return *this;
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100368}
369
Diego Lopez Recas35ceeb22017-12-04 18:56:10 +0000370ITensorInfo &TensorInfo::set_tensor_shape(const TensorShape &shape)
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100371{
372 _tensor_shape = shape;
373 _offset_first_element_in_bytes = 0;
374 _strides_in_bytes = compute_strides(*this);
375
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +0100376 if (_tensor_shape.num_dimensions() == 0)
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100377 {
378 _total_size = _strides_in_bytes[0];
379 }
380 else
381 {
382 const unsigned int idx_last_dimension = _tensor_shape.num_dimensions() - 1;
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +0100383 _total_size = static_cast<size_t>(_tensor_shape[idx_last_dimension]) * _strides_in_bytes[idx_last_dimension];
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100384 }
385
Georgios Pinitas652bde52018-01-10 15:33:28 +0000386 std::tie(_strides_in_bytes, _offset_first_element_in_bytes, _total_size) = calculate_padding_requirements(_padding);
387
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +0100388 _valid_region = ValidRegion{Coordinates(), _tensor_shape};
Georgios Pinitas283c1792017-11-10 18:14:06 +0000389 return *this;
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100390}
391
Georgios Pinitasb14a0f02021-01-08 03:14:31 +0000392ITensorInfo &TensorInfo::set_tensor_dims_state(const TensorDimsState &state)
393{
394 _dims_state = state;
395 return *this;
396}
397
Diego Lopez Recas35ceeb22017-12-04 18:56:10 +0000398ITensorInfo &TensorInfo::set_quantization_info(const QuantizationInfo &quantization_info)
Georgios Pinitas283c1792017-11-10 18:14:06 +0000399{
400 _quantization_info = quantization_info;
401 return *this;
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100402}
403
Isabella Gottardid17a6772018-02-27 17:41:55 +0000404ITensorInfo &TensorInfo::set_data_layout(const DataLayout &data_layout)
405{
406 _data_layout = data_layout;
407 return *this;
408}
409
Georgios Pinitas30902ed2017-11-14 15:32:57 +0000410ITensorInfo &TensorInfo::reset_padding()
411{
412 _padding = PaddingSize();
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +0100413 if (((_format != Format::UNKNOWN) || (_data_type != DataType::UNKNOWN)) && _total_size != 0)
Georgios Pinitas30902ed2017-11-14 15:32:57 +0000414 {
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +0100415 std::tie(_strides_in_bytes, _offset_first_element_in_bytes, _total_size) =
416 calculate_padding_requirements(_padding);
Georgios Pinitas30902ed2017-11-14 15:32:57 +0000417 }
418 return *this;
419}
420
Michalis Spyrou7c60c992019-10-10 14:33:47 +0100421int32_t TensorInfo::offset_element_in_bytes(const Coordinates &pos) const
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100422{
423 ARM_COMPUTE_ERROR_ON_COORDINATES_DIMENSIONS_GTE(pos, _tensor_shape.num_dimensions());
424
Michalis Spyrou7c60c992019-10-10 14:33:47 +0100425 int32_t offset = _offset_first_element_in_bytes;
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100426
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +0100427 for (size_t i = 0; i < _tensor_shape.num_dimensions(); ++i)
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100428 {
429 offset += pos[i] * _strides_in_bytes[i];
430 }
431
432 return offset;
433}
Giorgio Arena63e0beb2021-09-24 14:04:27 +0100434} // namespace arm_compute