Compute Library
 21.08
Dimensions.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2017-2021 Arm Limited.
3  *
4  * SPDX-License-Identifier: MIT
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and associated documentation files (the "Software"), to
8  * deal in the Software without restriction, including without limitation the
9  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10  * sell copies of the Software, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in all
14  * copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22  * SOFTWARE.
23  */
24 #ifndef ARM_COMPUTE_DIMENSIONS_H
25 #define ARM_COMPUTE_DIMENSIONS_H
26 
27 #include "arm_compute/core/Error.h"
28 
29 #include <algorithm>
30 #include <array>
31 #include <functional>
32 #include <limits>
33 #include <numeric>
34 
35 namespace arm_compute
36 {
37 /** Constant value used to indicate maximum dimensions of a Window, TensorShape and Coordinates */
38 constexpr size_t MAX_DIMS = 6;
39 
40 /** Dimensions with dimensionality */
41 template <typename T>
43 {
44 public:
45  /** Number of dimensions the tensor has */
46  static constexpr size_t num_max_dimensions = MAX_DIMS;
47 
48  /** Constructor to initialize the tensor shape.
49  *
50  * @param[in] dims Values to initialize the dimensions.
51  */
52  template <typename... Ts>
53  explicit Dimensions(Ts... dims)
54  : _id{ { static_cast<T>(dims)... } }, _num_dimensions{ sizeof...(dims) }
55  {
56  }
57 
58  /** Allow instances of this class to be copy constructed */
59  Dimensions(const Dimensions &) = default;
60 
61  /** Allow instances of this class to be copied */
62  Dimensions &operator=(const Dimensions &) = default;
63 
64  /** Allow instances of this class to be move constructed */
65  Dimensions(Dimensions &&) = default;
66 
67  /** Allow instances of this class to be moved */
68  Dimensions &operator=(Dimensions &&) = default;
69 
70  /** Accessor to set the value of one of the dimensions.
71  *
72  * @param[in] dimension Dimension for which the value is set.
73  * @param[in] value Value to be set for the dimension.
74  * @param[in] increase_dim_unit (Optional) Set to true if new unit dimensions increase the number of dimensions (e.g. for Coordinates), false otherwise (e.g. for TensorShapes)
75  */
76  void set(size_t dimension, T value, bool increase_dim_unit = true)
77  {
78  ARM_COMPUTE_ERROR_ON(dimension >= num_max_dimensions);
79  _id[dimension] = value;
80  // Don't increase the number of dimensions if the new dimension is 1
81  if(increase_dim_unit || value != 1)
82  {
83  _num_dimensions = std::max(_num_dimensions, dimension + 1);
84  }
85  }
86  /** Alias to access the size of the first dimension */
87  T x() const
88  {
89  return _id[0];
90  }
91  /** Alias to access the size of the second dimension */
92  T y() const
93  {
94  return _id[1];
95  }
96  /** Alias to access the size of the third dimension */
97  T z() const
98  {
99  return _id[2];
100  }
101  /** Increments the given dimension by a step size, avoiding overflows
102  *
103  * @note Precondition: dim < _num_dimensions
104  *
105  * @param[in] dim Dimension to increment.
106  * @param[in] step Step to increment @p dim by.
107  */
108  void increment(size_t dim, T step = 1)
109  {
110  ARM_COMPUTE_ERROR_ON(dim >= _num_dimensions);
111  if((std::numeric_limits<T>::max() - _id[dim]) >= step)
112  {
113  _id[dim] += step;
114  }
115  }
116  /** Generic accessor to get the size of any dimension
117  *
118  * @note Precondition: dimension < Dimensions::num_max_dimensions
119  *
120  * @param[in] dimension Dimension of the wanted size
121  *
122  * @return The size of the requested dimension.
123  */
124  const T &operator[](size_t dimension) const
125  {
126  ARM_COMPUTE_ERROR_ON(dimension >= num_max_dimensions);
127  return _id[dimension];
128  }
129  /** Generic accessor to get the size of any dimension
130  *
131  * @note Precondition: dimension < Dimensions::num_max_dimensions
132  *
133  * @param[in] dimension Dimension of the wanted size
134  *
135  * @return The size of the requested dimension.
136  */
137  T &operator[](size_t dimension)
138  {
139  ARM_COMPUTE_ERROR_ON(dimension >= num_max_dimensions);
140  return _id[dimension];
141  }
142  /** Returns the effective dimensionality of the tensor */
143  unsigned int num_dimensions() const
144  {
145  return _num_dimensions;
146  }
147 
148  /** Set number of dimensions */
150  {
151  _num_dimensions = num_dimensions;
152  }
153 
154  /** Collapse dimensions.
155  *
156  * @param[in] n Number of dimensions to collapse into @p first.
157  * @param[in] first Dimensions into which the following @p n are collapsed.
158  */
159  void collapse(const size_t n, const size_t first = 0)
160  {
161  ARM_COMPUTE_ERROR_ON(first + n > _id.size());
162 
163  const size_t last = std::min(_num_dimensions, first + n);
164 
165  if(last > (first + 1))
166  {
167  // Collapse dimensions into the first
168  _id[first] = std::accumulate(&_id[first], &_id[last], 1, std::multiplies<T>());
169  // Shift the remaining dimensions down
170  std::copy(&_id[last], &_id[_num_dimensions], &_id[first + 1]);
171  // Reduce the number of dimensions
172  const size_t old_num_dimensions = _num_dimensions;
173  _num_dimensions -= last - first - 1;
174  // Fill the now empty dimensions with zero
175  std::fill(&_id[_num_dimensions], &_id[old_num_dimensions], 0);
176  }
177  }
178 
179  /** Collapse dimensions starting from a given point
180  *
181  * @param[in] start Starting point of collapsing dimensions
182  */
183  void collapse_from(size_t start)
184  {
186 
187  collapse(num_dimensions() - start, start);
188  }
189 
190  /** Remove dimension of a given index
191  *
192  * @note If index is greater than the number of dimensions no operation is performed
193  *
194  * @param[in] idx Dimension index to remove
195  */
196  void remove(size_t idx)
197  {
198  ARM_COMPUTE_ERROR_ON(_num_dimensions < 1);
199  if(idx >= _num_dimensions)
200  {
201  return;
202  }
203 
204  std::copy(_id.begin() + idx + 1, _id.end(), _id.begin() + idx);
205  _num_dimensions--;
206 
207  // Make sure all empty dimensions are filled with 0
208  std::fill(_id.begin() + _num_dimensions, _id.end(), 0);
209  }
210 
211  /** Returns a read/write iterator that points to the first element in the dimension array.
212  *
213  * @return an iterator.
214  */
215  typename std::array<T, num_max_dimensions>::iterator begin()
216  {
217  return _id.begin();
218  }
219  /** Returns a read-only (constant) iterator that points to the first element in the dimension array.
220  *
221  * @return an iterator.
222  */
223  typename std::array<T, num_max_dimensions>::const_iterator begin() const
224  {
225  return _id.begin();
226  }
227  /** Returns a read-only (constant) iterator that points to the first element in the dimension array.
228  *
229  * @return an iterator.
230  */
231  typename std::array<T, num_max_dimensions>::const_iterator cbegin() const
232  {
233  return begin();
234  }
235  /** Returns a read/write iterator that points one past the last element in the dimension array.
236  *
237  * @return an iterator.
238  */
239  typename std::array<T, num_max_dimensions>::iterator end()
240  {
241  return _id.end();
242  }
243  /** Returns a read-only (constant) iterator that points one past the last element in the dimension array.
244  *
245  * @return an iterator.
246  */
247  typename std::array<T, num_max_dimensions>::const_iterator end() const
248  {
249  return _id.end();
250  }
251  /** Returns a read-only (constant) iterator that points one past the last element in the dimension array.
252  *
253  * @return an iterator.
254  */
255  typename std::array<T, num_max_dimensions>::const_iterator cend() const
256  {
257  return end();
258  }
259 
260 protected:
261  /** Protected destructor. */
262  ~Dimensions() = default;
263 
264  std::array<T, num_max_dimensions> _id;
265  size_t _num_dimensions{ 0 };
266 };
267 
268 /** Check that given dimensions are equal.
269  *
270  * @param[in] lhs Left-hand side Dimensions.
271  * @param[in] rhs Right-hand side Dimensions.
272  *
273  * @return True if the given dimensions are equal.
274  */
275 template <typename T>
276 inline bool operator==(const Dimensions<T> &lhs, const Dimensions<T> &rhs)
277 {
278  return ((lhs.num_dimensions() == rhs.num_dimensions()) && std::equal(lhs.cbegin(), lhs.cend(), rhs.cbegin()));
279 }
280 /** Check that given dimensions are not equal.
281  *
282  * @param[in] lhs Left-hand side Dimensions.
283  * @param[in] rhs Right-hand side Dimensions.
284  *
285  * @return True if the given dimensions are not equal.
286  */
287 template <typename T>
288 inline bool operator!=(const Dimensions<T> &lhs, const Dimensions<T> &rhs)
289 {
290  return !(lhs == rhs);
291 }
292 }
293 #endif /*ARM_COMPUTE_DIMENSIONS_H*/
std::array< T, num_max_dimensions >::const_iterator begin() const
Returns a read-only (constant) iterator that points to the first element in the dimension array...
Definition: Dimensions.h:223
T & operator[](size_t dimension)
Generic accessor to get the size of any dimension.
Definition: Dimensions.h:137
Dimensions & operator=(const Dimensions &)=default
Allow instances of this class to be copied.
bool operator!=(const Dimensions< T > &lhs, const Dimensions< T > &rhs)
Check that given dimensions are not equal.
Definition: Dimensions.h:288
#define ARM_COMPUTE_ERROR_ON(cond)
If the condition is true then an error message is printed and an exception thrown.
Definition: Error.h:466
bool operator==(const Dimensions< T > &lhs, const Dimensions< T > &rhs)
Check that given dimensions are equal.
Definition: Dimensions.h:276
SimpleTensor< T > copy(const SimpleTensor< T > &src, const TensorShape &output_shape)
Definition: Copy.cpp:37
SimpleTensor< T2 > accumulate(const SimpleTensor< T1 > &src, DataType output_data_type)
Definition: Accumulate.cpp:38
void collapse(const size_t n, const size_t first=0)
Collapse dimensions.
Definition: Dimensions.h:159
Copyright (c) 2017-2021 Arm Limited.
constexpr size_t MAX_DIMS
Constant value used to indicate maximum dimensions of a Window, TensorShape and Coordinates.
Definition: Dimensions.h:38
T x() const
Alias to access the size of the first dimension.
Definition: Dimensions.h:87
void collapse_from(size_t start)
Collapse dimensions starting from a given point.
Definition: Dimensions.h:183
library fill(src, distribution, 0)
T z() const
Alias to access the size of the third dimension.
Definition: Dimensions.h:97
Dimensions with dimensionality.
Definition: Dimensions.h:42
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
std::array< T, num_max_dimensions >::const_iterator cend() const
Returns a read-only (constant) iterator that points one past the last element in the dimension array...
Definition: Dimensions.h:255
std::array< T, num_max_dimensions >::const_iterator cbegin() const
Returns a read-only (constant) iterator that points to the first element in the dimension array...
Definition: Dimensions.h:231
const T & operator[](size_t dimension) const
Generic accessor to get the size of any dimension.
Definition: Dimensions.h:124
std::array< 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:239
void increment(size_t dim, T step=1)
Increments the given dimension by a step size, avoiding overflows.
Definition: Dimensions.h:108
constexpr int step
Definition: fp32.cpp:35
unsigned int num_dimensions() const
Returns the effective dimensionality of the tensor.
Definition: Dimensions.h:143
Dimensions(Ts... dims)
Constructor to initialize the tensor shape.
Definition: Dimensions.h:53
std::array< T, num_max_dimensions >::const_iterator end() const
Returns a read-only (constant) iterator that points one past the last element in the dimension array...
Definition: Dimensions.h:247
void set_num_dimensions(size_t num_dimensions)
Set number of dimensions.
Definition: Dimensions.h:149
T y() const
Alias to access the size of the second dimension.
Definition: Dimensions.h:92
static constexpr size_t num_max_dimensions
Number of dimensions the tensor has.
Definition: Dimensions.h:46