blob: 4b491e3ceca2c88513397944ecfb51f26a033e52 [file] [log] [blame]
Laurent Carlier749294b2020-06-01 09:03:17 +01001//
Mike Kelly7cbe7812023-07-25 17:37:33 +01002// Copyright © 2017-2023 Arm Ltd and Contributors. All rights reserved.
David Beckecb56cd2018-09-05 12:52:57 +01003// SPDX-License-Identifier: MIT
telsoa014fcda012018-03-09 14:13:49 +00004//
5#pragma once
6
Francis Murtaghd301c0a2022-08-02 19:42:29 +01007#include <BFloat16.hpp>
Aron Virginas-Tarc9cc8042018-11-01 16:15:57 +00008#include <Half.hpp>
Matthew Bentham14e46692018-09-20 15:35:30 +01009
Aron Virginas-Tarc9cc8042018-11-01 16:15:57 +000010#include <aclCommon/ArmComputeTensorUtils.hpp>
11#include <cl/OpenClTimer.hpp>
Colm Donelan0c479742021-12-10 12:43:54 +000012#include <armnn/backends/TensorHandle.hpp>
telsoa01c577f2c2018-08-31 09:22:23 +010013
Derek Lambertid466a542020-01-22 15:37:29 +000014#include <armnn/Utils.hpp>
15
Matthew Bentham9b3e7382020-02-05 21:39:55 +000016#include <arm_compute/runtime/CL/CLTensor.h>
17#include <arm_compute/runtime/IFunction.h>
Aron Virginas-Tara8e06ed2018-10-19 16:46:15 +010018
19#include <sstream>
20
telsoa01c577f2c2018-08-31 09:22:23 +010021#define ARMNN_SCOPED_PROFILING_EVENT_CL(name) \
22 ARMNN_SCOPED_PROFILING_EVENT_WITH_INSTRUMENTS(armnn::Compute::GpuAcc, \
Keith Davis5a64f222021-08-04 10:35:20 +010023 armnn::EmptyOptional(), \
24 name, \
25 armnn::OpenClTimer(), \
26 armnn::WallClockTimer())
27
28#define ARMNN_SCOPED_PROFILING_EVENT_CL_GUID(name, guid) \
29 ARMNN_SCOPED_PROFILING_EVENT_WITH_INSTRUMENTS(armnn::Compute::GpuAcc, \
30 guid, \
Mike Kelly7cbe7812023-07-25 17:37:33 +010031 GetName() + "_" + name, \
32 armnn::OpenClTimer(), \
33 armnn::WallClockTimer())
34
35/// Creates a profiling event that uses GetGuid() and GetName() from the calling class
36#define ARMNN_SCOPED_PROFILING_EVENT_CL_NAME_GUID(label) \
37 ARMNN_SCOPED_PROFILING_EVENT_WITH_INSTRUMENTS(armnn::Compute::GpuAcc, \
38 this->GetGuid(), \
39 this->GetName() + "_" + label, \
telsoa01c577f2c2018-08-31 09:22:23 +010040 armnn::OpenClTimer(), \
41 armnn::WallClockTimer())
telsoa014fcda012018-03-09 14:13:49 +000042
43namespace armnn
44{
45
Keith Davis5a64f222021-08-04 10:35:20 +010046inline std::string GetConvolutionMethodString(arm_compute::ConvolutionMethod& convolutionMethod)
47{
48 switch (convolutionMethod)
49 {
50 case arm_compute::ConvolutionMethod::FFT:
51 return "FFT";
52 case arm_compute::ConvolutionMethod::DIRECT:
53 return "Direct";
54 case arm_compute::ConvolutionMethod::GEMM:
55 return "GEMM";
56 case arm_compute::ConvolutionMethod::WINOGRAD:
57 return "Winograd";
58 default:
59 return "Unknown";
60 }
61}
62
telsoa014fcda012018-03-09 14:13:49 +000063template <typename T>
Matthew Benthamca6616c2018-09-21 15:16:53 +010064void CopyArmComputeClTensorData(arm_compute::CLTensor& dstTensor, const T* srcData)
telsoa014fcda012018-03-09 14:13:49 +000065{
66 {
telsoa01c577f2c2018-08-31 09:22:23 +010067 ARMNN_SCOPED_PROFILING_EVENT_CL("MapClTensorForWriting");
telsoa014fcda012018-03-09 14:13:49 +000068 dstTensor.map(true);
69 }
70
71 {
telsoa01c577f2c2018-08-31 09:22:23 +010072 ARMNN_SCOPED_PROFILING_EVENT_CL("CopyToClTensor");
telsoa014fcda012018-03-09 14:13:49 +000073 armcomputetensorutils::CopyArmComputeITensorData<T>(srcData, dstTensor);
74 }
75
76 dstTensor.unmap();
77}
78
keidav01d74dc912018-12-10 18:16:07 +000079inline auto SetClStridedSliceData(const std::vector<int>& m_begin,
80 const std::vector<int>& m_end,
81 const std::vector<int>& m_stride)
82{
83 arm_compute::Coordinates starts;
84 arm_compute::Coordinates ends;
85 arm_compute::Coordinates strides;
86
87 unsigned int num_dims = static_cast<unsigned int>(m_begin.size());
88
89 for (unsigned int i = 0; i < num_dims; i++) {
90 unsigned int revertedIndex = num_dims - i - 1;
91
92 starts.set(i, static_cast<int>(m_begin[revertedIndex]));
93 ends.set(i, static_cast<int>(m_end[revertedIndex]));
94 strides.set(i, static_cast<int>(m_stride[revertedIndex]));
95 }
96
97 return std::make_tuple(starts, ends, strides);
98}
99
Aron Virginas-Tar94c4fef2019-11-25 15:37:08 +0000100inline auto SetClSliceData(const std::vector<unsigned int>& m_begin,
101 const std::vector<unsigned int>& m_size)
102{
103 // This function must translate the size vector given to an end vector
104 // expected by the ACL NESlice workload
105 arm_compute::Coordinates starts;
106 arm_compute::Coordinates ends;
107
108 unsigned int num_dims = static_cast<unsigned int>(m_begin.size());
109
110 // For strided slices, we have the relationship size = (end - begin) / stride
111 // For slice, we assume stride to be a vector of all ones, yielding the formula
112 // size = (end - begin) therefore we know end = size + begin
113 for (unsigned int i = 0; i < num_dims; i++)
114 {
115 unsigned int revertedIndex = num_dims - i - 1;
116
117 starts.set(i, static_cast<int>(m_begin[revertedIndex]));
118 ends.set(i, static_cast<int>(m_begin[revertedIndex] + m_size[revertedIndex]));
119 }
120
121 return std::make_tuple(starts, ends);
122}
123
Matthew Bentham785df502018-09-21 10:29:58 +0100124inline void InitializeArmComputeClTensorData(arm_compute::CLTensor& clTensor,
James Conroy1f58f032021-04-27 17:13:27 +0100125 const ConstTensorHandle* handle)
telsoa01c577f2c2018-08-31 09:22:23 +0100126{
Narumol Prangnawaratac2770a2020-04-01 16:51:23 +0100127 ARMNN_ASSERT(handle);
Matthew Benthamca6616c2018-09-21 15:16:53 +0100128
129 armcomputetensorutils::InitialiseArmComputeTensorEmpty(clTensor);
telsoa01c577f2c2018-08-31 09:22:23 +0100130 switch(handle->GetTensorInfo().GetDataType())
131 {
132 case DataType::Float16:
Matthew Benthamca6616c2018-09-21 15:16:53 +0100133 CopyArmComputeClTensorData(clTensor, handle->GetConstTensor<armnn::Half>());
telsoa01c577f2c2018-08-31 09:22:23 +0100134 break;
135 case DataType::Float32:
Matthew Benthamca6616c2018-09-21 15:16:53 +0100136 CopyArmComputeClTensorData(clTensor, handle->GetConstTensor<float>());
telsoa01c577f2c2018-08-31 09:22:23 +0100137 break;
Derek Lambertif90c56d2020-01-10 17:14:08 +0000138 case DataType::QAsymmU8:
Matthew Benthamca6616c2018-09-21 15:16:53 +0100139 CopyArmComputeClTensorData(clTensor, handle->GetConstTensor<uint8_t>());
Matthew Bentham785df502018-09-21 10:29:58 +0100140 break;
Narumol Prangnawarat33d2c782020-11-13 18:00:23 +0000141 case DataType::QAsymmS8:
Derek Lambertid466a542020-01-22 15:37:29 +0000142 case DataType::QSymmS8:
Keith Davis899f64f2019-11-26 16:01:18 +0000143 CopyArmComputeClTensorData(clTensor, handle->GetConstTensor<int8_t>());
144 break;
Ryan OShea2323af42020-05-13 16:36:19 +0100145 case DataType::QSymmS16:
146 CopyArmComputeClTensorData(clTensor, handle->GetConstTensor<int16_t>());
147 break;
Matthew Bentham785df502018-09-21 10:29:58 +0100148 case DataType::Signed32:
Matthew Benthamca6616c2018-09-21 15:16:53 +0100149 CopyArmComputeClTensorData(clTensor, handle->GetConstTensor<int32_t>());
Matthew Bentham785df502018-09-21 10:29:58 +0100150 break;
Francis Murtaghd301c0a2022-08-02 19:42:29 +0100151 case DataType::BFloat16:
152 CopyArmComputeClTensorData(clTensor, handle->GetConstTensor<armnn::BFloat16>());
153 break;
telsoa01c577f2c2018-08-31 09:22:23 +0100154 default:
Francis Murtaghd301c0a2022-08-02 19:42:29 +0100155 // Throw exception; assertion not called in release build.
156 throw Exception("Unexpected tensor type during InitializeArmComputeClTensorData().");
telsoa01c577f2c2018-08-31 09:22:23 +0100157 }
158};
159
Aron Virginas-Tara8e06ed2018-10-19 16:46:15 +0100160inline RuntimeException WrapClError(const cl::Error& clError, const CheckLocation& location)
161{
162 std::stringstream message;
163 message << "CL error: " << clError.what() << ". Error code: " << clError.err();
164
165 return RuntimeException(message.str(), location);
166}
167
168inline void RunClFunction(arm_compute::IFunction& function, const CheckLocation& location)
169{
170 try
171 {
172 function.run();
173 }
174 catch (cl::Error& error)
175 {
176 throw WrapClError(error, location);
177 }
178}
179
David Monahanc11ba462020-12-03 11:09:46 +0000180template <typename DataType, typename PayloadType>
181DataType* GetOutputTensorData(unsigned int idx, const PayloadType& data)
182{
183 ITensorHandle* tensorHandle = data.m_Outputs[idx];
184 return reinterpret_cast<DataType*>(tensorHandle->Map());
185}
186
telsoa014fcda012018-03-09 14:13:49 +0000187} //namespace armnn