ArmNN
 24.08
Slice.cpp
Go to the documentation of this file.
1 //
2 // Copyright © 2019,2024 Arm Ltd. All rights reserved.
3 // SPDX-License-Identifier: MIT
4 //
5 
6 #include "Slice.hpp"
7 
10 
11 namespace armnn
12 {
13 
14 void Slice(const TensorInfo& inputInfo,
15  const SliceDescriptor& descriptor,
16  const void* inputData,
17  void* outputData,
18  unsigned int dataTypeSize)
19 {
20  const TensorShape& inputShape = inputInfo.GetShape();
21  const unsigned int numDims = inputShape.GetNumDimensions();
22 
23  constexpr unsigned int maxNumDims = 5;
24  if (descriptor.m_Begin.size() != numDims)
25  {
26  std::stringstream msg;
27  msg << "Slice: Number of dimensions (" << numDims <<
28  ") does not match the Begin vector in the descriptor (" << descriptor.m_Begin.size() << ")";
29  throw InvalidArgumentException(msg.str());
30  }
31  if (descriptor.m_Size.size() != numDims)
32  {
33  std::stringstream msg;
34  msg << "Slice: Number of dimensions (" << numDims <<
35  ") does not match the Size vector in the descriptor (" << descriptor.m_Size.size() << ")";
36  throw InvalidArgumentException(msg.str());
37  }
38  if (numDims > maxNumDims)
39  {
40  std::stringstream msg;
41  msg << "Slice: Number of dimensions (" << numDims <<
42  ") is greater than the maximum supported (" << maxNumDims << ")";
43  throw InvalidArgumentException(msg.str());
44  }
45 
46  std::vector<unsigned int> paddedInput(5);
47  std::vector<unsigned int> paddedBegin(5);
48  std::vector<unsigned int> paddedSize (5);
49 
50  const unsigned int numPaddingDims = maxNumDims - numDims;
51  for (unsigned int i = 0u; i < maxNumDims; ++i)
52  {
53  if (i < numPaddingDims)
54  {
55  paddedInput[i] = 1u;
56  paddedBegin[i] = 0u;
57  paddedSize[i] = 1u;
58  }
59  else
60  {
61  const unsigned int j = i - numPaddingDims;
62  paddedInput[i] = inputShape[j];
63  paddedBegin[i] = descriptor.m_Begin[j];
64  paddedSize[i] = descriptor.m_Size[j];
65  }
66  }
67 
68  unsigned int dim0 = paddedInput[0];
69  unsigned int dim1 = paddedInput[1];
70  unsigned int dim2 = paddedInput[2];
71  unsigned int dim3 = paddedInput[3];
72  unsigned int dim4 = paddedInput[4];
73 
74  unsigned int begin0 = paddedBegin[0];
75  unsigned int begin1 = paddedBegin[1];
76  unsigned int begin2 = paddedBegin[2];
77  unsigned int begin3 = paddedBegin[3];
78  unsigned int begin4 = paddedBegin[4];
79 
80  unsigned int size0 = paddedSize[0];
81  unsigned int size1 = paddedSize[1];
82  unsigned int size2 = paddedSize[2];
83  unsigned int size3 = paddedSize[3];
84  unsigned int size4 = paddedSize[4];
85 
86  if (begin0 + size0 > dim0)
87  {
88  std::stringstream msg;
89  msg << "Slice: begin0 + size0 (" << (begin0 + size0) <<
90  ") exceeds dim0 (" << dim0 << ")";
91  throw InvalidArgumentException(msg.str());
92  }
93  if (begin1 + size1 > dim1)
94  {
95  std::stringstream msg;
96  msg << "Slice: begin1 + size1 (" << (begin1 + size1) <<
97  ") exceeds dim2 (" << dim1 << ")";
98  throw InvalidArgumentException(msg.str());
99  }
100  if (begin2 + size2 > dim2)
101  {
102  std::stringstream msg;
103  msg << "Slice: begin2 + size2 (" << (begin2 + size2) <<
104  ") exceeds dim2 (" << dim2 << ")";
105  throw InvalidArgumentException(msg.str());
106  }
107  if (begin3 + size3 > dim3)
108  {
109  std::stringstream msg;
110  msg << "Slice: begin3 + size3 (" << (begin3 + size3) <<
111  ") exceeds dim3 (" << dim3 << ")";
112  throw InvalidArgumentException(msg.str());
113  }
114 
115  if (inputData == nullptr)
116  {
117  throw armnn::NullPointerException("Slice: Null inputData pointer");
118  }
119  if (outputData == nullptr)
120  {
121  throw armnn::NullPointerException("Slice: Null outputData pointer");
122  }
123 
124  const unsigned char* input = reinterpret_cast<const unsigned char*>(inputData);
125  unsigned char* output = reinterpret_cast<unsigned char*>(outputData);
126 
127  for (unsigned int idx0 = begin0; idx0 < begin0 + size0; ++idx0)
128  {
129  for (unsigned int idx1 = begin1; idx1 < begin1 + size1; ++idx1)
130  {
131  for (unsigned int idx2 = begin2; idx2 < begin2 + size2; ++idx2)
132  {
133  for (unsigned int idx3 = begin3; idx3 < begin3 + size3; ++idx3)
134  {
135  for (unsigned int idx4 = begin4; idx4 < begin4 + size4; ++idx4)
136  {
137  const unsigned int inputOffset =
138  ((((idx0 * dim1 + idx1) * dim2 + idx2) * dim3 + idx3) * dim4 + idx4) * dataTypeSize;
139 
140  ::memcpy(output, input + inputOffset, dataTypeSize);
141  output += dataTypeSize;
142  }
143  }
144  }
145  }
146  }
147 }
148 
149 } // namespace armnn
armnn::SliceDescriptor::m_Begin
std::vector< unsigned int > m_Begin
Beginning indices of the slice in each dimension.
Definition: Descriptors.hpp:1244
armnn::TensorInfo
Definition: Tensor.hpp:152
IgnoreUnused.hpp
Assert.hpp
armnn::TensorShape
Definition: Tensor.hpp:20
armnn::TensorShape::GetNumDimensions
unsigned int GetNumDimensions() const
Function that returns the tensor rank.
Definition: Tensor.cpp:174
armnn::Slice
void Slice(const TensorInfo &inputInfo, const SliceDescriptor &descriptor, const void *inputData, void *outputData, unsigned int dataTypeSize)
Definition: Slice.cpp:14
armnn::SliceDescriptor
A SliceDescriptor for the SliceLayer.
Definition: Descriptors.hpp:1228
armnn::InvalidArgumentException
Definition: Exceptions.hpp:80
armnn::TensorInfo::GetShape
const TensorShape & GetShape() const
Definition: Tensor.hpp:193
armnn
Copyright (c) 2021 ARM Limited and Contributors.
Definition: 01_00_quick_start.dox:6
armnn::SliceDescriptor::m_Size
std::vector< unsigned int > m_Size
Size of the slice in each dimension.
Definition: Descriptors.hpp:1247
armnn::NullPointerException
Definition: Exceptions.hpp:146
Slice.hpp