Compute Library
 23.11
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) : _id{{static_cast<T>(dims)...}}, _num_dimensions{sizeof...(dims)}
54  {
55  }
56 
57  /** Allow instances of this class to be copy constructed */
58  Dimensions(const Dimensions &) = default;
59 
60  /** Allow instances of this class to be copied */
61  Dimensions &operator=(const Dimensions &) = default;
62 
63  /** Allow instances of this class to be move constructed */
64  Dimensions(Dimensions &&) = default;
65 
66  /** Allow instances of this class to be moved */
67  Dimensions &operator=(Dimensions &&) = default;
68 
69  /** Accessor to set the value of one of the dimensions.
70  *
71  * @param[in] dimension Dimension for which the value is set.
72  * @param[in] value Value to be set for the dimension.
73  * @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)
74  */
75  void set(size_t dimension, T value, bool increase_dim_unit = true)
76  {
78  _id[dimension] = value;
79  // Don't increase the number of dimensions if the new dimension is 1
80  if (increase_dim_unit || value != 1)
81  {
82  _num_dimensions = std::max(_num_dimensions, dimension + 1);
83  }
84  }
85  /** Alias to access the size of the first dimension */
86  T x() const
87  {
88  return _id[0];
89  }
90  /** Alias to access the size of the second dimension */
91  T y() const
92  {
93  return _id[1];
94  }
95  /** Alias to access the size of the third dimension */
96  T z() const
97  {
98  return _id[2];
99  }
100  /** Increments the given dimension by a step size, avoiding overflows
101  *
102  * @note Precondition: dim < _num_dimensions
103  *
104  * @param[in] dim Dimension to increment.
105  * @param[in] step Step to increment @p dim by.
106  */
107  void increment(size_t dim, T step = 1)
108  {
109  ARM_COMPUTE_ERROR_ON(dim >= _num_dimensions);
110  if ((std::numeric_limits<T>::max() - _id[dim]) >= step)
111  {
112  _id[dim] += step;
113  }
114  }
115  /** Generic accessor to get the size of any dimension
116  *
117  * @note Precondition: dimension < Dimensions::num_max_dimensions
118  *
119  * @param[in] dimension Dimension of the wanted size
120  *
121  * @return The size of the requested dimension.
122  */
123  const T &operator[](size_t dimension) const
124  {
126  return _id[dimension];
127  }
128  /** Generic accessor to get the size of any dimension
129  *
130  * @note Precondition: dimension < Dimensions::num_max_dimensions
131  *
132  * @param[in] dimension Dimension of the wanted size
133  *
134  * @return The size of the requested dimension.
135  */
136  T &operator[](size_t dimension)
137  {
139  return _id[dimension];
140  }
141  /** Returns the effective dimensionality of the tensor */
142  unsigned int num_dimensions() const
143  {
144  return _num_dimensions;
145  }
146 
147  /** Set number of dimensions */
149  {
150  _num_dimensions = num_dimensions;
151  }
152 
153  /** Collapse dimensions.
154  *
155  * @param[in] n Number of dimensions to collapse into @p first.
156  * @param[in] first Dimensions into which the following @p n are collapsed.
157  */
158  void collapse(const size_t n, const size_t first = 0)
159  {
160  ARM_COMPUTE_ERROR_ON(first + n > _id.size());
161 
162  const size_t last = std::min(_num_dimensions, first + n);
163 
164  if (last > (first + 1))
165  {
166  // Collapse dimensions into the first
167  _id[first] = std::accumulate(&_id[first], &_id[last], 1, std::multiplies<T>());
168  // Shift the remaining dimensions down
169  std::copy(&_id[last], &_id[_num_dimensions], &_id[first + 1]);
170  // Reduce the number of dimensions
171  const size_t old_num_dimensions = _num_dimensions;
172  _num_dimensions -= last - first - 1;
173  // Fill the now empty dimensions with zero
174  std::fill(&_id[_num_dimensions], &_id[old_num_dimensions], 0);
175  }
176  }
177 
178  /** Collapse dimensions starting from a given point
179  *
180  * @param[in] start Starting point of collapsing dimensions
181  */
182  void collapse_from(size_t start)
183  {
185 
186  collapse(num_dimensions() - start, start);
187  }
188 
189  /** Remove dimension of a given index
190  *
191  * @note If index is greater than the number of dimensions no operation is performed
192  *
193  * @param[in] idx Dimension index to remove
194  */
195  void remove(size_t idx)
196  {
197  ARM_COMPUTE_ERROR_ON(_num_dimensions < 1);
198  if (idx >= _num_dimensions)
199  {
200  return;
201  }
202 
203  std::copy(_id.begin() + idx + 1, _id.end(), _id.begin() + idx);
204  _num_dimensions--;
205 
206  // Make sure all empty dimensions are filled with 0
207  std::fill(_id.begin() + _num_dimensions, _id.end(), 0);
208  }
209 
210  /** Returns a read/write iterator that points to the first element in the dimension array.
211  *
212  * @return an iterator.
213  */
214  typename std::array<T, num_max_dimensions>::iterator begin()
215  {
216  return _id.begin();
217  }
218  /** Returns a read-only (constant) iterator that points to the first element in the dimension array.
219  *
220  * @return an iterator.
221  */
222  typename std::array<T, num_max_dimensions>::const_iterator begin() const
223  {
224  return _id.begin();
225  }
226  /** Returns a read-only (constant) iterator that points to the first element in the dimension array.
227  *
228  * @return an iterator.
229  */
230  typename std::array<T, num_max_dimensions>::const_iterator cbegin() const
231  {
232  return begin();
233  }
234  /** Returns a read/write iterator that points one past the last element in the dimension array.
235  *
236  * @return an iterator.
237  */
238  typename std::array<T, num_max_dimensions>::iterator end()
239  {
240  return _id.end();
241  }
242  /** Returns a read-only (constant) iterator that points one past the last element in the dimension array.
243  *
244  * @return an iterator.
245  */
246  typename std::array<T, num_max_dimensions>::const_iterator end() const
247  {
248  return _id.end();
249  }
250  /** Returns a read-only (constant) iterator that points one past the last element in the dimension array.
251  *
252  * @return an iterator.
253  */
254  typename std::array<T, num_max_dimensions>::const_iterator cend() const
255  {
256  return end();
257  }
258 
259 protected:
260  /** Protected destructor. */
261  ~Dimensions() = default;
262 
263  std::array<T, num_max_dimensions> _id;
264  size_t _num_dimensions{0};
265 };
266 
267 /** Check that given dimensions are equal.
268  *
269  * @param[in] lhs Left-hand side Dimensions.
270  * @param[in] rhs Right-hand side Dimensions.
271  *
272  * @return True if the given dimensions are equal.
273  */
274 template <typename T>
275 inline bool operator==(const Dimensions<T> &lhs, const Dimensions<T> &rhs)
276 {
277  return ((lhs.num_dimensions() == rhs.num_dimensions()) && std::equal(lhs.cbegin(), lhs.cend(), rhs.cbegin()));
278 }
279 /** Check that given dimensions are not equal.
280  *
281  * @param[in] lhs Left-hand side Dimensions.
282  * @param[in] rhs Right-hand side Dimensions.
283  *
284  * @return True if the given dimensions are not equal.
285  */
286 template <typename T>
287 inline bool operator!=(const Dimensions<T> &lhs, const Dimensions<T> &rhs)
288 {
289  return !(lhs == rhs);
290 }
291 } // namespace arm_compute
292 #endif /*ARM_COMPUTE_DIMENSIONS_H*/
arm_compute::Dimensions::remove
void remove(size_t idx)
Remove dimension of a given index.
Definition: Dimensions.h:195
arm_compute::Dimensions::set
void set(size_t dimension, T value, bool increase_dim_unit=true)
Accessor to set the value of one of the dimensions.
Definition: Dimensions.h:75
arm_compute::Dimensions::begin
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:222
arm_compute::Dimensions::operator[]
T & operator[](size_t dimension)
Generic accessor to get the size of any dimension.
Definition: Dimensions.h:136
Error.h
arm_compute::Dimensions::z
T z() const
Alias to access the size of the third dimension.
Definition: Dimensions.h:96
arm_compute::operator==
bool operator==(const Dimensions< T > &lhs, const Dimensions< T > &rhs)
Check that given dimensions are equal.
Definition: Dimensions.h:275
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:466
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::Dimensions::collapse
void collapse(const size_t n, const size_t first=0)
Collapse dimensions.
Definition: Dimensions.h:158
arm_compute::test::validation::fill
library fill(src, distribution, 0)
arm_compute::Dimensions::cbegin
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:230
arm_compute::Dimensions::x
T x() const
Alias to access the size of the first dimension.
Definition: Dimensions.h:86
arm_compute::test::validation::reference::copy
SimpleTensor< T > copy(const SimpleTensor< T > &src, const TensorShape &output_shape)
Definition: Copy.cpp:37
arm_compute::test::validation::reference::accumulate
SimpleTensor< T2 > accumulate(const SimpleTensor< T1 > &src, DataType output_data_type)
Definition: Accumulate.cpp:38
arm_compute::Dimensions::cend
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:254
arm_compute::Dimensions::collapse_from
void collapse_from(size_t start)
Collapse dimensions starting from a given point.
Definition: Dimensions.h:182
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:214
arm_compute::Dimensions::operator[]
const T & operator[](size_t dimension) const
Generic accessor to get the size of any dimension.
Definition: Dimensions.h:123
arm_compute::Dimensions::Dimensions
Dimensions(Ts... dims)
Constructor to initialize the tensor shape.
Definition: Dimensions.h:53
arm_compute
Copyright (c) 2017-2023 Arm Limited.
Definition: introduction.dox:24
arm_compute::Dimensions::end
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:246
arm_compute::Dimensions::set_num_dimensions
void set_num_dimensions(size_t num_dimensions)
Set number of dimensions.
Definition: Dimensions.h:148
arm_compute::Dimensions::increment
void increment(size_t dim, T step=1)
Increments the given dimension by a step size, avoiding overflows.
Definition: Dimensions.h:107
arm_compute::Dimensions::end
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:238
arm_compute::cpu::step
constexpr int step
Definition: fp32.cpp:35
arm_compute::Dimensions
Dimensions with dimensionality.
Definition: Dimensions.h:42
arm_compute::Dimensions::y
T y() const
Alias to access the size of the second dimension.
Definition: Dimensions.h:91
arm_compute::Dimensions::num_dimensions
unsigned int num_dimensions() const
Returns the effective dimensionality of the tensor.
Definition: Dimensions.h:142
arm_compute::Dimensions::num_max_dimensions
static constexpr size_t num_max_dimensions
Number of dimensions the tensor has.
Definition: Dimensions.h:46
arm_compute::operator!=
bool operator!=(const Dimensions< T > &lhs, const Dimensions< T > &rhs)
Check that given dimensions are not equal.
Definition: Dimensions.h:287
arm_compute::Dimensions::operator=
Dimensions & operator=(const Dimensions &)=default
Allow instances of this class to be copied.