ArmNN
 20.02
Descriptors.cpp
Go to the documentation of this file.
1 //
2 // Copyright © 2017 Arm Ltd. All rights reserved.
3 // SPDX-License-Identifier: MIT
4 //
5 #include "armnn/Descriptors.hpp"
6 #include "armnn/Logging.hpp"
7 
8 #include <algorithm>
9 #include <array>
10 #include <vector>
11 
12 #include <boost/format.hpp>
13 #include <boost/numeric/conversion/cast.hpp>
14 
15 namespace armnn
16 {
17 
18 PermutationVector::PermutationVector(const ValueType *dimMappings, const SizeType numDimMappings)
19 {
20  // Validation
21 
22  if (numDimMappings > MaxNumOfTensorDimensions)
23  {
24  boost::format fmt("The number of mappings (%1%) cannot be greater "
25  "than the maximum number of dimensions supported (%2%)");
26  throw InvalidArgumentException(boost::str(fmt % numDimMappings % MaxNumOfTensorDimensions));
27  }
28 
29  if ((dimMappings == nullptr) && (numDimMappings != 0))
30  {
31  throw InvalidArgumentException("Dimension mappings must not be NULL if the number of mappings is positive");
32  }
33 
34  for (SizeType i = 0; i < numDimMappings; ++i)
35  {
36  const ValueType dstIndex = dimMappings[i];
37  if (dstIndex >= numDimMappings)
38  {
39  boost::format fmt("Dimension mapping at index %1% is invalid: %2% is outside of the valid range [0,%3%]");
40  throw InvalidArgumentException(boost::str(fmt % i % dstIndex % (numDimMappings - 1)));
41  }
42  }
43 
44  // Validation: Detect duplicates
45  {
46  std::array<bool, MaxNumOfTensorDimensions> observedDims;
47  observedDims.fill(false);
48 
49  for (SizeType i = 0; i < numDimMappings; ++i)
50  {
51  const ValueType dstIndex = dimMappings[i];
52  if (observedDims[dstIndex])
53  {
54  throw InvalidArgumentException("Invalid dimension mappings: Two or more source dimensions are mapped "
55  "to the same output dimension");
56  }
57  observedDims[dstIndex] = true;
58  }
59  }
60 
61  // Initialize
62  for (SizeType i = 0; i < numDimMappings; ++i)
63  {
64  m_DimMappings[i] = dimMappings[i];
65  }
66  m_NumDimMappings = numDimMappings;
67 }
68 
69 PermutationVector::PermutationVector(std::initializer_list<ValueType> dimMappings)
70  : PermutationVector(dimMappings.begin(), boost::numeric_cast<SizeType>(dimMappings.size()))
71 {
72 }
73 
75 : m_ConcatAxis(1)
76 , m_NumViews(0)
77 , m_NumDimensions(0)
78 , m_ViewOrigins(nullptr)
79 {}
80 
81 OriginsDescriptor::OriginsDescriptor(uint32_t numViews, uint32_t numDimensions /*= 4*/)
82 : m_ConcatAxis(1)
83 , m_NumViews(numViews)
84 , m_NumDimensions(numDimensions)
85 , m_ViewOrigins(numViews && numDimensions > 0 ? new uint32_t *[numViews]() : nullptr)
86 {
87  for (uint32_t i = 0; m_NumDimensions > 0 && i < m_NumViews; ++i)
88  {
89  m_ViewOrigins[i] = new uint32_t[m_NumDimensions]();
90  }
91 }
92 
94 : m_ConcatAxis(other.m_ConcatAxis)
95 , m_NumViews(other.m_NumViews)
96 , m_NumDimensions(other.m_NumDimensions)
97 , m_ViewOrigins(other.m_NumViews && other.m_NumDimensions > 0 ? new uint32_t *[other.m_NumViews]() : nullptr)
98 {
99  for (uint32_t i = 0; m_NumDimensions > 0 && i < m_NumViews; ++i)
100  {
101  m_ViewOrigins[i] = new uint32_t[m_NumDimensions]();
102  memcpy(m_ViewOrigins[i], other.m_ViewOrigins[i], m_NumDimensions * sizeof(uint32_t));
103  }
104 }
105 
108 {
109  swap(*this, other);
110 }
111 
113 {
114  for (uint32_t i = 0; m_NumDimensions > 0 && i < m_NumViews; ++i)
115  {
116  delete[] m_ViewOrigins[i];
117  }
118  delete[] m_ViewOrigins;
119 }
120 
122 {
123  swap(*this, rhs);
124  return *this;
125 }
126 
128 {
129  if (GetNumViews() != rhs.GetNumViews() ||
130  GetNumDimensions() != rhs.GetNumDimensions() ||
131  GetConcatAxis() != rhs.GetConcatAxis())
132  {
133  return false;
134  }
135 
136  for (unsigned int i = 0u; i < GetNumViews(); ++i)
137  {
138  for (unsigned int j = 0u; j < GetNumDimensions(); ++j)
139  {
140  if (GetViewOrigin(i)[j] != rhs.GetViewOrigin(i)[j])
141  {
142  return false;
143  }
144  }
145  }
146 
147  return true;
148 }
149 
150 void OriginsDescriptor::SetConcatAxis(unsigned int concatAxis)
151 {
152  m_ConcatAxis = concatAxis;
153 }
155 {
156  return m_ConcatAxis;
157 }
158 
159 Status OriginsDescriptor::SetViewOriginCoord(uint32_t view, uint32_t coord, uint32_t value)
160 {
161  if (view >= m_NumViews)
162  {
163  ARMNN_LOG(error) << "OriginsDescriptor::SetViewOriginCoord: view argument:" << view <<
164  " is out of range";
165  return Status::Failure;
166  }
167  if (coord >= m_NumDimensions)
168  {
169  ARMNN_LOG(error) << "OriginsDescriptor::SetViewOriginCoord: coord argument:" << coord <<
170  " is out of range";
171  return Status::Failure;
172  }
173 
174  m_ViewOrigins[view][coord] = value;
175  return Status::Success;
176 }
177 
178 
180 {
181  return m_NumViews;
182 }
183 
185 {
186  return m_NumDimensions;
187 }
188 
189 const uint32_t* OriginsDescriptor::GetViewOrigin(uint32_t idx) const
190 {
191  return m_ViewOrigins ? m_ViewOrigins[idx] : nullptr;
192 }
193 
194 
195 // Reorders the viewOrigins in accordance with the indices presented in newOrdering array.
196 void OriginsDescriptor::ReorderOrigins(unsigned int* newOrdering, unsigned int numNewOrdering)
197 {
198  BOOST_ASSERT_MSG(m_NumViews == numNewOrdering, "number of views must match number of "
199  "elements in the new ordering array");
200  std::vector<uint32_t*> viewOrigins(&m_ViewOrigins[0], &m_ViewOrigins[m_NumViews]);
201 
202  for (unsigned int i = 0; i < numNewOrdering; ++i)
203  {
204  m_ViewOrigins[i] = viewOrigins[newOrdering[i]];
205  }
206 }
207 
209 : m_Origins()
210 , m_ViewSizes(nullptr)
211 {}
212 
213 ViewsDescriptor::ViewsDescriptor(uint32_t numViews, uint32_t numDimensions /*= 4*/)
214  : m_Origins(numViews, numDimensions)
215  , m_ViewSizes(numViews > 0 && numDimensions > 0 ?
216  new uint32_t *[numViews]() : nullptr)
217 {
218  if (m_ViewSizes)
219  {
220  for (uint32_t i = 0; GetNumDimensions() > 0 && i < GetNumViews(); ++i)
221  {
222  m_ViewSizes[i] = new uint32_t[GetNumDimensions()]();
223  }
224  }
225 }
226 
228  : m_Origins(other.m_Origins)
229  , m_ViewSizes(other.GetNumViews() > 0 && other.GetNumDimensions() > 0 ?
230  new uint32_t *[other.GetNumViews()]() : nullptr)
231 {
232  if (m_ViewSizes)
233  {
234  for (uint32_t i = 0; GetNumDimensions() > 0 && i < GetNumViews(); ++i)
235  {
236  m_ViewSizes[i] = new uint32_t[GetNumDimensions()]();
237  memcpy(m_ViewSizes[i], other.m_ViewSizes[i], GetNumDimensions() * sizeof(uint32_t));
238  }
239  }
240 }
241 
243  : ViewsDescriptor()
244 {
245  swap(*this, other);
246 }
247 
249 {
250  if (m_ViewSizes)
251  {
252  for (uint32_t i = 0; GetNumDimensions() > 0 && i < GetNumViews(); ++i)
253  {
254  delete[] m_ViewSizes[i];
255  }
256  delete[] m_ViewSizes;
257  }
258 }
259 
261 {
262  swap(*this, rhs);
263  return *this;
264 }
265 
267 {
268  if (GetNumViews() != rhs.GetNumViews() || GetNumDimensions() != rhs.GetNumDimensions())
269  {
270  return false;
271  }
272 
273  for (unsigned int i = 0u; i < GetNumViews(); ++i)
274  {
275  for (unsigned int j = 0u; j < GetNumDimensions(); ++j)
276  {
277  if (GetViewOrigin(i)[j] != rhs.GetViewOrigin(i)[j] || GetViewSizes(i)[j] != rhs.GetViewSizes(i)[j])
278  {
279  return false;
280  }
281  }
282  }
283 
284  return true;
285 }
286 
288 {
289  return m_Origins.GetNumViews();
290 }
291 
293 {
294  return m_Origins.GetNumDimensions();
295 }
296 
297 const uint32_t* ViewsDescriptor::GetViewOrigin(uint32_t idx) const
298 {
299  return m_Origins.GetViewOrigin(idx);
300 }
301 
302 Status ViewsDescriptor::SetViewOriginCoord(uint32_t view, uint32_t coord, uint32_t value)
303 {
304  return m_Origins.SetViewOriginCoord(view, coord, value);
305 }
306 
307 Status ViewsDescriptor::SetViewSize(uint32_t view, uint32_t coord, uint32_t value)
308 {
309  if (!m_ViewSizes)
310  {
311  ARMNN_LOG(error) << "ViewsDescriptor::SetViewSize: invalid view sizes";
312  return Status::Failure;
313  }
314 
315  if (view >= GetNumViews())
316  {
317  ARMNN_LOG(error) << "ViewsDescriptor::SetViewSize: view argument:" << view <<
318  " is out of range";
319  return Status::Failure;
320  }
321  if (coord >= GetNumDimensions())
322  {
323  ARMNN_LOG(error) << "ViewsDescriptor::SetViewSize: coord argument:" << coord <<
324  " is out of range";
325  return Status::Failure;
326  }
327 
328  m_ViewSizes[view][coord] = value;
329  return Status::Success;
330 }
331 
332 const uint32_t* ViewsDescriptor::GetViewSizes(uint32_t idx) const
333 {
334  return m_ViewSizes ? m_ViewSizes[idx] : nullptr;
335 }
336 
338 {
339  return m_Origins;
340 }
341 
343 {
344  using std::swap;
345  swap(first.m_NumViews, second.m_NumViews);
346  swap(first.m_NumDimensions, second.m_NumDimensions);
347  swap(first.m_ViewOrigins, second.m_ViewOrigins);
348  swap(first.m_ConcatAxis, second.m_ConcatAxis);
349 }
350 
351 void swap(ViewsDescriptor& first, ViewsDescriptor& second)
352 {
353  using std::swap;
354  swap(first.m_Origins, second.m_Origins);
355  swap(first.m_ViewSizes, second.m_ViewSizes);
356 }
357 
359  unsigned int axis) const
360 {
361  int start = m_Begin[axis];
362 
363  if (m_BeginMask & (1 << axis))
364  {
365  if (m_Stride[axis] > 0)
366  {
367  start = std::numeric_limits<int>::min();
368  }
369  else
370  {
371  start = std::numeric_limits<int>::max();
372  }
373  }
374 
375  const int axisSize = boost::numeric_cast<int>(inputShape[axis]);
376  if (start < 0)
377  {
378  start += (axisSize);
379  }
380 
381  return std::max(0, std::min(start, axisSize - 1));
382 
383 }
384 
386  unsigned int axis,
387  int startForAxis) const
388 {
389 
390  if (m_ShrinkAxisMask & (1 << axis))
391  {
392  return startForAxis + 1;
393  }
394 
395  int stop = m_End[axis];
396 
397  if (m_EndMask & (1 << axis))
398  {
399  if (m_Stride[axis] > 0)
400  {
401  stop = std::numeric_limits<int>::max();
402  }
403  else
404  {
405  stop = std::numeric_limits<int>::min();
406  }
407  }
408 
409  const int axisSize = boost::numeric_cast<int>(inputShape[axis]);
410  if (stop < 0)
411  {
412  stop += axisSize;
413  }
414 
415  return m_Stride[axis] > 0 ? std::max(0, std::min(stop, axisSize)) :
416  std::max(-1, std::min(stop, axisSize - 1));
417 
418 }
419 
420 }
friend void swap(OriginsDescriptor &first, OriginsDescriptor &second)
Swap the ViewsDescriptor values first and second.
unsigned int ValueType
Definition: Types.hpp:176
A ViewsDescriptor for the SplitterLayer.
OriginsDescriptor & operator=(OriginsDescriptor rhs)
int GetStartForAxis(const TensorShape &inputShape, unsigned int axis) const
void swap(ViewsDescriptor &first, ViewsDescriptor &second)
uint32_t GetNumDimensions() const
Get the number of dimensions.
friend void swap(ViewsDescriptor &first, ViewsDescriptor &second)
Swap the ViewsDescriptor value first and second.
#define ARMNN_LOG(severity)
Definition: Logging.hpp:163
bool operator==(const ViewsDescriptor &rhs) const
uint32_t GetNumViews() const
Get the number of views.
Copyright (c) 2020 ARM Limited.
const uint32_t * GetViewOrigin(uint32_t idx) const
Return the view origin at the int value idx.
void ReorderOrigins(unsigned int *newOrdering, unsigned int numNewOrdering)
Reorders the viewOrigins in accordance with the indices presented in newOrdering array.
Status SetViewSize(uint32_t view, uint32_t coord, uint32_t value)
Set the size of the views.
PermutationVector(const ValueType *dimMappings, SizeType numDimMappings)
Definition: Descriptors.cpp:18
An OriginsDescriptor for the ConcatLayer.
Status
enumeration
Definition: Types.hpp:26
std::enable_if_t< std::is_unsigned< Source >::value &&std::is_unsigned< Dest >::value, Dest > numeric_cast(Source source)
Definition: NumericCast.hpp:33
unsigned int SizeType
Definition: Types.hpp:177
const uint32_t * GetViewOrigin(uint32_t idx) const
Get the view origin at the int value idx.
const uint32_t * GetViewSizes(uint32_t idx) const
Get the view sizes at the int value idx.
ConstIterator begin() const
Definition: Types.hpp:204
void SetConcatAxis(unsigned int concatAxis)
Set the concatenation axis value.
uint32_t GetNumDimensions() const
Get the number of dimensions.
int GetStopForAxis(const TensorShape &inputShape, unsigned int axis, int startForAxis) const
uint32_t GetNumViews() const
Get the number of views.
bool operator==(const OriginsDescriptor &rhs) const
unsigned int GetConcatAxis() const
Get the concatenation axis value.
ViewsDescriptor & operator=(ViewsDescriptor rhs)
const OriginsDescriptor & GetOrigins() const
Get the View Origins.
Status SetViewOriginCoord(uint32_t view, uint32_t coord, uint32_t value)
Set the view origin coordinates.
constexpr unsigned int MaxNumOfTensorDimensions
Definition: Types.hpp:18
Status SetViewOriginCoord(uint32_t view, uint32_t coord, uint32_t value)
Set the view origin coordinates.