xref: /aosp_15_r20/external/armnn/src/backends/reference/workloads/Slice.cpp (revision 89c4ff92f2867872bb9e2354d150bf0c8c502810)
1 //
2 // Copyright © 2019 Arm Ltd. All rights reserved.
3 // SPDX-License-Identifier: MIT
4 //
5 
6 #include "Slice.hpp"
7 
8 #include <armnn/utility/Assert.hpp>
9 #include <armnn/utility/IgnoreUnused.hpp>
10 
11 namespace armnn
12 {
13 
Slice(const TensorInfo & inputInfo,const SliceDescriptor & descriptor,const void * inputData,void * outputData,unsigned int dataTypeSize)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     ARMNN_ASSERT(descriptor.m_Begin.size() == numDims);
24     ARMNN_ASSERT(descriptor.m_Size.size()  == numDims);
25 
26     constexpr unsigned int maxNumDims = 4;
27     ARMNN_ASSERT(numDims <= maxNumDims);
28 
29     std::vector<unsigned int> paddedInput(4);
30     std::vector<unsigned int> paddedBegin(4);
31     std::vector<unsigned int> paddedSize (4);
32 
33     const unsigned int numPaddingDims = maxNumDims - numDims;
34     for (unsigned int i = 0u; i < maxNumDims; ++i)
35     {
36         if (i < numPaddingDims)
37         {
38             paddedInput[i] = 1u;
39             paddedBegin[i] = 0u;
40             paddedSize[i]  = 1u;
41         }
42         else
43         {
44             const unsigned int j = i - numPaddingDims;
45             paddedInput[i] = inputShape[j];
46             paddedBegin[i] = descriptor.m_Begin[j];
47             paddedSize[i]  = descriptor.m_Size[j];
48         }
49     }
50 
51     unsigned int dim0 = paddedInput[0];
52     unsigned int dim1 = paddedInput[1];
53     unsigned int dim2 = paddedInput[2];
54     unsigned int dim3 = paddedInput[3];
55 
56     unsigned int begin0 = paddedBegin[0];
57     unsigned int begin1 = paddedBegin[1];
58     unsigned int begin2 = paddedBegin[2];
59     unsigned int begin3 = paddedBegin[3];
60 
61     unsigned int size0  = paddedSize[0];
62     unsigned int size1  = paddedSize[1];
63     unsigned int size2  = paddedSize[2];
64     unsigned int size3  = paddedSize[3];
65 
66     ARMNN_ASSERT(begin0 + size0 <= dim0);
67     ARMNN_ASSERT(begin1 + size1 <= dim1);
68     ARMNN_ASSERT(begin2 + size2 <= dim2);
69     ARMNN_ASSERT(begin3 + size3 <= dim3);
70 
71     const unsigned char* input = reinterpret_cast<const unsigned char*>(inputData);
72     unsigned char* output      = reinterpret_cast<unsigned char*>(outputData);
73 
74     IgnoreUnused(dim0);
75     for (unsigned int idx0 = begin0; idx0 < begin0 + size0; ++idx0)
76     {
77         for (unsigned int idx1 = begin1; idx1 < begin1 + size1; ++idx1)
78         {
79             for (unsigned int idx2 = begin2; idx2 < begin2 + size2; ++idx2)
80             {
81                 for (unsigned int idx3 = begin3; idx3 < begin3 + size3; ++idx3)
82                 {
83                     const unsigned int inputOffset =
84                         (((idx0 * dim1 + idx1) * dim2 + idx2) * dim3 + idx3) * dataTypeSize;
85 
86                     ::memcpy(output, input + inputOffset, dataTypeSize);
87                     output += dataTypeSize;
88                 }
89             }
90         }
91     }
92 }
93 
94 } // namespace armnn
95