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