xref: /aosp_15_r20/external/armnn/src/backends/neon/workloads/NeonWorkloadUtils.hpp (revision 89c4ff92f2867872bb9e2354d150bf0c8c502810)
1 //
2 // Copyright © 2017,2022 Arm Ltd and Contributors. All rights reserved.
3 // SPDX-License-Identifier: MIT
4 //
5 #pragma once
6 
7 #include <armnn/backends/Workload.hpp>
8 #include <aclCommon/ArmComputeTensorUtils.hpp>
9 #include <neon/NeonTensorHandle.hpp>
10 #include <neon/NeonTimer.hpp>
11 #include <armnn/backends/TensorHandle.hpp>
12 
13 #include <armnn/Utils.hpp>
14 
15 #include <Half.hpp>
16 
17 #define ARMNN_SCOPED_PROFILING_EVENT_NEON(name) \
18     ARMNN_SCOPED_PROFILING_EVENT_WITH_INSTRUMENTS(armnn::Compute::CpuAcc, \
19                                                   armnn::EmptyOptional(), \
20                                                   name, \
21                                                   armnn::NeonTimer(), \
22                                                   armnn::WallClockTimer())
23 
24 #define ARMNN_SCOPED_PROFILING_EVENT_NEON_GUID(name, guid) \
25     ARMNN_SCOPED_PROFILING_EVENT_WITH_INSTRUMENTS(armnn::Compute::CpuAcc, \
26                                                   guid, \
27                                                   name, \
28                                                   armnn::NeonTimer(), \
29                                                   armnn::WallClockTimer())
30 
31 using namespace armnn::armcomputetensorutils;
32 
33 namespace armnn
34 {
35 
GetConvolutionMethodString(arm_compute::ConvolutionMethod & convolutionMethod)36 inline std::string GetConvolutionMethodString(arm_compute::ConvolutionMethod& convolutionMethod)
37 {
38     switch (convolutionMethod)
39     {
40         case arm_compute::ConvolutionMethod::FFT:
41             return "FFT";
42         case arm_compute::ConvolutionMethod::DIRECT:
43             return "Direct";
44         case arm_compute::ConvolutionMethod::GEMM:
45             return "GEMM";
46         case arm_compute::ConvolutionMethod::WINOGRAD:
47             return "Winograd";
48         default:
49             return "Unknown";
50     }
51 }
52 
53 template <typename T>
CopyArmComputeTensorData(arm_compute::Tensor & dstTensor,const T * srcData)54 void CopyArmComputeTensorData(arm_compute::Tensor& dstTensor, const T* srcData)
55 {
56     InitialiseArmComputeTensorEmpty(dstTensor);
57     CopyArmComputeITensorData(srcData, dstTensor);
58 }
59 
InitializeArmComputeTensorData(arm_compute::Tensor & tensor,TensorInfo tensorInfo,const ITensorHandle * handle)60 inline void InitializeArmComputeTensorData(arm_compute::Tensor& tensor,
61                                            TensorInfo tensorInfo,
62                                            const ITensorHandle* handle)
63 {
64     ARMNN_ASSERT(handle);
65 
66     switch(tensorInfo.GetDataType())
67     {
68         case DataType::Float16:
69             CopyArmComputeTensorData(tensor, reinterpret_cast<const armnn::Half*>(handle->Map()));
70             break;
71         case DataType::Float32:
72             CopyArmComputeTensorData(tensor, reinterpret_cast<const float*>(handle->Map()));
73             break;
74         case DataType::QAsymmU8:
75             CopyArmComputeTensorData(tensor, reinterpret_cast<const uint8_t*>(handle->Map()));
76             break;
77         case DataType::QSymmS8:
78         case DataType::QAsymmS8:
79             CopyArmComputeTensorData(tensor, reinterpret_cast<const int8_t*>(handle->Map()));
80             break;
81         case DataType::Signed32:
82             CopyArmComputeTensorData(tensor, reinterpret_cast<const int32_t*>(handle->Map()));
83             break;
84         case DataType::QSymmS16:
85             CopyArmComputeTensorData(tensor, reinterpret_cast<const int16_t*>(handle->Map()));
86             break;
87         case DataType::BFloat16:
88             CopyArmComputeTensorData(tensor, reinterpret_cast<const armnn::BFloat16*>(handle->Map()));
89             break;
90         default:
91             // Throw exception; assertion not called in release build.
92             throw Exception("Unexpected tensor type during InitializeArmComputeTensorData().");
93     }
94 };
95 
InitializeArmComputeTensorData(arm_compute::Tensor & tensor,const ConstTensorHandle * handle)96 inline void InitializeArmComputeTensorData(arm_compute::Tensor& tensor,
97                                            const ConstTensorHandle* handle)
98 {
99     ARMNN_ASSERT(handle);
100 
101     switch(handle->GetTensorInfo().GetDataType())
102     {
103         case DataType::Float16:
104             CopyArmComputeTensorData(tensor, handle->GetConstTensor<armnn::Half>());
105             break;
106         case DataType::Float32:
107             CopyArmComputeTensorData(tensor, handle->GetConstTensor<float>());
108             break;
109         case DataType::QAsymmU8:
110             CopyArmComputeTensorData(tensor, handle->GetConstTensor<uint8_t>());
111             break;
112         case DataType::QSymmS8:
113         case DataType::QAsymmS8:
114             CopyArmComputeTensorData(tensor, handle->GetConstTensor<int8_t>());
115             break;
116         case DataType::Signed32:
117             CopyArmComputeTensorData(tensor, handle->GetConstTensor<int32_t>());
118             break;
119         case DataType::QSymmS16:
120             CopyArmComputeTensorData(tensor, handle->GetConstTensor<int16_t>());
121             break;
122         case DataType::BFloat16:
123             CopyArmComputeTensorData(tensor, handle->GetConstTensor<armnn::BFloat16>());
124             break;
125         default:
126             // Throw exception; assertion not called in release build.
127             throw Exception("Unexpected tensor type during InitializeArmComputeTensorData().");
128     }
129 };
130 
SetNeonStridedSliceData(const std::vector<int> & m_begin,const std::vector<int> & m_end,const std::vector<int> & m_stride)131 inline auto SetNeonStridedSliceData(const std::vector<int>& m_begin,
132                                     const std::vector<int>& m_end,
133                                     const std::vector<int>& m_stride)
134 {
135     arm_compute::Coordinates starts;
136     arm_compute::Coordinates ends;
137     arm_compute::Coordinates strides;
138 
139     unsigned int num_dims = static_cast<unsigned int>(m_begin.size());
140 
141     for (unsigned int i = 0; i < num_dims; i++)
142     {
143         unsigned int revertedIndex = num_dims - i - 1;
144 
145         starts.set(i, static_cast<int>(m_begin[revertedIndex]));
146         ends.set(i, static_cast<int>(m_end[revertedIndex]));
147         strides.set(i, static_cast<int>(m_stride[revertedIndex]));
148     }
149 
150     return std::make_tuple(starts, ends, strides);
151 }
152 
SetNeonSliceData(const std::vector<unsigned int> & m_begin,const std::vector<unsigned int> & m_size)153 inline auto SetNeonSliceData(const std::vector<unsigned int>& m_begin,
154                              const std::vector<unsigned int>& m_size)
155 {
156     // This function must translate the size vector given to an end vector
157     // expected by the ACL NESlice workload
158     arm_compute::Coordinates starts;
159     arm_compute::Coordinates ends;
160 
161     unsigned int num_dims = static_cast<unsigned int>(m_begin.size());
162 
163     // For strided slices, we have the relationship size = (end - begin) / stride
164     // For slice, we assume stride to be a vector of all ones, yielding the formula
165     // size = (end - begin) therefore we know end = size + begin
166     for (unsigned int i = 0; i < num_dims; i++)
167     {
168         unsigned int revertedIndex = num_dims - i - 1;
169 
170         starts.set(i, static_cast<int>(m_begin[revertedIndex]));
171         ends.set(i, static_cast<int>(m_begin[revertedIndex] + m_size[revertedIndex]));
172     }
173 
174     return std::make_tuple(starts, ends);
175 }
176 
177 template <typename DataType, typename PayloadType>
GetOutputTensorData(unsigned int idx,const PayloadType & data)178 DataType* GetOutputTensorData(unsigned int idx, const PayloadType& data)
179 {
180     ITensorHandle* tensorHandle = data.m_Outputs[idx];
181     return reinterpret_cast<DataType*>(tensorHandle->Map());
182 }
183 
184 } //namespace armnn
185