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