Compute Library
 19.08
TensorShape.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2016-2018 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 __ARM_COMPUTE_TENSORSHAPE_H__
25 #define __ARM_COMPUTE_TENSORSHAPE_H__
26 
28 #include "arm_compute/core/Error.h"
30 
31 #include <algorithm>
32 #include <array>
33 #include <functional>
34 #include <numeric>
35 
36 namespace arm_compute
37 {
39 class TensorShape : public Dimensions<size_t>
40 {
41 public:
46  template <typename... Ts>
47  TensorShape(Ts... dims)
48  : Dimensions{ dims... }
49  {
50  // Initialize unspecified dimensions to 1
51  if(_num_dimensions > 0)
52  {
53  std::fill(_id.begin() + _num_dimensions, _id.end(), 1);
54  }
55 
56  // Correct number dimensions to ignore trailing dimensions of size 1
57  apply_dimension_correction();
58  }
60  TensorShape(const TensorShape &) = default;
62  TensorShape &operator=(const TensorShape &) = default;
64  TensorShape(TensorShape &&) = default;
66  TensorShape &operator=(TensorShape &&) = default;
68  ~TensorShape() = default;
69 
78  TensorShape &set(size_t dimension, size_t value, bool apply_dim_correction = true)
79  {
80  // Clear entire shape if one dimension is zero
81  if(value == 0)
82  {
83  _num_dimensions = 0;
84  std::fill(_id.begin(), _id.end(), 0);
85  }
86  else
87  {
88  // Make sure all empty dimensions are filled with 1
89  std::fill(_id.begin() + _num_dimensions, _id.end(), 1);
90 
91  // Set the specified dimension and increase the number of dimensions if
92  // necessary
93  Dimensions::set(dimension, value);
94 
95  // Correct number dimensions to ignore trailing dimensions of size 1
96  if(apply_dim_correction)
97  {
98  apply_dimension_correction();
99  }
100  }
101  return *this;
102  }
103 
110  void remove_dimension(size_t n)
111  {
112  ARM_COMPUTE_ERROR_ON(_num_dimensions < 1);
113  ARM_COMPUTE_ERROR_ON(n >= _num_dimensions);
114 
115  std::copy(_id.begin() + n + 1, _id.end(), _id.begin() + n);
116 
117  // Reduce number of dimensions
118  _num_dimensions--;
119 
120  // Make sure all empty dimensions are filled with 1
121  std::fill(_id.begin() + _num_dimensions, _id.end(), 1);
122 
123  // Correct number dimensions to ignore trailing dimensions of size 1
124  apply_dimension_correction();
125  }
126 
132  void collapse(size_t n, size_t first = 0)
133  {
134  Dimensions::collapse(n, first);
135 
136  // Make sure all empty dimensions are filled with 1
137  std::fill(_id.begin() + _num_dimensions, _id.end(), 1);
138  }
143  void shift_right(size_t step)
144  {
146 
147  std::rotate(begin(), begin() + TensorShape::num_max_dimensions - step, end());
148  _num_dimensions += step;
149 
150  // Correct number dimensions to ignore trailing dimensions of size 1
151  apply_dimension_correction();
152  }
153 
160  TensorShape collapsed_from(size_t start) const
161  {
162  TensorShape copy(*this);
163  copy.collapse(num_dimensions() - start, start);
164  return copy;
165  }
166 
171  size_t total_size() const
172  {
173  return std::accumulate(_id.begin(), _id.end(), 1, std::multiplies<size_t>());
174  }
181  size_t total_size_upper(size_t dimension) const
182  {
184  return std::accumulate(_id.begin() + dimension, _id.end(), 1, std::multiplies<size_t>());
185  }
186 
193  size_t total_size_lower(size_t dimension) const
194  {
196  return std::accumulate(_id.begin(), _id.begin() + dimension, 1, std::multiplies<size_t>());
197  }
198 
209  template <typename... Shapes>
210  static TensorShape broadcast_shape(const Shapes &... shapes)
211  {
212  TensorShape bc_shape;
213 
214  auto broadcast = [&bc_shape](const TensorShape & other)
215  {
216  if(bc_shape.num_dimensions() == 0)
217  {
218  bc_shape = other;
219  }
220  else if(other.num_dimensions() != 0)
221  {
222  for(size_t d = 0; d < TensorShape::num_max_dimensions; ++d)
223  {
224  const size_t dim_min = std::min(bc_shape[d], other[d]);
225  const size_t dim_max = std::max(bc_shape[d], other[d]);
226 
227  if((dim_min != 1) && (dim_min != dim_max))
228  {
229  bc_shape = TensorShape{ 0U };
230  break;
231  }
232 
233  bc_shape.set(d, dim_max);
234  }
235  }
236  };
237 
238  utility::for_each(broadcast, shapes...);
239 
240  return bc_shape;
241  }
242 
243 private:
245  void apply_dimension_correction()
246  {
247  for(int i = static_cast<int>(_num_dimensions) - 1; i > 0; --i)
248  {
249  if(_id[i] == 1)
250  {
251  --_num_dimensions;
252  }
253  else
254  {
255  break;
256  }
257  }
258  }
259 };
260 }
261 #endif /*__ARM_COMPUTE_TENSORSHAPE_H__*/
void shift_right(size_t step)
Shifts right the tensor shape increasing its dimensions.
Definition: TensorShape.h:143
Shape of a tensor.
Definition: TensorShape.h:39
void remove_dimension(size_t n)
Accessor to remove the dimension n from the tensor shape.
Definition: TensorShape.h:110
TensorShape collapsed_from(size_t start) const
Return a copy with collapsed dimensions starting from a given point.
Definition: TensorShape.h:160
TensorShape & operator=(const TensorShape &)=default
Allow instances of this class to be copied.
static TensorShape broadcast_shape(const Shapes &... shapes)
If shapes are broadcast compatible, return the broadcasted shape.
Definition: TensorShape.h:210
#define ARM_COMPUTE_ERROR_ON(cond)
If the condition is true then an error message is printed and an exception thrown.
Definition: Error.h:337
size_t total_size_upper(size_t dimension) const
Collapses given dimension and above.
Definition: TensorShape.h:181
SimpleTensor< T > copy(const SimpleTensor< T > &src, const TensorShape &output_shape)
Definition: Copy.cpp:37
void set(size_t dimension, T value)
Accessor to set the value of one of the dimensions.
Definition: Dimensions.h:74
size_t total_size_lower(size_t dimension) const
Compute size of dimensions lower than the given one.
Definition: TensorShape.h:193
void collapse(const size_t n, const size_t first=0)
Collapse dimensions.
Definition: Dimensions.h:138
Copyright (c) 2017-2018 ARM Limited.
TensorShape(Ts... dims)
Constructor to initialize the tensor shape.
Definition: TensorShape.h:47
library fill(src, distribution, 0)
size_t total_size() const
Collapses all dimensions to a single linear total size.
Definition: TensorShape.h:171
Dimensions with dimensionality.
Definition: Dimensions.h:41
std::array< size_t, num_max_dimensions >::iterator begin()
Returns a read/write iterator that points to the first element in the dimension array.
Definition: Dimensions.h:194
void for_each(F &&)
Base case of for_each.
Definition: Utility.h:93
std::array< size_t, num_max_dimensions >::iterator end()
Returns a read/write iterator that points one past the last element in the dimension array.
Definition: Dimensions.h:218
unsigned int num_dimensions() const
Returns the effective dimensionality of the tensor.
Definition: Dimensions.h:122
TensorShape & set(size_t dimension, size_t value, bool apply_dim_correction=true)
Accessor to set the value of one of the dimensions.
Definition: TensorShape.h:78
__kernel void accumulate(__global uchar *input_ptr, uint input_stride_x, uint input_step_x, uint input_stride_y, uint input_step_y, uint input_offset_first_element_in_bytes, __global uchar *accu_ptr, uint accu_stride_x, uint accu_step_x, uint accu_stride_y, uint accu_step_y, uint accu_offset_first_element_in_bytes)
This function accumulates an input image into output image.
Definition: accumulate.cl:41
~TensorShape()=default
Default destructor.
static constexpr size_t num_max_dimensions
Number of dimensions the tensor has.
Definition: Dimensions.h:45
void collapse(size_t n, size_t first=0)
Collapse the first n dimensions.
Definition: TensorShape.h:132