blob: 10954b07b51c40b7ffdd82399399ef4c7d942a22 [file] [log] [blame]
David Monahanbd738082023-12-08 12:50:02 +00001//
2// Copyright © 2023-2024 Arm Ltd and Contributors. All rights reserved.
3// SPDX-License-Identifier: MIT
4//
5#pragma once
6
7#include <BFloat16.hpp>
8#include <Half.hpp>
9
10#include <aclCommon/ArmComputeTensorUtils.hpp>
11#include <armnn/backends/TensorHandle.hpp>
12
13#include <armnn/Utils.hpp>
14
15#include <arm_compute/runtime/CL/CLTensor.h>
16#include <arm_compute/runtime/IFunction.h>
17
18#include <sstream>
19
20
21namespace armnn
22{
23
24 inline std::string GetConvolutionMethodString(arm_compute::ConvolutionMethod& convolutionMethod)
25 {
26 switch (convolutionMethod)
27 {
28 case arm_compute::ConvolutionMethod::FFT:
29 return "FFT";
30 case arm_compute::ConvolutionMethod::DIRECT:
31 return "Direct";
32 case arm_compute::ConvolutionMethod::GEMM:
33 return "GEMM";
34 case arm_compute::ConvolutionMethod::WINOGRAD:
35 return "Winograd";
36 default:
37 return "Unknown";
38 }
39 }
40
41 template <typename T>
42 void CopyArmComputeClTensorData(arm_compute::CLTensor& dstTensor, const T* srcData)
43 {
44 {
45 dstTensor.map(true);
46 }
47
48 {
49 armcomputetensorutils::CopyArmComputeITensorData<T>(srcData, dstTensor);
50 }
51
52 dstTensor.unmap();
53 }
54
55 inline auto SetClStridedSliceData(const std::vector<int>& m_begin,
56 const std::vector<int>& m_end,
57 const std::vector<int>& m_stride)
58 {
59 arm_compute::Coordinates starts;
60 arm_compute::Coordinates ends;
61 arm_compute::Coordinates strides;
62
63 unsigned int num_dims = static_cast<unsigned int>(m_begin.size());
64
65 for (unsigned int i = 0; i < num_dims; i++) {
66 unsigned int revertedIndex = num_dims - i - 1;
67
68 starts.set(i, static_cast<int>(m_begin[revertedIndex]));
69 ends.set(i, static_cast<int>(m_end[revertedIndex]));
70 strides.set(i, static_cast<int>(m_stride[revertedIndex]));
71 }
72
73 return std::make_tuple(starts, ends, strides);
74 }
75
76 inline auto SetClSliceData(const std::vector<unsigned int>& m_begin,
77 const std::vector<unsigned int>& m_size)
78 {
79 // This function must translate the size vector given to an end vector
80 // expected by the ACL NESlice workload
81 arm_compute::Coordinates starts;
82 arm_compute::Coordinates ends;
83
84 unsigned int num_dims = static_cast<unsigned int>(m_begin.size());
85
86 // For strided slices, we have the relationship size = (end - begin) / stride
87 // For slice, we assume stride to be a vector of all ones, yielding the formula
88 // size = (end - begin) therefore we know end = size + begin
89 for (unsigned int i = 0; i < num_dims; i++)
90 {
91 unsigned int revertedIndex = num_dims - i - 1;
92
93 starts.set(i, static_cast<int>(m_begin[revertedIndex]));
94 ends.set(i, static_cast<int>(m_begin[revertedIndex] + m_size[revertedIndex]));
95 }
96
97 return std::make_tuple(starts, ends);
98 }
99
100 inline void InitializeArmComputeClTensorData(arm_compute::CLTensor& clTensor,
101 const ConstTensorHandle* handle)
102 {
103 ARMNN_ASSERT(handle);
104
105 armcomputetensorutils::InitialiseArmComputeTensorEmpty(clTensor);
106 switch(handle->GetTensorInfo().GetDataType())
107 {
108 case DataType::Float16:
109 CopyArmComputeClTensorData(clTensor, handle->GetConstTensor<armnn::Half>());
110 break;
111 case DataType::Float32:
112 CopyArmComputeClTensorData(clTensor, handle->GetConstTensor<float>());
113 break;
114 case DataType::QAsymmU8:
115 CopyArmComputeClTensorData(clTensor, handle->GetConstTensor<uint8_t>());
116 break;
117 case DataType::QAsymmS8:
118 case DataType::QSymmS8:
119 CopyArmComputeClTensorData(clTensor, handle->GetConstTensor<int8_t>());
120 break;
121 case DataType::QSymmS16:
122 CopyArmComputeClTensorData(clTensor, handle->GetConstTensor<int16_t>());
123 break;
124 case DataType::Signed32:
125 CopyArmComputeClTensorData(clTensor, handle->GetConstTensor<int32_t>());
126 break;
127 case DataType::BFloat16:
128 CopyArmComputeClTensorData(clTensor, handle->GetConstTensor<armnn::BFloat16>());
129 break;
130 default:
131 // Throw exception; assertion not called in release build.
132 throw Exception("Unexpected tensor type during InitializeArmComputeClTensorData().");
133 }
134 };
135
136 inline RuntimeException WrapClError(const cl::Error& clError, const CheckLocation& location)
137 {
138 std::stringstream message;
139 message << "CL error: " << clError.what() << ". Error code: " << clError.err();
140
141 return RuntimeException(message.str(), location);
142 }
143
144 inline void RunClFunction(arm_compute::IFunction& function, const CheckLocation& location)
145 {
146 try
147 {
148 function.run();
149 }
150 catch (cl::Error& error)
151 {
152 throw WrapClError(error, location);
153 }
154 }
155
156 template <typename DataType, typename PayloadType>
157 DataType* GetOutputTensorData(unsigned int idx, const PayloadType& data)
158 {
159 ITensorHandle* tensorHandle = data.m_Outputs[idx];
160 return reinterpret_cast<DataType*>(tensorHandle->Map());
161 }
162
163} //namespace armnn