Compute Library
 23.08
ShapeCalculator.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2017-2023 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  */
24 #ifndef ACL_ARM_COMPUTE_CORE_UTILS_MISC_SHAPECALCULATOR
25 #define ACL_ARM_COMPUTE_CORE_UTILS_MISC_SHAPECALCULATOR
26 
30 #include "arm_compute/core/Utils.h"
33 
35 
36 #include <cmath>
37 
38 namespace arm_compute
39 {
40 namespace misc
41 {
42 namespace shape_calculator
43 {
44 /** Calculate the output tensor shape for the reduce mean operation
45  *
46  * @param[in] input Input tensor shape
47  * @param[in] reduction_axis Reduction axis
48  * @param[in] keep_dims Flag to indicate if dimensions are kept
49  *
50  * @return the calculated shape
51  */
52 inline TensorShape calculate_reduce_mean_shape(ITensorInfo *input, const Coordinates &reduction_axis, bool keep_dims)
53 {
54  const int reduction_ops = reduction_axis.num_dimensions();
55  Coordinates axis_local = reduction_axis;
56  const int input_dims = input->num_dimensions();
57  convert_negative_axis(axis_local, input_dims);
58  TensorShape out_shape = input->tensor_shape();
59  // Configure reshape layer if we want to drop the dimensions
60  if(!keep_dims)
61  {
62  // We have to sort the reduction axis vectors in order for remove_dimension
63  // to work properly
64  std::sort(axis_local.begin(), axis_local.begin() + reduction_ops);
65  for(int i = 0; i < reduction_ops; ++i)
66  {
67  out_shape.remove_dimension(axis_local[i] - i, false);
68  }
69  return out_shape;
70  }
71  else
72  {
73  for(int i = 0; i < reduction_ops; ++i)
74  {
75  out_shape.set(axis_local[i], 1);
76  }
77  return out_shape;
78  }
79 }
80 /** Calculate the output tensor shape of a vector input given the convolution dimensions
81  *
82  * @param[in] input Input tensor shape
83  * @param[in] conv_w Convolution width
84  * @param[in] conv_h Convolution height
85  * @param[in] data_layout Data layout
86  *
87  * @return the calculated shape
88  */
89 inline TensorShape compute_vector_to_tensor_output_shape(const TensorShape &input, size_t conv_w, size_t conv_h, const DataLayout &data_layout)
90 {
94 
96  output_shape.set(idx_w, conv_w);
97  output_shape.set(idx_h, conv_h);
98  output_shape.set(idx_c, input.x() / (conv_w * conv_h));
99 
100  return output_shape;
101 }
102 
103 /** Calculate the permuted shape of an input given a permutation vector
104  *
105  * @param[in] input Input tensor info
106  * @param[in] perm Permutation vector
107  *
108  * @return the calculated shape
109  */
111 {
112  TensorShape output_shape = input.tensor_shape();
113  permute(output_shape, perm);
114  return output_shape;
115 }
116 
117 /** Calculate the output shape of the reorg layer given a stride
118  *
119  * @param[in] input Input tensor info
120  * @param[in] stride Stride
121  *
122  * @return the calculated shape
123  */
125 {
128  const size_t idx_channel = get_data_layout_dimension_index(input.data_layout(), DataLayoutDimension::CHANNEL);
129 
130  ARM_COMPUTE_ERROR_ON(stride <= 0);
131  ARM_COMPUTE_ERROR_ON_MSG((input.tensor_shape()[idx_width] % stride != 0), "The width of the input tensor must be a multiple of stride");
132  ARM_COMPUTE_ERROR_ON_MSG((input.tensor_shape()[idx_height] % stride != 0), "The height of the input tensor must be a multiple of stride");
133 
134  TensorShape output_shape{ input.tensor_shape() };
135 
138  output_shape.set(idx_channel, output_shape[idx_channel] * stride * stride);
139 
140  return output_shape;
141 }
142 
143 /** Calculate the reshaped shape of the weights
144  *
145  * @param[in] weights Weights tensor info
146  * @param[in] has_bias (Optional) Set to true if there is bias
147  * @param[in] num_groups (Optional) Number of groups
148  *
149  * @return the calculated shape of the reshaped weights
150  */
151 inline TensorShape compute_weights_reshaped_shape(const ITensorInfo &weights, bool has_bias = false, unsigned int num_groups = 1)
152 {
153  // Number of groups greater than one are only supported for NCHW data layout, and the number of weights must be a multiple of it.
156  ARM_COMPUTE_ERROR_ON((weights.dimension(3) % num_groups) != 0);
157 
158  // Calculate output shape
159  TensorShape weights_reshaped{ weights.tensor_shape() };
160  weights_reshaped.set(3, weights_reshaped[3] / num_groups);
161 
162  weights_reshaped.collapse(3);
163  const size_t tmp_dim = weights_reshaped[0];
164  weights_reshaped.set(0, weights_reshaped[1]);
165  weights_reshaped.set(1, tmp_dim + (has_bias ? 1 : 0));
166  if(weights.num_dimensions() < 5)
167  {
168  weights_reshaped.set(2, num_groups);
169  }
170 
171  return weights_reshaped;
172 }
173 
174 /** Calculate the Left Hand Side matrix reshaped shape
175  *
176  * @param[in] a Input tensor info
177  * @param[in] lhs_info Left Hand Side matrix information
178  * @param[in] reinterpret_input_as_3d (Optional) Set to true if the input need to be interpreted as 3d
179  *
180  * @return the calculated shape
181  */
182 inline TensorShape compute_lhs_reshaped_shape(const ITensorInfo &a, const GEMMLHSMatrixInfo &lhs_info, bool reinterpret_input_as_3d = false)
183 {
187 
188  // Input width/height
189  const unsigned int input_width = a.dimension(0);
190  const unsigned int input_height = reinterpret_input_as_3d ? a.dimension(1) * a.dimension(2) : a.dimension(1);
191 
192  // Number of horizontal/vertical blocks in the input tensor
193  const unsigned int num_horiz_blocks = std::ceil(input_width / static_cast<float>(lhs_info.k0));
194  const unsigned int num_vert_blocks = std::ceil(input_height / static_cast<float>(lhs_info.m0));
195 
196  // Block size
197  const unsigned int block_size = lhs_info.m0 * lhs_info.k0;
198 
199  // Output width/height
200  const unsigned int output_width = block_size * num_horiz_blocks * lhs_info.v0;
201  const unsigned int output_height = std::ceil(num_vert_blocks / static_cast<float>(lhs_info.v0));
202 
203  TensorShape lhs_shape{ a.tensor_shape() };
204  lhs_shape.set(0, output_width);
205  lhs_shape.set(1, output_height);
206 
207  if((reinterpret_input_as_3d) && (lhs_shape.num_dimensions() > 2))
208  {
209  // When the data format is NHWC and the shapes are Nx1x1
210  // the tensor shape num_dimensions is automatically set to 1 instead of 3.
211  // To avoid failures by removing a dimension that doesn't exist
212  // check if the number of dimensions is greater than 2.
213  lhs_shape.remove_dimension(2);
214  }
215 
216  return lhs_shape;
217 }
218 
219 /** Calculate the Right Hand Side matrix reshaped shape
220  *
221  * @param[in] a Input tensor info
222  * @param[in] rhs_info Right Hand Side matrix information
223  *
224  * @return the calculated shape
225  */
227 {
231 
232  // Input width/height
233  const unsigned int input_width = a.dimension(0);
234  const unsigned int input_height = a.dimension(1);
235 
236  // Number of horizontal/vertical blocks in the input tensor
237  const unsigned int num_horiz_blocks = std::ceil(input_width / static_cast<float>(rhs_info.n0));
238  const unsigned int num_vert_blocks = std::ceil(input_height / static_cast<float>(rhs_info.k0));
239 
240  // Block size
241  const unsigned int block_size = rhs_info.n0 * rhs_info.k0;
242 
243  // Output width/height
244  const unsigned int output_width = block_size * num_vert_blocks * rhs_info.h0;
245  const unsigned int output_height = std::ceil(num_horiz_blocks / static_cast<float>(rhs_info.h0));
246 
247  TensorShape rhs_shape{ a.tensor_shape() };
248  rhs_shape.set(0, output_width);
249  rhs_shape.set(1, output_height);
250 
251  return rhs_shape;
252 }
253 
254 /** Calculate the interleaved shape of an input tensor
255  *
256  * @param[in] a Input tensor info
257  * @param[in] mult_interleave4x4_height (Optional) Interleave4x4 height
258  * @param[in] reinterpret_input_as_3d (Optional) Set to true if the input need to be interpreted as 3d
259  *
260  * @return the calculated shape
261  */
262 inline TensorShape compute_interleaved_shape(const ITensorInfo &a, int mult_interleave4x4_height = 1, bool reinterpret_input_as_3d = false)
263 {
264  // The interleaved output matrix will have the following shape: [ a_height * W, ceil(a_width / W) ] where W = 4 * mult_interleave4x4_height
265  ARM_COMPUTE_ERROR_ON(mult_interleave4x4_height < 1);
266  const int interleave_width = 4 * mult_interleave4x4_height;
267  TensorShape shape_interleaved_a{ a.tensor_shape() };
268  shape_interleaved_a.set(0, a.dimension(0) * interleave_width);
269  if(reinterpret_input_as_3d)
270  {
271  const int M = a.dimension(1) * a.dimension(2);
272  const int height = std::ceil(M / static_cast<float>(interleave_width));
273  shape_interleaved_a.set(1, height);
274 
275  // When the data format is NHWC and the shapes are Nx1x1
276  // the tensor shape num_dimensions is automatically set to 1 instead of 3.
277  // To avoid failures by removing a dimension that doesn't exist
278  // check if the number of dimensions is greater than 2.
279  if(shape_interleaved_a.num_dimensions() > 2)
280  {
281  shape_interleaved_a.remove_dimension(2);
282  }
283  }
284  else
285  {
286  shape_interleaved_a.set(1, std::ceil(a.dimension(1) / static_cast<float>(interleave_width)));
287  }
288 
289  return shape_interleaved_a;
290 }
291 
292 /** Calculate the transposed 1xW shape
293  *
294  * @param[in] b Input tensor info
295  *
296  * @return the calculated shape
297  */
299 {
300  // The transpose1xW output matrix will have the following shape: [ b_height * 16, ceil(b_width / 16.0f) ]
301  TensorShape shape_transposed1xW_b{ b.tensor_shape() };
302  shape_transposed1xW_b.set(0, b.dimension(1) * 16);
303  shape_transposed1xW_b.set(1, std::ceil(b.dimension(0) / 16.f));
304 
305  return shape_transposed1xW_b;
306 }
307 
308 /** Calculate the transposed 1xW width element shape
309  *
310  * @param[in] b Input tensor info
311  * @param[in] mult_transpose1xW_width (Optional) Transpose1xW width
312  *
313  * @return the calculated shape
314  */
315 inline TensorShape compute_transpose1xW_with_element_size_shape(const ITensorInfo &b, int mult_transpose1xW_width = 1)
316 {
317  // Note: mult_transpose1xW_width expresses the number of chunks with size 1x(W) we want to store on the same row
318  // The transpose1xW output matrix will have the following shape:
319  // [ b_height * W, ceil(b_width / W) ] where W = (16 / element size of the tensor) * mult_transpose1xW_width
320  ARM_COMPUTE_ERROR_ON(mult_transpose1xW_width < 1);
321  TensorShape shape_transposed1xW_b{ b.tensor_shape() };
322  const size_t transpose_width = (16 / b.element_size()) * mult_transpose1xW_width;
323  shape_transposed1xW_b.set(0, b.dimension(1) * transpose_width);
324  shape_transposed1xW_b.set(1, static_cast<size_t>(std::ceil(b.dimension(0) / static_cast<float>(transpose_width))));
325 
326  return shape_transposed1xW_b;
327 }
328 
329 /** Calculate the reductionA shape used in GEMMLowp
330  *
331  * @param[in] b Input tensor info
332  *
333  * @return the calculated shape
334  */
336 {
337  TensorShape shape_vector_sum_col{ b.tensor_shape() };
338  if(shape_vector_sum_col.num_dimensions() > 1)
339  {
340  shape_vector_sum_col.remove_dimension(1);
341  }
342 
343  return shape_vector_sum_col;
344 }
345 
346 /** Calculate the reductionB shape used in GEMMLowp
347  *
348  * @param[in] a Input tensor info
349  *
350  * @return the calculated shape
351  */
353 {
354  TensorShape shape_vector_sum_row{ a.tensor_shape() };
355  shape_vector_sum_row.set(Window::DimX, a.dimension(1));
356  if(shape_vector_sum_row.num_dimensions() > 1)
357  {
358  shape_vector_sum_row.remove_dimension(1);
359  }
360 
361  return shape_vector_sum_row;
362 }
363 
364 /** Calculate the Col2Im shape
365  *
366  * @param[in] input Input tensor info
367  * @param[in] convolved_dims Convolved dimensions
368  * @param[in] batch_size_on_z True if batch size is on z axis
369  * @param[in] num_groups (Optional) Number of groups when performing a grouped convolution
370  *
371  * @return the calculated shape
372  */
373 inline TensorShape compute_col2im_shape(const ITensorInfo &input, const Size2D &convolved_dims, bool batch_size_on_z, unsigned int num_groups = 1)
374 {
376  ARM_COMPUTE_ERROR_ON(input.tensor_shape()[1] != (convolved_dims.area()));
377  ARM_COMPUTE_ERROR_ON((num_groups > 1) && input.tensor_shape()[2] != num_groups);
378 
379  const DataLayout data_layout = input.data_layout();
383 
384  TensorShape col2im_shape{ input.tensor_shape() };
385  // If batches start on 3rd dimension shift dimensions right by 1 to retain upper tensor shape,
386  // as first three will be override by H,W,C data
387  if(batch_size_on_z && num_groups == 1)
388  {
389  col2im_shape.shift_right(1);
390  }
391  col2im_shape.set(width_idx, convolved_dims.width);
392  col2im_shape.set(height_idx, convolved_dims.height);
393  col2im_shape.set(channel_idx, input.tensor_shape()[0] * num_groups);
394 
395  return col2im_shape;
396 }
397 
398 /** Calculate the transposed shape of a tensor
399  *
400  * @param[in] input Input tensor info
401  *
402  * @return the calculated shape
403  */
405 {
406  TensorShape shape_transposed{ input.tensor_shape() };
407 
408  shape_transposed.set(0, input.dimension(1), false);
409  shape_transposed.set(1, input.dimension(0), false);
410 
411  return shape_transposed;
412 }
413 
414 /** Calculate the depthwise convolution output shape of a tensor
415  *
416  * @param[in] input Input tensor info
417  * @param[in] weights Weights tensor info
418  * @param[in] info Convolution info
419  *
420  * @return the calculated shape
421  */
423 {
424  const TensorShape input_shape{ input.tensor_shape() };
425  const TensorShape weights_shape{ weights.tensor_shape() };
426 
427  const DataLayout data_layout = input.data_layout();
431 
432  const DataLayout weights_data_layout = weights.data_layout();
433  const int weights_width_idx = get_data_layout_dimension_index(weights_data_layout, DataLayoutDimension::WIDTH);
434  const int weights_height_idx = get_data_layout_dimension_index(weights_data_layout, DataLayoutDimension::HEIGHT);
435 
436  unsigned int output_width = 0;
437  unsigned int output_height = 0;
438  std::tie(output_width, output_height) = scaled_dimensions(input_shape[width_idx], input_shape[height_idx],
439  weights_shape[weights_width_idx], weights_shape[weights_height_idx],
440  info.pad_stride_info, info.dilation);
441 
443  output_shape.set(width_idx, output_width);
444  output_shape.set(height_idx, output_height);
445  output_shape.set(channel_idx, input_shape[channel_idx] * info.depth_multiplier);
446 
447  return output_shape;
448 }
449 
450 /** Calculate the upsampled output shape used for deconvolution
451  *
452  * @param[in] input Input tensor info
453  * @param[in] weights Weights tensor shape
454  * @param[in] sx Stride on x axis
455  * @param[in] sy Stride on y axis
456  * @param[in] out_dims Output shape dimensions
457  * @param[in] padx Padding on x axis
458  * @param[in] pady Padding on y axis
459  *
460  * @return the calculated shape
461  */
462 inline TensorShape compute_deconvolution_upsampled_shape(const ITensorInfo &input, const ITensorInfo &weights, unsigned int sx, unsigned int sy,
463  std::pair<unsigned int, unsigned int> &out_dims, uint32_t &padx, uint32_t &pady)
464 {
465  const DataLayout data_layout = input.data_layout();
468 
469  // Find the upsampled dimensions
470  unsigned int out_x = (input.dimension(idx_w) - 1) * sx + 1;
471  unsigned int out_y = (input.dimension(idx_h) - 1) * sy + 1;
472 
473  // Find the padding needed for the convolution with stride 1 in order to match output shape
474  padx = out_dims.first - (out_x - weights.dimension(idx_w) + 1);
475  pady = out_dims.second - (out_y - weights.dimension(idx_h) + 1);
476  out_x += padx;
477  out_y += pady;
478 
479  TensorShape scale_out_shape(input.tensor_shape());
480  scale_out_shape.set(idx_w, out_x);
481  scale_out_shape.set(idx_h, out_y);
482 
483  return scale_out_shape;
484 }
485 
486 /** Calculate the output shape of the deconvolution layer
487  *
488  * @param[in] out_dims Output x and y shape dimensions
489  * @param[in] input Input tensor info
490  * @param[in] weights Weights tensor shape
491  *
492  * @return the calculated shape
493  */
494 inline TensorShape compute_deconvolution_output_shape(const std::pair<unsigned int, unsigned int> &out_dims, const ITensorInfo &input, const ITensorInfo &weights)
495 {
496  const TensorShape input_shape{ input.tensor_shape() };
497  const TensorShape weights_shape{ weights.tensor_shape() };
498 
499  const DataLayout data_layout = input.data_layout();
504 
505  TensorShape out_shape{ input_shape };
506  out_shape.set(width_idx, out_dims.first);
507  out_shape.set(height_idx, out_dims.second);
508  out_shape.set(channel_idx, weights_shape[batch_idx]);
509  return out_shape;
510 }
511 
512 /** Calculate the im2col output shape of a tensor
513  *
514  * @param[in] input Input tensor info
515  * @param[in] kernel_dims The kernel dimensions (width and height).
516  * @param[in] conv_info Contains padding and stride information
517  * @param[in] has_bias In case biases are provided expands the matrix with 1
518  * @param[in] dilation Dilation, in elements, across x and y
519  * @param[in] batch_size_on_z True if batch size is on z axis
520  * @param[in] num_groups (Optional) Number of groups when performing a grouped convolution
521  * @param[in] input_pad_right (Optional) When fast-math is selected, per element padding for the im2col matrix may be necessary
522  *
523  * @return the calculated shape
524  */
525 inline TensorShape compute_im2col_conv_shape(const ITensorInfo *input, const Size2D &kernel_dims, const PadStrideInfo &conv_info, bool has_bias, const Size2D &dilation, bool batch_size_on_z,
526  unsigned int num_groups = 1, unsigned int input_pad_right = 0)
527 {
528  // The output shape will be the 3D shape [ out_channels * kernel_area, num_elems_per_out_channel, batches ] if batch_size_on_z == true
529  // or the 4D shape [ out_channels * kernel_area / num_groups, num_elems_per_out_channel, num_groups, batches ] if batch_size_on_z == false
530 
532  ARM_COMPUTE_ERROR_ON(num_groups > 1 && input->data_layout() != DataLayout::NCHW);
533  ARM_COMPUTE_ERROR_ON(num_groups > 1 && batch_size_on_z);
534 
535  TensorShape output_shape{ input->tensor_shape() };
536 
537  const DataLayout data_layout = input->data_layout();
541 
542  std::pair<unsigned int, unsigned int> out_dims = scaled_dimensions(output_shape[width_idx], output_shape[height_idx], kernel_dims.width, kernel_dims.height, conv_info, dilation);
543  output_shape.set(0, ((output_shape[channel_idx] + input_pad_right) / num_groups * kernel_dims.area() + (has_bias ? 1 : 0))); // NOLINT
544  output_shape.set(1, (out_dims.first * out_dims.second));
545  if(batch_size_on_z && output_shape.num_dimensions() >= 3)
546  {
547  output_shape.remove_dimension(2);
548  }
549  else
550  {
551  output_shape.set(2, num_groups);
552  }
553 
554  return output_shape;
555 }
556 
557 /** Calculate the flattened output shape of a tensor
558  *
559  * @param[in] input Input tensor info
560  *
561  * @return the calculated shape
562  */
564 {
565  // The output shape will be the flatten version of the input (i.e. [ width * height * channels, num_batches, ... ] ). Used for FlattenLayer and FullyConnectedLayer.
566 
567  TensorShape output_shape{ input->tensor_shape() };
568 
569  output_shape.collapse(3);
570 
571  return output_shape;
572 }
573 
574 /** Calculate the softmax output shape of a tensor
575  *
576  * @param[in] input Input tensor info
577  * @param[in] axis (Optional) Softmax axis
578  *
579  * @return the calculated shape
580  */
581 inline TensorShape compute_softmax_shape(const ITensorInfo *input, size_t axis = 1)
582 {
583  // The output shape will be a 2D version of the input. For instance:
584  // - [x,y,z] and axis 1 will return [x, y*z]
585  // - [x,y,z,w] and axis 2 will return [x*y, w*z]
586  // - [x,y,z,w] and axis 3 will return [x*y*z, w]
587  TensorShape shape2D = input->tensor_shape();
588 
589  if(axis < input->num_dimensions())
590  {
591  // Collapse from axis onward (this changes the shape)
592  shape2D.collapse_from(axis);
593 
594  // Collapse the rest (collapse is inclusive)
595  shape2D.collapse(shape2D.num_dimensions() - 1);
596  }
597  else
598  {
599  // Collapse everything
600  shape2D.collapse(shape2D.num_dimensions());
601  }
602 
603  if(axis == 0)
604  {
605  // If axis is zero the first dim should be one. Since
606  // collapse is an inclusive operation we need to shift
607  shape2D.shift_right(1);
608  }
609 
610  return shape2D;
611 }
612 
613 /** Calculate the winograd filter transform shape
614  *
615  * @param[in] input Input tensor info
616  * @param[in] winograd_info Winograd information
617  *
618  * @return the calculated shape
619  */
621 {
622  TensorShape tensor_shape{ input.tensor_shape() };
623 
624  const Size2D kernel_size = winograd_info.kernel_size;
625  const Size2D output_tile_size = winograd_info.output_tile_size;
626  const Size2D input_tile_size = Size2D(output_tile_size.width + kernel_size.width - 1, output_tile_size.height + kernel_size.height - 1);
627 
628  tensor_shape.remove_dimension(get_data_layout_dimension_index(input.data_layout(), DataLayoutDimension::WIDTH));
629  tensor_shape.set(Window::DimX, input.dimension(3));
630  tensor_shape.set(Window::DimY, input.dimension(get_data_layout_dimension_index(input.data_layout(), DataLayoutDimension::CHANNEL)));
631  tensor_shape.set(Window::DimZ, input_tile_size.area());
632 
633  return tensor_shape;
634 }
635 
636 /** Calculate the winograd input transform shape
637  *
638  * @param[in] input Input tensor info
639  * @param[in] winograd_info Winograd information
640  *
641  * @return the calculated shape
642  */
644 {
645  const PadStrideInfo conv_info = winograd_info.convolution_info;
646  const Size2D kernel_size = winograd_info.kernel_size;
647  const Size2D output_tile_size = winograd_info.output_tile_size;
648  const Size2D input_tile_size = Size2D(output_tile_size.width + kernel_size.width - 1, output_tile_size.height + kernel_size.height - 1);
649 
650  const size_t idx_w = get_data_layout_dimension_index(input.data_layout(), DataLayoutDimension::WIDTH);
651  const size_t idx_h = get_data_layout_dimension_index(input.data_layout(), DataLayoutDimension::HEIGHT);
652  const size_t idx_c = get_data_layout_dimension_index(input.data_layout(), DataLayoutDimension::CHANNEL);
653 
654  // Compute the number of output tiles along the x and y direction of size "output_tile_size"
655  const Size2D num_tiles = compute_winograd_convolution_tiles(Size2D(input.tensor_shape()[idx_w], input.tensor_shape()[idx_h]),
656  kernel_size,
657  output_tile_size,
658  conv_info);
659 
660  const unsigned int width = input.tensor_shape()[idx_c];
661  const unsigned int height = num_tiles.area();
662  const unsigned int depth = input_tile_size.area();
663 
664  TensorShape output_shape{ input.tensor_shape() };
665  output_shape.set(0, width);
666  output_shape.set(1, height);
667  output_shape.set(2, depth);
668 
669  return output_shape;
670 }
671 
672 /** Calculate the winograd output transform shape
673  *
674  * @param[in] input Input tensor info
675  * @param[in] winograd_info Winograd information
676  *
677  * @return the calculated shape
678  */
680 {
681  const PadStrideInfo conv_info = winograd_info.convolution_info;
682  const Size2D kernel_size = winograd_info.kernel_size;
683  const Size2D input_dimensions = winograd_info.input_dimensions;
684  const DataLayout data_layout = winograd_info.output_data_layout;
685 
686  // Compute output shape
687  unsigned int output_width = 0;
688  unsigned int output_height = 0;
689  std::tie(output_width, output_height) = scaled_dimensions(input_dimensions.width, input_dimensions.height,
690  kernel_size.width, kernel_size.height, conv_info);
691 
692  TensorShape tensor_shape{ input.tensor_shape() };
693 
694  // Output dimension
695  const unsigned int out_w = output_width;
696  const unsigned int out_h = output_height;
697  const unsigned int out_c = input.dimension(0);
698 
702 
703  return tensor_shape;
704 }
705 
706 /** Calculate the deep convolution shape output shape of a tensor
707  *
708  * @param[in] input_shape Input tensor shape
709  * @param[in] input_data_layout Input data layout
710  * @param[in] weights_shape Weights tensor shape
711  * @param[in] conv_info Contains padding and stride information
712  *
713  * @return the calculated shape
714  */
716 {
717  const size_t idx_width = get_data_layout_dimension_index(input_data_layout, DataLayoutDimension::WIDTH);
719  const size_t idx_channel = get_data_layout_dimension_index(input_data_layout, DataLayoutDimension::CHANNEL);
720 
721  const unsigned int input_width = input_shape[idx_width];
722  const unsigned int input_height = input_shape[idx_height];
723  const unsigned int weights_width = weights_shape[idx_width];
724  const unsigned int weights_height = weights_shape[idx_height];
725  const unsigned int weights_out_channel = weights_shape[3];
726  unsigned int output_width = 0;
727  unsigned int output_height = 0;
728  std::tie(output_width, output_height) = scaled_dimensions(input_width, input_height, weights_width, weights_height, conv_info);
729 
731  output_shape.set(idx_width, output_width);
732  output_shape.set(idx_height, output_height);
733  output_shape.set(idx_channel, weights_out_channel);
734 
735  return output_shape;
736 }
737 
738 /** Calculate the deep convolution shape output shape of a tensor
739  *
740  * @param[in] input Input tensor info
741  * @param[in] weights Weights tensor info
742  * @param[in] conv_info Contains padding and stride information
743  *
744  * @return the calculated shape
745  */
747 {
748  return compute_deep_convolution_shape(input.tensor_shape(), input.data_layout(), weights.tensor_shape(), conv_info);
749 }
750 
751 /** Calculate the indirect buffer output shape used by the indirect convolution function
752  *
753  * @param[in] input_shape Input tensor shape
754  * @param[in] input_data_layout Input data layout
755  * @param[in] weights_shape Weights tensor shape
756  * @param[in] conv_info Contains padding and stride information
757  * @param[in] desc Contains the direct/indirect convolution compute arguments, such as the tiling dimensions
758  *
759  * @return the calculated shape
760  */
762  const DirectConvComputeKernelInfo &desc)
763 {
764  ARM_COMPUTE_ERROR_ON_MSG(input_data_layout != DataLayout::NHWC, "The data layout can only be NHWC");
765  ARM_COMPUTE_ERROR_ON_MSG(desc.m0 <= 0 || desc.m0 > 8, "M0 can only be greater than 0 and less than or equal to 8");
766 
767  const unsigned int m0 = desc.m0;
768  const unsigned int kw = weights_shape[1];
769  const unsigned int kh = weights_shape[2];
770 
771  TensorShape output_conv2d_shape = compute_deep_convolution_shape(input_shape, input_data_layout, weights_shape, conv_info);
772 
773  const unsigned int output_w = m0 * kw * kh;
774  const unsigned int output_h = DIV_CEIL(output_conv2d_shape[1] * output_conv2d_shape[2], m0);
775  const unsigned int output_b = output_conv2d_shape[3];
776 
777  return TensorShape(output_w, output_h, output_b);
778 }
779 
780 /** Calculate the min/max shape output shape of a tensor
781  *
782  * @param[in] input Input tensor info
783  *
784  * @return the calculated shape
785  */
787 {
788  TensorShape output_shape{ input->tensor_shape() };
789  output_shape.set(Window::DimX, 2);
790  output_shape.remove_dimension(1);
791  output_shape.remove_dimension(1);
792 
793  return output_shape;
794 }
795 
796 /** Calculate the output pool shape of a tensor
797  *
798  * @param[in] input Input tensor info
799  * @param[in] pool_info Pooling layer info
800  *
801  * @return the calculated shape
802  */
804 {
805  int pooled_w = 0;
806  int pooled_h = 0;
807 
808  TensorShape output_shape{ input.tensor_shape() };
809 
810  const bool is_global_pooling = pool_info.is_global_pooling;
813  const int input_width = input.tensor_shape()[idx_width];
814  const int input_height = input.tensor_shape()[idx_height];
815  const int pool_size_x = is_global_pooling ? output_shape[idx_width] : pool_info.pool_size.width;
816  const int pool_size_y = is_global_pooling ? output_shape[idx_height] : pool_info.pool_size.height;
817 
818  std::tie(pooled_w, pooled_h) = scaled_dimensions_signed(input_width, input_height,
819  pool_size_x, pool_size_y,
820  pool_info.pad_stride_info);
821 
822  ARM_COMPUTE_ERROR_ON_MSG((pooled_w < 1 || pooled_h < 1), "Calculated output dimension size is invalid");
823 
824  output_shape.set(idx_width, static_cast<size_t>(pooled_w));
825  output_shape.set(idx_height, static_cast<size_t>(pooled_h));
826 
827  return output_shape;
828 }
829 
830 /** Calculate the output unpool shape of a tensor
831  *
832  * @param[in] input Input tensor info
833  * @param[in] pool_info Pooling layer info
834  *
835  * @return the calculated shape
836  */
838 {
839  const unsigned int idx_width = get_data_layout_dimension_index(input.data_layout(), DataLayoutDimension::WIDTH);
841  const TensorShape input_shape = input.tensor_shape();
843  const PadStrideInfo pad_stride_info = pool_info.pad_stride_info;
844  const unsigned int stride_x = pad_stride_info.stride().first;
845  const unsigned int stride_y = pad_stride_info.stride().second;
846 
847  const int pad_left = pad_stride_info.pad_left();
848  const int pad_top = pad_stride_info.pad_top();
849  const int pad_right = pad_stride_info.pad_right();
850  const int pad_bottom = pad_stride_info.pad_bottom();
851 
853  const unsigned int out_width = (input_shape[idx_width] - 1) * stride_x - pad_left - pad_right + pool_info.pool_size.width;
854  const unsigned int out_height = (input_shape[idx_height] - 1) * stride_y - pad_top - pad_bottom + pool_info.pool_size.height;
855 
856  output_shape.set(idx_width, out_width);
857  output_shape.set(idx_height, out_height);
858  return output_shape;
859 }
860 
861 /** Calculate the output roi align shape of a tensor
862  *
863  * @param[in] input Input tensor info
864  * @param[in] rois Rois tensor info
865  * @param[in] pool_info Pooling layer info
866  *
867  * @return the calculated shape
868  */
870 {
871  TensorShape output_shape{ input.tensor_shape() };
872 
873  const unsigned int idx_width = get_data_layout_dimension_index(input.data_layout(), DataLayoutDimension::WIDTH);
875 
876  output_shape.set(idx_width, pool_info.pooled_width());
877  output_shape.set(idx_height, pool_info.pooled_height());
878  output_shape.set(3, rois.dimension(1));
879 
880  return output_shape;
881 }
882 
883 /** Calculate the RNN shape of a tensor
884  *
885  * @param[in] input Input tensor info
886  * @param[in] batch_size Batch size
887  *
888  * @return the calculated shape
889  */
890 inline TensorShape compute_rnn_shape(const ITensorInfo *input, const unsigned int batch_size)
891 {
892  TensorShape output_shape{ input->tensor_shape() };
893  output_shape.set(1, batch_size);
894 
895  return output_shape;
896 }
897 
898 /** Calculate the matrix multiplication output shape of two tensors
899  *
900  * @param[in] input0 First input tensor info
901  * @param[in] input1 Second input tensor info
902  * @param[in] is_interleaved_transposed True if the input is interleaved transposed
903  * @param[in] reshape_info GEMM reshape info
904  *
905  * @return the calculated shape
906  */
907 inline TensorShape compute_mm_shape(const ITensorInfo &input0, const ITensorInfo &input1, bool is_interleaved_transposed, const GEMMReshapeInfo &reshape_info)
908 {
909  ARM_COMPUTE_ERROR_ON_MSG(input0.num_dimensions() > 4, "The number of dimensions for the matrix A must be <= 4");
910  ARM_COMPUTE_ERROR_ON_MSG(is_interleaved_transposed && reshape_info.reinterpret_input_as_3d(), "The first input tensor cannot be reinterpreted as 3D if is_interleaved_transposed is true");
911 
912  const bool reinterpret_input_as_3d = reshape_info.reinterpret_input_as_3d();
913  const bool reinterpret_output_as_3d = reshape_info.depth_output_gemm3d() != 0;
914  const int depth_output_gemm3d = reinterpret_output_as_3d ? reshape_info.depth_output_gemm3d() : 1;
915  const int m = reshape_info.reinterpret_input_as_3d() ? input0.dimension(1) * input0.dimension(2) : input0.dimension(1);
916 
917  // If the output of GEMM has to be reinterpreted as 3D, the number of input0 rows (M) is obtained collapsing the second and third
918  // dimension of the output tensor
919  const int dim0 = is_interleaved_transposed ? reshape_info.n() : input1.dimension(0);
920  const int dim1 = is_interleaved_transposed ? reshape_info.m() / depth_output_gemm3d : m / depth_output_gemm3d;
921  const int dim2 = reinterpret_input_as_3d ? input0.tensor_shape()[3] : input0.tensor_shape()[2];
922  const int dim3 = reinterpret_input_as_3d ? 1 : input0.tensor_shape()[3];
923 
925 
926  output_shape.set(0, dim0);
927  output_shape.set(1, dim1);
928  output_shape.set(2, reinterpret_output_as_3d ? depth_output_gemm3d : dim2);
929  output_shape.set(3, reinterpret_output_as_3d ? dim2 : dim3);
930  output_shape.set(4, reinterpret_output_as_3d ? dim3 : 1);
931 
932  return output_shape;
933 }
934 
935 /** Calculate the matrix multiplication output shape of two tensors
936  *
937  * @param[in] input0 First input tensor info
938  * @param[in] input1 Second input tensor info
939  * @param[in] gemm_info GEMM reshape info
940  *
941  * @return the calculated shape
942  */
943 inline TensorShape compute_mm_shape(const ITensorInfo &input0, const ITensorInfo &input1, const GEMMReshapeInfo &gemm_info)
944 {
945  ARM_COMPUTE_UNUSED(input1);
946  ARM_COMPUTE_ERROR_ON_MSG(input0.num_dimensions() > 4, "The number of dimensions for the matrix A must be <= 4");
947 
948  const bool reinterpret_input_as_3d = gemm_info.reinterpret_input_as_3d();
949  const bool reinterpret_output_as_3d = gemm_info.depth_output_gemm3d() != 0;
950  const int depth_output_gemm3d = reinterpret_output_as_3d ? gemm_info.depth_output_gemm3d() : 1;
951 
953 
954  if(!reinterpret_input_as_3d && !reinterpret_output_as_3d)
955  {
956  output_shape.set(0, gemm_info.n());
957  output_shape.set(1, gemm_info.m());
958  }
959  else
960  {
961  // If the output of GEMM has to be reinterpreted as 3D, the number of input0 rows (M) is obtained collapsing the second and third
962  // dimension of the output tensor
963  const int batch_size = reinterpret_input_as_3d ? input0.tensor_shape()[3] : input0.tensor_shape()[2];
964  output_shape.set(0, gemm_info.n());
965  output_shape.set(1, gemm_info.m() / depth_output_gemm3d);
966  output_shape.set(2, reinterpret_output_as_3d ? depth_output_gemm3d : batch_size);
967  output_shape.set(3, reinterpret_output_as_3d ? batch_size : 1);
968  }
969 
970  return output_shape;
971 }
972 
973 /** Calculate the matrix multiplication output shape of two tensors
974  *
975  * @param[in] input0 First input tensor info
976  * @param[in] input1 Second input tensor info
977  * @param[in] gemm_info GEMM kernel info used to retrieve the original dimensions of the input matrices
978  *
979  * @return the calculated shape
980  */
981 inline TensorShape compute_mm_shape(const ITensorInfo &input0, const ITensorInfo &input1, const GEMMKernelInfo &gemm_info)
982 {
983  ARM_COMPUTE_UNUSED(input1);
984  ARM_COMPUTE_ERROR_ON_MSG(input0.num_dimensions() > 4, "The number of dimensions for the matrix A must be <= 4");
985 
986  const bool reinterpret_input_as_3d = gemm_info.reinterpret_input_as_3d;
987  const bool reinterpret_output_as_3d = gemm_info.depth_output_gemm3d != 0;
988  const unsigned int depth_output_gemm3d = reinterpret_output_as_3d ? gemm_info.depth_output_gemm3d : 1;
989 
991 
992  if(!reinterpret_input_as_3d && !reinterpret_output_as_3d)
993  {
994  output_shape.set(0, gemm_info.n);
995  output_shape.set(1, gemm_info.m);
996  }
997  else
998  {
999  // If the output of GEMM has to be reinterpreted as 3D, the number of input0 rows (M) is obtained collapsing the second and third
1000  // dimension of the output tensor
1001  const unsigned int batch_size = reinterpret_input_as_3d ? input0.tensor_shape()[3] : input0.tensor_shape()[2];
1002  output_shape.set(0, gemm_info.n);
1003  output_shape.set(1, gemm_info.m / depth_output_gemm3d);
1004  output_shape.set(2, reinterpret_output_as_3d ? depth_output_gemm3d : batch_size);
1005  output_shape.set(3, reinterpret_output_as_3d ? batch_size : 1);
1006  }
1007 
1008  return output_shape;
1009 }
1010 
1011 /** Calculate the matrix multiplication output shape of two tensors
1012  *
1013  * @param[in] input0 First input tensor info
1014  * @param[in] input1 Second input tensor info
1015  * @param[in] matmul_info Batch MatMul Kernel info to know which matrix is transposed
1016  *
1017  * @return the calculated shape
1018  */
1019 inline TensorShape compute_matmul_shape(const TensorShape &input0, const TensorShape &input1, const MatMulKernelInfo &matmul_info)
1020 {
1021  TensorShape output_shape{ input0 };
1022 
1023  if(matmul_info.adj_lhs)
1024  {
1025  output_shape.set(1, input0[0]); // The vertical (M) dimension
1026  }
1027 
1028  if(matmul_info.adj_rhs)
1029  {
1030  output_shape.set(0, input1[1]); // The horizontal (N) dimension
1031  }
1032  else
1033  {
1034  output_shape.set(0, input1[0]); // The horizontal (N) dimension
1035  }
1036 
1037  return output_shape;
1038 }
1039 /** Calculate the matrix multiplication output shape of two tensors
1040  *
1041  * @param[in] input Input tensor info
1042  * @param[in] gemm_3d_depth (Optional) GEMM 3d depth
1043  * @param[in] batch_size_on_z (Optional) True if batch size is on z axis
1044  *
1045  * @return the calculated shape
1046  */
1047 inline TensorShape compute_output_stage_shape(const ITensorInfo &input, unsigned int gemm_3d_depth = 1, bool batch_size_on_z = false)
1048 {
1049  ARM_COMPUTE_ERROR_ON(input.data_layout() != DataLayout::NHWC && gemm_3d_depth > 1);
1050 
1051  TensorShape output_shape = input.tensor_shape();
1052  if(gemm_3d_depth > 1)
1053  {
1054  if(batch_size_on_z)
1055  {
1056  output_shape.shift_right(1);
1057  }
1058  output_shape.set(0, input.tensor_shape().x());
1059  output_shape.set(1, input.tensor_shape().y() / gemm_3d_depth);
1060  output_shape.set(2, gemm_3d_depth);
1061  }
1062 
1063  return output_shape;
1064 }
1065 
1066 /** Calculate the strided slice output shape of a tensor
1067  *
1068  * @param[in] input Input tensor info
1069  * @param[in] starts The starts of the dimensions of the input tensor to be sliced
1070  * @param[in] ends The ends of the dimensions of the input tensor to be sliced
1071  * @param[in] strides The strides of the dimensions of the input tensor to be sliced
1072  * @param[in] begin_mask If the ith bit of begin_mask is set, starts[i] is ignored and the fullest possible range in that dimension is used instead.
1073  * @param[in] end_mask If the ith bit of end_mask is set, ends[i] is ignored and the fullest possible range in that dimension is used instead.
1074  * @param[in] shrink_axis_mask If the ith bit of shrink_axis_mask is set, it implies that the ith specification shrinks the dimensionality by 1
1075  *
1076  * @return the calculated shape
1077  */
1079  const Coordinates &starts, const Coordinates &ends, const Coordinates &strides,
1080  int32_t begin_mask, int32_t end_mask, int32_t shrink_axis_mask)
1081 {
1083  return compute_strided_slice_output_shape(input.tensor_shape(), starts, ends, strides, begin_mask, end_mask, shrink_axis_mask);
1084 }
1085 
1086 /** Calculate the slice output shape of a tensor
1087  *
1088  * @param[in] input_shape Input tensor info
1089  * @param[in] starts The starts of the dimensions of the input tensor to be sliced
1090  * @param[in] ends The ends of the dimensions of the input tensor to be sliced
1091  *
1092  * @return the calculated shape
1093  */
1095 {
1097 
1099  starts, ends, BiStrides(),
1100  0, construct_slice_end_mask(ends), 0);
1101 }
1102 
1103 /** Calculate the batch to space output shape of a tensor
1104  *
1105  * @param[in] data_layout Data layout
1106  * @param[in] input Input tensor shape
1107  * @param[in] block_x Block shape x value
1108  * @param[in] block_y Block shape y value
1109  * @param[in] crop_info Information about how the output shape is cropped after batch to space is performed
1110  *
1111  * @return the calculated shape
1112  */
1113 inline TensorShape compute_batch_to_space_shape(DataLayout data_layout, const TensorShape &input, int block_x, int block_y, const CropInfo &crop_info = CropInfo{})
1114 {
1115  ARM_COMPUTE_ERROR_ON(block_x < 1 || block_y < 1);
1116 
1120 
1122 
1123  unsigned int new_width = input[idx_width] * static_cast<unsigned int>(block_x);
1124  unsigned int new_height = input[idx_height] * static_cast<unsigned int>(block_y);
1125  const unsigned int width_crop = crop_info.left + crop_info.right;
1126  const unsigned int height_crop = crop_info.top + crop_info.bottom;
1127  ARM_COMPUTE_ERROR_ON(new_width <= width_crop);
1128  ARM_COMPUTE_ERROR_ON(new_height <= height_crop);
1129  new_width -= width_crop;
1130  new_height -= height_crop;
1131 
1132  output_shape.set(idx_width, new_width);
1133  output_shape.set(idx_height, new_height);
1134  output_shape.set(idx_batch, input[idx_batch] / (block_x * block_y));
1135 
1136  return output_shape;
1137 }
1138 
1139 /** Calculate the depth to space output shape of a tensor
1140  *
1141  * @param[in] input_shape Input tensor shape
1142  * @param[in] data_layout Operation data layout
1143  * @param[in] block Block shape value
1144  *
1145  * @return the calculated shape
1146  */
1148 {
1149  ARM_COMPUTE_ERROR_ON(block < 2);
1150 
1154 
1158  output_shape.set(idx_channel, input_shape[idx_channel] / (block * block));
1159 
1160  return output_shape;
1161 }
1162 
1163 /** Calculate the split output shape of a tensor
1164  *
1165  * @param[in] input Input tensor info
1166  * @param[in] axis Axis on which to split the input
1167  * @param[in] num_splits Number of splits
1168  *
1169  * @return the calculated shape
1170  */
1171 inline TensorShape compute_split_shape(const ITensorInfo *input, unsigned int axis, unsigned int num_splits)
1172 {
1173  TensorShape empty_shape;
1174  empty_shape.set(0, 0);
1175 
1176  TensorShape out_shape{ input->tensor_shape() };
1177 
1178  // Return empty shape if axis is invalid
1179  if(axis > input->tensor_shape().num_dimensions())
1180  {
1181  return empty_shape;
1182  }
1183 
1184  size_t axis_size = out_shape[axis];
1185 
1186  // Return empty shape if num_split is not valid
1187  if(axis_size % num_splits)
1188  {
1189  return empty_shape;
1190  }
1191 
1192  out_shape[axis] = axis_size / num_splits;
1193  return out_shape;
1194 }
1195 
1196 /** Calculate the space to batch output shape of a tensor
1197  *
1198  * @param[in] input Input tensor info
1199  * @param[in] block_x Block shape x value
1200  * @param[in] block_y Block shape y value
1201  * @param[in] padding_left Left padding values
1202  * @param[in] padding_right Right padding values
1203  *
1204  * @return the calculated shape
1205  */
1206 inline TensorShape compute_space_to_batch_shape(const ITensorInfo *input, int block_x, int block_y, const Size2D &padding_left, const Size2D &padding_right)
1207 {
1208  TensorShape output_shape{ input->tensor_shape() };
1209 
1210  const DataLayout data_layout = input->data_layout();
1214 
1215  ARM_COMPUTE_ERROR_ON((input->tensor_shape()[idx_width] + padding_left.x() + padding_right.x()) % block_x != 0);
1216  ARM_COMPUTE_ERROR_ON((input->tensor_shape()[idx_height] + padding_left.y() + padding_right.y()) % block_y != 0);
1217 
1218  output_shape.set(idx_width, (input->tensor_shape()[idx_width] + padding_left.x() + padding_right.x()) / block_x);
1219  output_shape.set(idx_height, (input->tensor_shape()[idx_height] + padding_left.y() + padding_right.y()) / block_y);
1220  output_shape.set(idx_batch, input->tensor_shape()[idx_batch] * block_x * block_y);
1221 
1222  return output_shape;
1223 }
1224 
1225 /** Calculate the space to batch output shape of a tensor
1226  *
1227  * @param[in] input Input tensor info
1228  * @param[in] block_shape Block shape value
1229  *
1230  * @return the calculated shape
1231  */
1232 inline TensorShape compute_space_to_depth_shape(const ITensorInfo *input, int32_t block_shape)
1233 {
1234  TensorShape output_shape{ input->tensor_shape() };
1235 
1236  const DataLayout data_layout = input->data_layout();
1240 
1241  output_shape.set(idx_width, input->tensor_shape()[idx_width] / block_shape);
1242  output_shape.set(idx_height, input->tensor_shape()[idx_height] / block_shape);
1243  output_shape.set(idx_depth, input->tensor_shape()[idx_depth] * (block_shape * block_shape));
1244 
1245  return output_shape;
1246 }
1247 
1248 /** Calculate the prior box output shape of a tensor
1249  *
1250  * @param[in] input Input tensor info
1251  * @param[in] info PriorBoxLayer info
1252  *
1253  * @return the calculated shape
1254  */
1256 {
1257  DataLayout data_layout = input.data_layout();
1260  const int num_priors = info.aspect_ratios().size() * info.min_sizes().size() + info.max_sizes().size();
1261 
1263  output_shape.set(0, input.dimension(idx_w) * input.dimension(idx_h) * num_priors * 4);
1264  output_shape.set(1, 2);
1265 
1266  return output_shape;
1267 }
1268 
1269 /** Calculate the padded shape of a tensor
1270  *
1271  * @param[in] input_shape Input tensor shape
1272  * @param[in] padding Paddings list
1273  *
1274  * @return the calculated shape
1275  */
1277 {
1278  TensorShape padded_shape = input_shape;
1279  for(size_t dim = 0; dim < padding.size(); ++dim)
1280  {
1281  const auto &padding_pair = padding[dim];
1282  const uint32_t shape_on_index = (padded_shape.num_dimensions() <= dim) ? 1 : input_shape[dim];
1283  padded_shape.set(dim, padding_pair.first + shape_on_index + padding_pair.second);
1284  }
1285  return padded_shape;
1286 }
1287 
1288 /** Calculate the tiled shape of a tensor
1289  *
1290  * @param[in] input_shape Input tensor shape
1291  * @param[in] multiples Paddings list
1292  *
1293  * @return the calculated shape
1294  */
1296 {
1297  TensorShape tiled_shape = input_shape;
1298  for(size_t dim = 0; dim < multiples.size(); ++dim)
1299  {
1300  tiled_shape.set(dim, input_shape[dim] * multiples[dim]);
1301  }
1302  return tiled_shape;
1303 }
1304 
1305 /** Calculate the reduced shape of a tensor given an axis
1306  *
1307  * @param[in] input Input tensor info
1308  * @param[in] axis Axis on which to perform reduction
1309  * @param[in] keep_dims (Optional) Whether to keep the dimension after reduction operation. Defaults to true.
1310  *
1311  * @return the calculated shape
1312  */
1313 inline TensorShape compute_reduced_shape(const TensorShape &input, unsigned int axis, bool keep_dims = true)
1314 {
1316 
1317  if(!keep_dims)
1318  {
1319  output_shape.remove_dimension(axis);
1320  }
1321  else
1322  {
1323  output_shape.set(axis, 1);
1324  }
1325 
1326  return output_shape;
1327 }
1328 
1329 /** Calculate the upsampled shape of a tensor
1330  *
1331  * @param[in] input Input tensor info
1332  * @param[in] info Contains stride information (x and y)
1333  *
1334  * @return the calculated shape
1335  */
1337 {
1338  const DataLayout data_layout = input.data_layout();
1341 
1342  TensorShape scale_out_shape(input.tensor_shape());
1343  const unsigned int out_x = input.dimension(idx_width) * info.x();
1344  const unsigned int out_y = input.dimension(idx_height) * info.y();
1345  scale_out_shape.set(idx_width, out_x);
1346  scale_out_shape.set(idx_height, out_y);
1347 
1348  return scale_out_shape;
1349 }
1350 
1351 /** Get the tensor shape
1352  *
1353  * @param[in] data Input data
1354  *
1355  * @return the extracted tensor shape
1356  */
1357 template <typename T>
1359 {
1360  return data->info()->tensor_shape();
1361 }
1362 
1364 {
1365  return data->tensor_shape();
1366 }
1368 {
1369  return data->tensor_shape();
1370 }
1371 
1373 {
1374  return *data;
1375 }
1376 
1378 {
1379  return *data;
1380 }
1381 
1382 /** Calculate the unstack shape of a tensor
1383  *
1384  * @param[in] input_shape Input tensor shape
1385  * @param[in] axis Axis on which to perform the unstack operation
1386  *
1387  * @return the calculated shape
1388  */
1390 {
1391  ARM_COMPUTE_ERROR_ON(axis > input_shape.num_dimensions());
1392  input_shape.remove_dimension(axis);
1393  return input_shape;
1394 }
1395 
1396 /** Calculate the concatenate output shape of the concatenate operation along a single axis
1397  *
1398  * @param[in] input Vector containing the shapes of the inputs
1399  * @param[in] axis Axis along which to concatenate the input tensors
1400  *
1401  * @return the calculated shape
1402  */
1403 template <typename T>
1404 inline TensorShape calculate_concatenate_shape(const std::vector<T *> &input, size_t axis)
1405 {
1406  TensorShape out_shape = extract_shape(input[0]);
1407 
1408 #if defined(ARM_COMPUTE_ASSERTS_ENABLED)
1409  // All dimensions must match except the axis one
1410  for(unsigned int i = 0; i < MAX_DIMS; ++i)
1411  {
1412  if(i == axis)
1413  {
1414  continue;
1415  }
1416 
1417  for(const auto &tensor : input)
1418  {
1419  ARM_COMPUTE_ERROR_ON(tensor == nullptr);
1421  ARM_COMPUTE_ERROR_ON(out_shape[i] != shape[i]);
1422  }
1423  }
1424 #endif // defined(ARM_COMPUTE_ASSERTS_ENABLED)
1425 
1426  // Calculate output shape
1427  size_t new_size = 0;
1428  for(const auto &tensor : input)
1429  {
1431  new_size += shape[axis];
1432  }
1433 
1434  out_shape.set(axis, new_size);
1435 
1436  return out_shape;
1437 }
1438 /** Calculate the stack output shape of a tensor
1439  *
1440  * @param[in] a Input tensor info
1441  * @param[in] axis Axis on which to perform the stack operation
1442  * @param[in] num_tensors Number of tensors to stack
1443  *
1444  * @return the calculated shape
1445  */
1446 inline TensorShape compute_stack_shape(const ITensorInfo &a, unsigned int axis, unsigned int num_tensors)
1447 {
1450 
1451  TensorShape shape_out{ a.tensor_shape() };
1452  shape_out.set(axis, num_tensors);
1453 
1454  unsigned int i_shift = 0;
1455 
1456  for(unsigned int i = 0; i < a.num_dimensions(); ++i)
1457  {
1458  if(i == axis)
1459  {
1460  i_shift++;
1461  }
1462 
1463  shape_out.set(i + i_shift, a.tensor_shape()[i]);
1464  }
1465  return shape_out;
1466 }
1467 
1468 /** Calculate the output shape of 3d Convolution
1469  *
1470  * @param[in] src Input tensor shape
1471  * @param[in] weights Weights tensor shape
1472  * @param[in] conv3d_info 3d Convolution Parameters object
1473  *
1474  * @return the calculated shape
1475  */
1476 inline TensorShape compute_conv3d_shape(const TensorShape &src, const TensorShape &weights, const Conv3dInfo &conv3d_info)
1477 {
1478  // Weight tensor shape indices (D H W Cin Cout)
1479  constexpr unsigned int weights_depth_dim = 4u;
1480  constexpr unsigned int weights_height_dim = 3u;
1481  constexpr unsigned int weights_width_dim = 2u;
1482  constexpr unsigned int weights_CHout_dim = 0u;
1483 
1484  // Source/Destination Tensor shape indices (N D H W C)
1485  constexpr unsigned int batch_dim = 4u;
1486  constexpr unsigned int depth_dim = 3u;
1487  constexpr unsigned int height_dim = 2u;
1488  constexpr unsigned int width_dim = 1u;
1489  constexpr unsigned int channel_dim = 0u;
1490 
1492  const size_t pad_left = conv3d_info.padding.left;
1493  const size_t pad_right = conv3d_info.padding.right;
1494  const size_t pad_top = conv3d_info.padding.top;
1495  const size_t pad_bottom = conv3d_info.padding.bottom;
1496  const size_t pad_front = conv3d_info.padding.front;
1497  const size_t pad_back = conv3d_info.padding.back;
1498  const size_t dilation_x = conv3d_info.dilation.width;
1499  const size_t dilation_y = conv3d_info.dilation.height;
1500  const size_t dilation_z = conv3d_info.dilation.depth;
1501  const size_t stride_x = conv3d_info.stride.x();
1502  const size_t stride_y = conv3d_info.stride.y();
1503  const size_t stride_z = conv3d_info.stride.z();
1504 
1505  int output_width_size = 0;
1506  int output_height_size = 0;
1507  int output_depth_size = 0;
1508 
1509  switch(conv3d_info.round_type)
1510  {
1512  output_width_size = static_cast<int>(std::floor((static_cast<float>(src[width_dim] + pad_left + pad_right - (dilation_x * (weights[weights_width_dim] - 1) + 1)) / stride_x) + 1));
1513  output_height_size = static_cast<int>(std::floor((static_cast<float>(src[height_dim] + pad_top + pad_bottom - (dilation_y * (weights[weights_height_dim] - 1) + 1)) / stride_y) + 1));
1514  output_depth_size = static_cast<int>(std::floor((static_cast<float>(src[depth_dim] + pad_front + pad_back - (dilation_z * (weights[weights_depth_dim] - 1) + 1)) / stride_z) + 1));
1515  break;
1517  output_width_size = static_cast<int>(std::ceil((static_cast<float>(src[width_dim] + pad_left + pad_right - (dilation_x * (weights[weights_width_dim] - 1) + 1)) / stride_x) + 1));
1518  output_height_size = static_cast<int>(std::ceil((static_cast<float>(src[height_dim] + pad_top + pad_bottom - (dilation_y * (weights[weights_height_dim] - 1) + 1)) / stride_y) + 1));
1519  output_depth_size = static_cast<int>(std::ceil((static_cast<float>(src[depth_dim] + pad_front + pad_back - (dilation_z * (weights[weights_depth_dim] - 1) + 1)) / stride_z) + 1));
1520  break;
1521  default:
1522  ARM_COMPUTE_ERROR("Unsupported rounding type");
1523  }
1524 
1526  output_shape.set(width_dim, output_width_size);
1527  output_shape.set(height_dim, output_height_size);
1528  output_shape.set(depth_dim, output_depth_size);
1530  return output_shape;
1531 }
1532 
1533 /** Calculate the output pool3d shape of a tensor
1534  *
1535  * @param[in] src Input tensor info
1536  * @param[in] pool3d_info Pooling layer info
1537  *
1538  * @return the calculated shape
1539  */
1541 {
1543 
1544  const auto data_layout = DataLayout::NDHWC;
1548  const int pool_size_width = pool3d_info.is_global_pooling ? src[idx_width] : pool3d_info.pool_size.width;
1549  const int pool_size_height = pool3d_info.is_global_pooling ? src[idx_height] : pool3d_info.pool_size.height;
1550  const int pool_size_depth = pool3d_info.is_global_pooling ? src[idx_depth] : pool3d_info.pool_size.depth;
1551  int output_width = 0;
1552  int output_height = 0;
1553  int output_depth = 0;
1554 
1555  std::tie(output_width, output_height, output_depth) = scaled_3d_dimensions_signed(src[idx_width], src[idx_height], src[idx_depth], pool_size_width, pool_size_height,
1556  pool_size_depth, pool3d_info);
1557 
1558  ARM_COMPUTE_ERROR_ON_MSG((output_width < 1 || output_height < 1 || output_depth < 1), "Calculated output dimension size is invalid");
1559 
1560  output_shape.set(idx_width, static_cast<size_t>(output_width));
1561  output_shape.set(idx_height, static_cast<size_t>(output_height));
1562  output_shape.set(idx_depth, static_cast<size_t>(output_depth));
1563 
1564  return output_shape;
1565 }
1566 
1567 /** Calculate the gather output shape of a tensor
1568  *
1569  * @param[in] input_shape Input tensor shape
1570  * @param[in] indices_shape Indices tensor shape. Only supports for 2d and 3d indices
1571  * @param[in] actual_axis Axis to be used in the computation
1572  *
1573  * @note Let input_shape be (X,Y,Z) and indices shape (W,O,P) and axis 1
1574  * the new shape is computed by replacing the axis in the input shape with
1575  * the indice shape so the output shape will be (X,W,O,P,Z)
1576  *
1577  * @return the calculated shape
1578  */
1579 inline TensorShape compute_gather_shape(const TensorShape &input_shape, const TensorShape &indices_shape, uint32_t actual_axis)
1580 {
1581  const auto input_num_dims = input_shape.num_dimensions();
1582  const auto indices_num_dims = indices_shape.num_dimensions();
1583 
1584  ARM_COMPUTE_ERROR_ON(actual_axis >= input_num_dims);
1585  ARM_COMPUTE_ERROR_ON(input_num_dims + indices_num_dims - 1 > Coordinates::num_max_dimensions);
1586 
1588  size_t dim_no = 0;
1589 
1590  for(; dim_no < actual_axis; ++dim_no)
1591  {
1592  output_shape.set(dim_no, input_shape[dim_no]);
1593  }
1594 
1595  for(; dim_no < actual_axis + indices_num_dims; ++dim_no)
1596  {
1597  output_shape.set(dim_no, indices_shape[dim_no - actual_axis]);
1598  }
1599 
1600  for(; dim_no < input_num_dims + indices_num_dims - 1; ++dim_no)
1601  {
1602  output_shape.set(dim_no, input_shape[dim_no + 1 - indices_num_dims]);
1603  }
1604 
1605  ARM_COMPUTE_ERROR_ON(input_shape.total_size() * indices_shape.total_size() != output_shape.total_size() * input_shape[actual_axis]);
1606 
1607  return output_shape;
1608 }
1609 } // namespace shape_calculator
1610 } // namespace misc
1611 } // namespace arm_compute
1612 #endif /* ACL_ARM_COMPUTE_CORE_UTILS_MISC_SHAPECALCULATOR */
arm_compute::DataLayout::NCHW
@ NCHW
Num samples, channels, height, width.
arm_compute::misc::shape_calculator::compute_pool3d_shape
TensorShape compute_pool3d_shape(const TensorShape &src, Pooling3dLayerInfo pool3d_info)
Calculate the output pool3d shape of a tensor.
Definition: ShapeCalculator.h:1540
arm_compute::misc::shape_calculator::calculate_unstack_shape
TensorShape calculate_unstack_shape(TensorShape input_shape, unsigned int axis)
Calculate the unstack shape of a tensor.
Definition: ShapeCalculator.h:1389
arm_compute::Conv3dInfo::padding
Padding3D padding
Definition: FunctionDescriptors.h:97
arm_compute::misc::shape_calculator::compute_winograd_input_transform_shape
TensorShape compute_winograd_input_transform_shape(const ITensorInfo &input, const WinogradInfo &winograd_info)
Calculate the winograd input transform shape.
Definition: ShapeCalculator.h:643
arm_compute::Size2D::y
size_t y() const
Semantic accessor for height as y.
Definition: Size2D.h:84
arm_compute::misc::shape_calculator::compute_transpose1xW_shape
TensorShape compute_transpose1xW_shape(const ITensorInfo &b)
Calculate the transposed 1xW shape.
Definition: ShapeCalculator.h:298
arm_compute::misc::shape_calculator::compute_stack_shape
TensorShape compute_stack_shape(const ITensorInfo &a, unsigned int axis, unsigned int num_tensors)
Calculate the stack output shape of a tensor.
Definition: ShapeCalculator.h:1446
arm_compute::ITensorInfo::data_layout
virtual DataLayout data_layout() const =0
Get the data layout of the tensor.
arm_compute::misc::shape_calculator::compute_matmul_shape
TensorShape compute_matmul_shape(const TensorShape &input0, const TensorShape &input1, const MatMulKernelInfo &matmul_info)
Calculate the matrix multiplication output shape of two tensors.
Definition: ShapeCalculator.h:1019
weights_CHout_dim
constexpr unsigned int weights_CHout_dim
Definition: Conv3D.cpp:43
arm_compute::test::validation::src
SimpleTensor< float > src
Definition: DFT.cpp:155
arm_compute::WinogradInfo::output_data_layout
DataLayout output_data_layout
Data layout to use for the output tensor once the convolution has been applied (NCHW or NHWC)
Definition: Types.h:1855
arm_compute::misc::shape_calculator::compute_strided_slice_shape
TensorShape compute_strided_slice_shape(const ITensorInfo &input, const Coordinates &starts, const Coordinates &ends, const Coordinates &strides, int32_t begin_mask, int32_t end_mask, int32_t shrink_axis_mask)
Calculate the strided slice output shape of a tensor.
Definition: ShapeCalculator.h:1078
arm_compute::BiStrides
Coordinates BiStrides
Bidirectional strides.
Definition: Types.h:82
arm_compute::ITensorInfo::tensor_shape
virtual const TensorShape & tensor_shape() const =0
Size for each dimension of the tensor.
arm_compute::misc::shape_calculator::compute_depth_to_space_shape
TensorShape compute_depth_to_space_shape(const TensorShape &input_shape, DataLayout data_layout, int block)
Calculate the depth to space output shape of a tensor.
Definition: ShapeCalculator.h:1147
arm_compute::test::validation::idx_height
const int idx_height
Definition: Scale.cpp:263
arm_compute::ROIPoolingLayerInfo::pooled_width
unsigned int pooled_width() const
Get the pooled width of the layer.
Definition: Types.h:1249
arm_compute::PaddingList
std::vector< PaddingInfo > PaddingList
List of padding information.
Definition: Types.h:413
Helpers.h
input_width
const size_t input_width
Definition: impl.cpp:63
arm_compute::DataLayout
DataLayout
[DataLayout enum definition]
Definition: CoreTypes.h:109
arm_compute::DataLayoutDimension::CHANNEL
@ CHANNEL
channel
arm_compute::PadStrideInfo::pad_right
unsigned int pad_right() const
Get the right padding.
Definition: CoreTypes.h:217
arm_compute::misc::shape_calculator::compute_mm_shape
TensorShape compute_mm_shape(const ITensorInfo &input0, const ITensorInfo &input1, bool is_interleaved_transposed, const GEMMReshapeInfo &reshape_info)
Calculate the matrix multiplication output shape of two tensors.
Definition: ShapeCalculator.h:907
arm_compute::Conv3dInfo::stride
Size3D stride
Definition: FunctionDescriptors.h:96
FunctionDescriptors.h
arm_compute::test::validation::output_shape
const auto output_shape
Definition: ConvolutionLayer.cpp:411
arm_compute::misc::shape_calculator::compute_depthwise_convolution_shape
TensorShape compute_depthwise_convolution_shape(const ITensorInfo &input, const ITensorInfo &weights, const ConvolutionInfo &info)
Calculate the depthwise convolution output shape of a tensor.
Definition: ShapeCalculator.h:422
arm_compute::misc::shape_calculator::compute_permutation_output_shape
TensorShape compute_permutation_output_shape(const ITensorInfo &input, const PermutationVector &perm)
Calculate the permuted shape of an input given a permutation vector.
Definition: ShapeCalculator.h:110
arm_compute::helpers::tensor_transform
Definition: tensor_transform.h:33
arm_compute::GEMMReshapeInfo
GEMM reshape information class.
Definition: Types.h:1697
arm_compute::DataLayout::NHWC
@ NHWC
Num samples, height, width, channels.
arm_compute::compute_winograd_convolution_tiles
Size2D compute_winograd_convolution_tiles(const Size2D &in_dims, const Size2D &kernel_size, const Size2D &output_tile_size, const PadStrideInfo &conv_info)
Calculate the number of output tiles required by Winograd Convolution layer.
Definition: Helpers.h:248
arm_compute::misc::shape_calculator::compute_pool_shape
TensorShape compute_pool_shape(const ITensorInfo &input, PoolingLayerInfo pool_info)
Calculate the output pool shape of a tensor.
Definition: ShapeCalculator.h:803
arm_compute::GEMMReshapeInfo::n
int n() const
Number of matrix B columns.
Definition: Types.h:1735
arm_compute::TensorShape
Shape of a tensor.
Definition: TensorShape.h:39
ConvolutionInfo.h
arm_compute::WinogradInfo::output_tile_size
Size2D output_tile_size
Width and height of the output tile.
Definition: Types.h:1851
arm_compute::Window::DimX
static constexpr size_t DimX
Alias for dimension 0 also known as X dimension.
Definition: Window.h:43
arm_compute::misc::shape_calculator::compute_roi_align_shape
TensorShape compute_roi_align_shape(const ITensorInfo &input, const ITensorInfo &rois, ROIPoolingLayerInfo pool_info)
Calculate the output roi align shape of a tensor.
Definition: ShapeCalculator.h:869
weights_depth_dim
constexpr unsigned int weights_depth_dim
Definition: Conv3D.cpp:39
arm_compute::WinogradInfo
Winograd information.
Definition: Types.h:1836
arm_compute::MatMulKernelInfo::adj_rhs
bool adj_rhs
Get Adjoint RHS flag value.
Definition: KernelDescriptors.h:236
arm_compute::WinogradInfo::input_dimensions
Size2D input_dimensions
Width and height of the input tensor before the convolution is applied.
Definition: Types.h:1853
ARM_COMPUTE_ERROR
#define ARM_COMPUTE_ERROR(msg)
Print the given message then throw an std::runtime_error.
Definition: Error.h:353
arm_compute::misc::shape_calculator::compute_slice_shape
TensorShape compute_slice_shape(const TensorShape &input_shape, const Coordinates &starts, const Coordinates &ends)
Calculate the slice output shape of a tensor.
Definition: ShapeCalculator.h:1094
arm_compute::scaled_dimensions
std::pair< unsigned int, unsigned int > scaled_dimensions(int width, int height, int kernel_width, int kernel_height, const PadStrideInfo &pad_stride_info, const Size2D &dilation=Size2D(1U, 1U))
Returns expected width and height of output scaled tensor depending on dimensions rounding mode.
Definition: Utils.cpp:288
arm_compute::Size2D
Class for specifying the size of an image or rectangle.
Definition: Size2D.h:34
arm_compute::misc::shape_calculator::calculate_concatenate_shape
TensorShape calculate_concatenate_shape(const std::vector< T * > &input, size_t axis)
Calculate the concatenate output shape of the concatenate operation along a single axis.
Definition: ShapeCalculator.h:1404
arm_compute::helpers::tensor_transform::construct_slice_end_mask
int32_t construct_slice_end_mask(Coordinates ends)
Constructs end mask in case we want to perform a slice operation using the strided slice interface.
Definition: tensor_transform.cpp:172
arm_compute::misc::shape_calculator::compute_lhs_reshaped_shape
TensorShape compute_lhs_reshaped_shape(const ITensorInfo &a, const GEMMLHSMatrixInfo &lhs_info, bool reinterpret_input_as_3d=false)
Calculate the Left Hand Side matrix reshaped shape.
Definition: ShapeCalculator.h:182
arm_compute::test::validation::lhs_info
lhs_info
Definition: GEMMMatrixMultiplyReshaped.cpp:862
arm_compute::permute
void permute(Dimensions< T > &dimensions, const PermutationVector &perm)
Permutes given Dimensions according to a permutation vector.
Definition: Helpers.h:146
arm_compute::Size2D::height
size_t height
Height of the image region or rectangle.
Definition: Size2D.h:91
arm_compute::misc::shape_calculator::compute_indirect_buffer_shape
TensorShape compute_indirect_buffer_shape(const TensorShape &input_shape, DataLayout input_data_layout, const TensorShape &weights_shape, const PadStrideInfo &conv_info, const DirectConvComputeKernelInfo &desc)
Calculate the indirect buffer output shape used by the indirect convolution function.
Definition: ShapeCalculator.h:761
arm_compute::Size3D::x
size_t x() const
Semantic accessor for width as x.
Definition: Size3D.h:58
arm_compute::PoolingLayerInfo::pool_size
Size2D pool_size
Definition: Types.h:1120
arm_compute::misc::shape_calculator::compute_reductionA_shape
TensorShape compute_reductionA_shape(const ITensorInfo &b)
Calculate the reductionA shape used in GEMMLowp.
Definition: ShapeCalculator.h:335
arm_compute::DimensionRoundingType::CEIL
@ CEIL
Ceil rounding.
arm_compute::Size3D::width
size_t width
Width of the 3D shape or object.
Definition: Size3D.h:92
arm_compute::test::validation::idx_width
const int idx_width
Definition: Scale.cpp:262
arm_compute::misc::shape_calculator::compute_gather_shape
TensorShape compute_gather_shape(const TensorShape &input_shape, const TensorShape &indices_shape, uint32_t actual_axis)
Calculate the gather output shape of a tensor.
Definition: ShapeCalculator.h:1579
arm_compute::ROIPoolingLayerInfo::pooled_height
unsigned int pooled_height() const
Get the pooled height of the layer.
Definition: Types.h:1254
arm_compute::misc::shape_calculator::compute_transposed_shape
TensorShape compute_transposed_shape(const ITensorInfo &input)
Calculate the transposed shape of a tensor.
Definition: ShapeCalculator.h:404
arm_compute::GEMMKernelInfo
Descriptor used by the GEMM kernels.
Definition: KernelDescriptors.h:59
arm_compute::misc::shape_calculator::calculate_reduce_mean_shape
TensorShape calculate_reduce_mean_shape(ITensorInfo *input, const Coordinates &reduction_axis, bool keep_dims)
Calculate the output tensor shape for the reduce mean operation.
Definition: ShapeCalculator.h:52
arm_compute::DIV_CEIL
constexpr auto DIV_CEIL(S val, T m) -> decltype((val+m - 1)/m)
Calculate the rounded up quotient of val / m.
Definition: Math.h:37
ITensorInfo.h
weights_width_dim
constexpr unsigned int weights_width_dim
Definition: Conv3D.cpp:41
arm_compute::misc::shape_calculator::compute_min_max_shape
TensorShape compute_min_max_shape(const ITensorInfo *input)
Calculate the min/max shape output shape of a tensor.
Definition: ShapeCalculator.h:786
arm_compute::DataLayoutDimension::WIDTH
@ WIDTH
width
arm_compute::scaled_dimensions_signed
std::pair< int, int > scaled_dimensions_signed(int width, int height, int kernel_width, int kernel_height, const PadStrideInfo &pad_stride_info)
Returns calculated width and height of output scaled tensor depending on dimensions rounding mode.
Definition: Utils.cpp:322
arm_compute::Size2D::area
size_t area() const
The area of the image or rectangle calculated as (width * height)
Definition: Size2D.h:54
arm_compute::GEMMReshapeInfo::reinterpret_input_as_3d
bool reinterpret_input_as_3d() const
Flag which specifies if the input tensor has to be reinterpreted as 3D.
Definition: Types.h:1778
arm_compute::misc::shape_calculator::compute_reorg_output_shape
TensorShape compute_reorg_output_shape(const ITensorInfo &input, int32_t stride)
Calculate the output shape of the reorg layer given a stride.
Definition: ShapeCalculator.h:124
arm_compute::GEMMReshapeInfo::m
int m() const
Number of matrix A rows.
Definition: Types.h:1727
arm_compute::test::validation::data_layout
const auto data_layout
Definition: ConvolutionLayer.cpp:406
arm_compute::ITensorInfo::dimension
virtual size_t dimension(size_t index) const =0
Return the size of the requested dimension.
arm_compute::misc::shape_calculator::compute_im2col_conv_shape
TensorShape compute_im2col_conv_shape(const ITensorInfo *input, const Size2D &kernel_dims, const PadStrideInfo &conv_info, bool has_bias, const Size2D &dilation, bool batch_size_on_z, unsigned int num_groups=1, unsigned int input_pad_right=0)
Calculate the im2col output shape of a tensor.
Definition: ShapeCalculator.h:525
height_dim
constexpr unsigned int height_dim
Definition: Conv3D.cpp:34
arm_compute::Strides
Strides of an item in bytes.
Definition: Strides.h:38
arm_compute::DataLayoutDimension::DEPTH
@ DEPTH
depth
arm_compute::TensorShape::shift_right
void shift_right(size_t step)
Shifts right the tensor shape increasing its dimensions.
Definition: TensorShape.h:148
arm_compute::test::validation::m
const unsigned int m
Definition: GEMMMatrixMultiplyNative.cpp:359
arm_compute::test::validation::rhs_info
rhs_info
Definition: GEMMMatrixMultiplyReshaped.cpp:862
arm_compute::misc::shape_calculator::compute_transpose1xW_with_element_size_shape
TensorShape compute_transpose1xW_with_element_size_shape(const ITensorInfo &b, int mult_transpose1xW_width=1)
Calculate the transposed 1xW width element shape.
Definition: ShapeCalculator.h:315
arm_compute::test::validation::has_bias
const bool has_bias
Definition: Im2Col.cpp:152
arm_compute::misc::shape_calculator::compute_output_stage_shape
TensorShape compute_output_stage_shape(const ITensorInfo &input, unsigned int gemm_3d_depth=1, bool batch_size_on_z=false)
Calculate the matrix multiplication output shape of two tensors.
Definition: ShapeCalculator.h:1047
arm_compute::test::validation::shape
shape
Definition: DFT.cpp:115
depth_dim
constexpr unsigned int depth_dim
Definition: Conv3D.cpp:33
arm_compute::Size3D::y
size_t y() const
Semantic accessor for height as y.
Definition: Size3D.h:67
arm_compute::Size3D::height
size_t height
Height of the 3D shape or object.
Definition: Size3D.h:93
ARM_COMPUTE_ERROR_ON
#define ARM_COMPUTE_ERROR_ON(cond)
If the condition is true then an error message is printed and an exception thrown.
Definition: Error.h:467
arm_compute::Conv3dInfo::dilation
Size3D dilation
Definition: FunctionDescriptors.h:99
arm_compute::MAX_DIMS
constexpr size_t MAX_DIMS
Constant value used to indicate maximum dimensions of a Window, TensorShape and Coordinates.
Definition: Dimensions.h:38
arm_compute::misc::shape_calculator::compute_interleaved_shape
TensorShape compute_interleaved_shape(const ITensorInfo &a, int mult_interleave4x4_height=1, bool reinterpret_input_as_3d=false)
Calculate the interleaved shape of an input tensor.
Definition: ShapeCalculator.h:262
weights_width
const size_t weights_width
Definition: impl.cpp:54
arm_compute::misc::shape_calculator::compute_rnn_shape
TensorShape compute_rnn_shape(const ITensorInfo *input, const unsigned int batch_size)
Calculate the RNN shape of a tensor.
Definition: ShapeCalculator.h:890
arm_compute::misc::shape_calculator::compute_deconvolution_output_shape
TensorShape compute_deconvolution_output_shape(const std::pair< unsigned int, unsigned int > &out_dims, const ITensorInfo &input, const ITensorInfo &weights)
Calculate the output shape of the deconvolution layer.
Definition: ShapeCalculator.h:494
arm_compute::Size3D::depth
size_t depth
Depth of the 3D shape or object.
Definition: Size3D.h:94
arm_compute::Size2D::width
size_t width
Width of the image region or rectangle.
Definition: Size2D.h:90
arm_compute::Padding3D::top
size_t top
Padding across the height dimenstion on the top, in elements.
Definition: Types.h:636
arm_compute::test::validation::gemm_info
gemm_info
Definition: GEMMMatrixMultiplyReshaped.cpp:862
arm_compute::misc::shape_calculator::compute_vector_to_tensor_output_shape
TensorShape compute_vector_to_tensor_output_shape(const TensorShape &input, size_t conv_w, size_t conv_h, const DataLayout &data_layout)
Calculate the output tensor shape of a vector input given the convolution dimensions.
Definition: ShapeCalculator.h:89
arm_compute::DataLayoutDimension::HEIGHT
@ HEIGHT
height
ARM_COMPUTE_ERROR_ON_MSG
#define ARM_COMPUTE_ERROR_ON_MSG(cond, msg)
Definition: Error.h:457
width_dim
constexpr unsigned int width_dim
Definition: Conv3D.cpp:35
arm_compute::TensorShape::total_size
size_t total_size() const
Collapses all dimensions to a single linear total size.
Definition: TensorShape.h:176
arm_compute::misc::shape_calculator::compute_softmax_shape
TensorShape compute_softmax_shape(const ITensorInfo *input, size_t axis=1)
Calculate the softmax output shape of a tensor.
Definition: ShapeCalculator.h:581
arm_compute::misc::shape_calculator::compute_flatten_shape
TensorShape compute_flatten_shape(const ITensorInfo *input)
Calculate the flattened output shape of a tensor.
Definition: ShapeCalculator.h:563
arm_compute::PoolingLayerInfo
Pooling Layer Information struct.
Definition: Types.h:1018
arm_compute::Pooling3dLayerInfo::is_global_pooling
bool is_global_pooling
Definition: Types.h:1228
arm_compute::misc::shape_calculator::compute_unpool_shape
TensorShape compute_unpool_shape(const ITensorInfo &input, PoolingLayerInfo pool_info)
Calculate the output unpool shape of a tensor.
Definition: ShapeCalculator.h:837
arm_compute::misc::shape_calculator::compute_winograd_filter_transform_shape
TensorShape compute_winograd_filter_transform_shape(const ITensorInfo &input, const WinogradInfo &winograd_info)
Calculate the winograd filter transform shape.
Definition: ShapeCalculator.h:620
arm_compute::misc::shape_calculator::compute_tiled_shape
TensorShape compute_tiled_shape(const TensorShape &input_shape, const Multiples &multiples)
Calculate the tiled shape of a tensor.
Definition: ShapeCalculator.h:1295
arm_compute::DirectConvComputeKernelInfo::m0
int32_t m0
Number of rows to be processed by the kernel.
Definition: KernelDescriptors.h:117
arm_compute::Padding3D::back
size_t back
Padding across the depth dimenstion on the back, in elements.
Definition: Types.h:639
arm_compute::Padding3D::front
size_t front
Padding across the depth dimenstion on the front, in elements.
Definition: Types.h:638
arm_compute::misc::shape_calculator::compute_winograd_output_transform_shape
TensorShape compute_winograd_output_transform_shape(const ITensorInfo &input, const WinogradInfo &winograd_info)
Calculate the winograd output transform shape.
Definition: ShapeCalculator.h:679
arm_compute::misc::shape_calculator::compute_reduced_shape
TensorShape compute_reduced_shape(const TensorShape &input, unsigned int axis, bool keep_dims=true)
Calculate the reduced shape of a tensor given an axis.
Definition: ShapeCalculator.h:1313
arm_compute::misc::shape_calculator::compute_prior_box_shape
TensorShape compute_prior_box_shape(const ITensorInfo &input, const PriorBoxLayerInfo &info)
Calculate the prior box output shape of a tensor.
Definition: ShapeCalculator.h:1255
arm_compute::Size2D::x
size_t x() const
Semantic accessor for width as x.
Definition: Size2D.h:75
arm_compute::PriorBoxLayerInfo
PriorBox layer info.
Definition: Types.h:643
ARM_COMPUTE_UNUSED
#define ARM_COMPUTE_UNUSED(...)
To avoid unused variables warnings.
Definition: Error.h:152
arm_compute::Dimensions::collapse_from
void collapse_from(size_t start)
Collapse dimensions starting from a given point.
Definition: Dimensions.h:183
arm_compute::Coordinates
Coordinates of an item.
Definition: Coordinates.h:37
tensor
CLTensor * tensor
Pointer to the auxiliary tensor.
Definition: ClWorkloadRuntime.cpp:66
arm_compute::Size3D::z
size_t z() const
Semantic accessor for depth as z.
Definition: Size3D.h:76
arm_compute::PadStrideInfo
Definition: CoreTypes.h:138
arm_compute::misc::shape_calculator::compute_space_to_batch_shape
TensorShape compute_space_to_batch_shape(const ITensorInfo *input, int block_x, int block_y, const Size2D &padding_left, const Size2D &padding_right)
Calculate the space to batch output shape of a tensor.
Definition: ShapeCalculator.h:1206
arm_compute::Dimensions::begin
std::array< T, num_max_dimensions >::iterator begin()
Returns a read/write iterator that points to the first element in the dimension array.
Definition: Dimensions.h:215
arm_compute::Window::DimY
static constexpr size_t DimY
Alias for dimension 1 also known as Y dimension.
Definition: Window.h:45
channel_dim
constexpr unsigned int channel_dim
Definition: Conv3D.cpp:36
arm_compute::misc::shape_calculator::compute_reductionB_shape
TensorShape compute_reductionB_shape(const ITensorInfo &a)
Calculate the reductionB shape used in GEMMLowp.
Definition: ShapeCalculator.h:352
weights_height_dim
constexpr unsigned int weights_height_dim
Definition: Conv3D.cpp:40
arm_compute::misc::shape_calculator::compute_padded_shape
TensorShape compute_padded_shape(const TensorShape &input_shape, const PaddingList &padding)
Calculate the padded shape of a tensor.
Definition: ShapeCalculator.h:1276
arm_compute::helpers::tensor_transform::compute_strided_slice_output_shape
TensorShape compute_strided_slice_output_shape(TensorShape input_shape, Coordinates starts, Coordinates ends, Coordinates strides, int32_t begin_mask=0, int32_t end_mask=0, int32_t shrink_axis_mask=0, bool return_unshrinked=false)
Computes output shape of strided slice.
Definition: tensor_transform.cpp:139
arm_compute::test::validation::input_shape
const auto input_shape
Validate test suite is to test ARM_COMPUTE_RETURN_ON_* macros we use to check the validity of given a...
Definition: ConvolutionLayer.cpp:408
arm_compute::Pooling3dLayerInfo
Pooling Layer Information struct.
Definition: Types.h:1131
arm_compute::PadStrideInfo::pad_left
unsigned int pad_left() const
Get the left padding.
Definition: CoreTypes.h:212
arm_compute::MatMulKernelInfo::adj_lhs
bool adj_lhs
Get Adjoint LHS flag value.
Definition: KernelDescriptors.h:235
Utils.h
arm_compute::get_data_layout_dimension_index
size_t get_data_layout_dimension_index(const DataLayout &data_layout, const DataLayoutDimension &data_layout_dimension)
Get the index of the given dimension.
Definition: Helpers.inl:203
arm_compute::misc::shape_calculator::compute_rhs_reshaped_shape
TensorShape compute_rhs_reshaped_shape(const ITensorInfo &a, const GEMMRHSMatrixInfo &rhs_info)
Calculate the Right Hand Side matrix reshaped shape.
Definition: ShapeCalculator.h:226
arm_compute::Padding3D::left
size_t left
Padding across the width dimenstion on the left, in elements.
Definition: Types.h:634
arm_compute::GEMMLHSMatrixInfo
GEMM LHS (Left Hand Side) matrix information.
Definition: Types.h:1803
arm_compute::DimensionRoundingType::FLOOR
@ FLOOR
Floor rounding.
arm_compute::misc::shape_calculator::compute_upsample_shape
TensorShape compute_upsample_shape(const ITensorInfo &input, const Size2D &info)
Calculate the upsampled shape of a tensor.
Definition: ShapeCalculator.h:1336
arm_compute::test::validation::num_groups
const unsigned int num_groups
Definition: Im2Col.cpp:153
KernelDescriptors.h
arm_compute::misc::shape_calculator::compute_weights_reshaped_shape
TensorShape compute_weights_reshaped_shape(const ITensorInfo &weights, bool has_bias=false, unsigned int num_groups=1)
Calculate the reshaped shape of the weights.
Definition: ShapeCalculator.h:151
arm_compute::misc::shape_calculator::compute_conv3d_shape
TensorShape compute_conv3d_shape(const TensorShape &src, const TensorShape &weights, const Conv3dInfo &conv3d_info)
Calculate the output shape of 3d Convolution.
Definition: ShapeCalculator.h:1476
M
unsigned int M
Definition: CpuGemmAssemblyDispatch.cpp:95
arm_compute::PadStrideInfo::pad_bottom
unsigned int pad_bottom() const
Get the bottom padding.
Definition: CoreTypes.h:227
arm_compute::PoolingLayerInfo::is_global_pooling
bool is_global_pooling
Definition: Types.h:1124
arm_compute::test::validation::b
SimpleTensor< float > b
Definition: DFT.cpp:157
arm_compute::GEMMReshapeInfo::depth_output_gemm3d
int depth_output_gemm3d() const
Depth (third dimension) of the output tensor to be used with the GEMM3D kernel.
Definition: Types.h:1770
arm_compute
Copyright (c) 2017-2023 Arm Limited.
Definition: introduction.dox:24
arm_compute::misc::shape_calculator::compute_batch_to_space_shape
TensorShape compute_batch_to_space_shape(DataLayout data_layout, const TensorShape &input, int block_x, int block_y, const CropInfo &crop_info=CropInfo{})
Calculate the batch to space output shape of a tensor.
Definition: ShapeCalculator.h:1113
arm_compute::scaled_3d_dimensions_signed
std::tuple< int, int, int > scaled_3d_dimensions_signed(int width, int height, int depth, int kernel_width, int kernel_height, int kernel_depth, const Pooling3dLayerInfo &pool3d_info)
Returns calculated width, height and depth of output scaled tensor depending on dimensions rounding m...
Definition: Utils.cpp:351
arm_compute::Pooling3dLayerInfo::pool_size
Size3D pool_size
Definition: Types.h:1224
arm_compute::test::validation::conv_info
const auto conv_info
Definition: ConvolutionLayer.cpp:407
arm_compute::TensorShape::remove_dimension
void remove_dimension(size_t n, bool apply_dim_correction=true)
Accessor to remove the dimension n from the tensor shape.
Definition: TensorShape.h:112
arm_compute::misc::shape_calculator::extract_shape
TensorShape extract_shape(T *data)
Get the tensor shape.
Definition: ShapeCalculator.h:1358
arm_compute::Conv3dInfo
Descriptor used by the 3d Convolution function.
Definition: FunctionDescriptors.h:82
arm_compute::ConvolutionInfo
Definition: ConvolutionInfo.h:33
arm_compute::MatMulKernelInfo
Definition: KernelDescriptors.h:228
arm_compute::Multiples
std::vector< uint32_t > Multiples
Information to produce a tiled version of a Tensor.
Definition: Types.h:416
arm_compute::Window::DimZ
static constexpr size_t DimZ
Alias for dimension 2 also known as Z dimension.
Definition: Window.h:47
weights_height
const size_t weights_height
Definition: impl.cpp:55
arm_compute::WinogradInfo::kernel_size
Size2D kernel_size
Width and height of the kernel.
Definition: Types.h:1852
arm_compute::test::validation::weights_shape
const auto weights_shape
Definition: ConvolutionLayer.cpp:409
tensor_transform.h
arm_compute::misc::shape_calculator::compute_deconvolution_upsampled_shape
TensorShape compute_deconvolution_upsampled_shape(const ITensorInfo &input, const ITensorInfo &weights, unsigned int sx, unsigned int sy, std::pair< unsigned int, unsigned int > &out_dims, uint32_t &padx, uint32_t &pady)
Calculate the upsampled output shape used for deconvolution.
Definition: ShapeCalculator.h:462
arm_compute::Padding3D::right
size_t right
Padding across the width dimenstion on the right, in elements.
Definition: Types.h:635
arm_compute::misc::shape_calculator::compute_space_to_depth_shape
TensorShape compute_space_to_depth_shape(const ITensorInfo *input, int32_t block_shape)
Calculate the space to batch output shape of a tensor.
Definition: ShapeCalculator.h:1232
arm_compute::Padding3D::bottom
size_t bottom
Padding across the height dimenstion on the bottom, in elements.
Definition: Types.h:637
arm_compute::ITensorInfo
Store the tensor's metadata.
Definition: ITensorInfo.h:43
arm_compute::DataLayoutDimension::BATCHES
@ BATCHES
batches
arm_compute::Padding2D
Padding and stride information class.
Definition: Types.h:604
arm_compute::test::validation::info
ScaleKernelInfo info(interpolation_policy, default_border_mode, PixelValue(), sampling_policy, false)
arm_compute::WinogradInfo::convolution_info
PadStrideInfo convolution_info
Convolution info (Pads, strides,...)
Definition: Types.h:1854
arm_compute::TensorShape::set
TensorShape & set(size_t dimension, size_t value, bool apply_dim_correction=true, bool increase_dim_unit=true)
Accessor to set the value of one of the dimensions.
Definition: TensorShape.h:79
arm_compute::convert_negative_axis
Coordinates & convert_negative_axis(Coordinates &coords, int max_value)
Convert negative coordinates to positive in the range [0, num_dims_input].
Definition: Helpers.h:278
arm_compute::misc::shape_calculator::compute_split_shape
TensorShape compute_split_shape(const ITensorInfo *input, unsigned int axis, unsigned int num_splits)
Calculate the split output shape of a tensor.
Definition: ShapeCalculator.h:1171
batch_dim
constexpr unsigned int batch_dim
Definition: Conv3D.cpp:32
arm_compute::misc::shape_calculator::compute_deep_convolution_shape
TensorShape compute_deep_convolution_shape(const TensorShape &input_shape, DataLayout input_data_layout, const TensorShape &weights_shape, const PadStrideInfo &conv_info)
Calculate the deep convolution shape output shape of a tensor.
Definition: ShapeCalculator.h:715
arm_compute::GEMMRHSMatrixInfo
GEMM RHS (Right Hand Side) matrix information.
Definition: Types.h:1818
arm_compute::misc::shape_calculator::compute_col2im_shape
TensorShape compute_col2im_shape(const ITensorInfo &input, const Size2D &convolved_dims, bool batch_size_on_z, unsigned int num_groups=1)
Calculate the Col2Im shape.
Definition: ShapeCalculator.h:373
arm_compute::PoolingLayerInfo::pad_stride_info
PadStrideInfo pad_stride_info
Definition: Types.h:1122
arm_compute::Dimensions::num_dimensions
unsigned int num_dimensions() const
Returns the effective dimensionality of the tensor.
Definition: Dimensions.h:143
arm_compute::ROIPoolingLayerInfo
ROI Pooling Layer Information class.
Definition: Types.h:1234
input_height
const size_t input_height
Definition: impl.cpp:62
arm_compute::Dimensions< int >::num_max_dimensions
static constexpr size_t num_max_dimensions
Number of dimensions the tensor has.
Definition: Dimensions.h:46
arm_compute::PadStrideInfo::pad_top
unsigned int pad_top() const
Get the top padding.
Definition: CoreTypes.h:222
arm_compute::test::validation::input
auto input
Definition: LSTMLayerQuantized.cpp:486
arm_compute::ITensorInfo::num_dimensions
virtual size_t num_dimensions() const =0
The number of dimensions of the tensor (rank)
arm_compute::PadStrideInfo::stride
std::pair< unsigned int, unsigned int > stride() const
Get the stride.
Definition: CoreTypes.h:186
arm_compute::DataLayout::NDHWC
@ NDHWC
Num samples, depth, height, width, channels.
arm_compute::Conv3dInfo::round_type
DimensionRoundingType round_type
Definition: FunctionDescriptors.h:100
arm_compute::DirectConvComputeKernelInfo
Compute descriptor used by the direct convolution kernel.
Definition: KernelDescriptors.h:115
arm_compute::TensorShape::collapse
void collapse(size_t n, size_t first=0)
Collapse the first n dimensions.
Definition: TensorShape.h:137