ArmNN
 22.05.01
ClWorkloadUtils.hpp
Go to the documentation of this file.
1 //
2 // Copyright © 2017 Arm Ltd and Contributors. All rights reserved.
3 // SPDX-License-Identifier: MIT
4 //
5 #pragma once
6 
7 #include <Half.hpp>
8 
10 #include <cl/OpenClTimer.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 #define ARMNN_SCOPED_PROFILING_EVENT_CL(name) \
21  ARMNN_SCOPED_PROFILING_EVENT_WITH_INSTRUMENTS(armnn::Compute::GpuAcc, \
22  armnn::EmptyOptional(), \
23  name, \
24  armnn::OpenClTimer(), \
25  armnn::WallClockTimer())
26 
27 #define ARMNN_SCOPED_PROFILING_EVENT_CL_GUID(name, guid) \
28  ARMNN_SCOPED_PROFILING_EVENT_WITH_INSTRUMENTS(armnn::Compute::GpuAcc, \
29  guid, \
30  name, \
31  armnn::OpenClTimer(), \
32  armnn::WallClockTimer())
33 
34 namespace armnn
35 {
36 
37 inline std::string GetConvolutionMethodString(arm_compute::ConvolutionMethod& convolutionMethod)
38 {
39  switch (convolutionMethod)
40  {
41  case arm_compute::ConvolutionMethod::FFT:
42  return "FFT";
43  case arm_compute::ConvolutionMethod::DIRECT:
44  return "Direct";
45  case arm_compute::ConvolutionMethod::GEMM:
46  return "GEMM";
47  case arm_compute::ConvolutionMethod::WINOGRAD:
48  return "Winograd";
49  default:
50  return "Unknown";
51  }
52 }
53 
54 template <typename T>
55 void CopyArmComputeClTensorData(arm_compute::CLTensor& dstTensor, const T* srcData)
56 {
57  {
58  ARMNN_SCOPED_PROFILING_EVENT_CL("MapClTensorForWriting");
59  dstTensor.map(true);
60  }
61 
62  {
63  ARMNN_SCOPED_PROFILING_EVENT_CL("CopyToClTensor");
64  armcomputetensorutils::CopyArmComputeITensorData<T>(srcData, dstTensor);
65  }
66 
67  dstTensor.unmap();
68 }
69 
70 inline auto SetClStridedSliceData(const std::vector<int>& m_begin,
71  const std::vector<int>& m_end,
72  const std::vector<int>& m_stride)
73 {
77 
78  unsigned int num_dims = static_cast<unsigned int>(m_begin.size());
79 
80  for (unsigned int i = 0; i < num_dims; i++) {
81  unsigned int revertedIndex = num_dims - i - 1;
82 
83  starts.set(i, static_cast<int>(m_begin[revertedIndex]));
84  ends.set(i, static_cast<int>(m_end[revertedIndex]));
85  strides.set(i, static_cast<int>(m_stride[revertedIndex]));
86  }
87 
88  return std::make_tuple(starts, ends, strides);
89 }
90 
91 inline auto SetClSliceData(const std::vector<unsigned int>& m_begin,
92  const std::vector<unsigned int>& m_size)
93 {
94  // This function must translate the size vector given to an end vector
95  // expected by the ACL NESlice workload
98 
99  unsigned int num_dims = static_cast<unsigned int>(m_begin.size());
100 
101  // For strided slices, we have the relationship size = (end - begin) / stride
102  // For slice, we assume stride to be a vector of all ones, yielding the formula
103  // size = (end - begin) therefore we know end = size + begin
104  for (unsigned int i = 0; i < num_dims; i++)
105  {
106  unsigned int revertedIndex = num_dims - i - 1;
107 
108  starts.set(i, static_cast<int>(m_begin[revertedIndex]));
109  ends.set(i, static_cast<int>(m_begin[revertedIndex] + m_size[revertedIndex]));
110  }
111 
112  return std::make_tuple(starts, ends);
113 }
114 
115 inline void InitializeArmComputeClTensorData(arm_compute::CLTensor& clTensor,
116  const ConstTensorHandle* handle)
117 {
118  ARMNN_ASSERT(handle);
119 
120  armcomputetensorutils::InitialiseArmComputeTensorEmpty(clTensor);
121  switch(handle->GetTensorInfo().GetDataType())
122  {
123  case DataType::Float16:
125  break;
126  case DataType::Float32:
127  CopyArmComputeClTensorData(clTensor, handle->GetConstTensor<float>());
128  break;
129  case DataType::QAsymmU8:
130  CopyArmComputeClTensorData(clTensor, handle->GetConstTensor<uint8_t>());
131  break;
132  case DataType::QAsymmS8:
133  case DataType::QSymmS8:
134  CopyArmComputeClTensorData(clTensor, handle->GetConstTensor<int8_t>());
135  break;
136  case DataType::QSymmS16:
137  CopyArmComputeClTensorData(clTensor, handle->GetConstTensor<int16_t>());
138  break;
139  case DataType::Signed32:
140  CopyArmComputeClTensorData(clTensor, handle->GetConstTensor<int32_t>());
141  break;
142  default:
143  ARMNN_ASSERT_MSG(false, "Unexpected tensor type.");
144  }
145 };
146 
147 inline RuntimeException WrapClError(const cl::Error& clError, const CheckLocation& location)
148 {
149  std::stringstream message;
150  message << "CL error: " << clError.what() << ". Error code: " << clError.err();
151 
152  return RuntimeException(message.str(), location);
153 }
154 
155 inline void RunClFunction(arm_compute::IFunction& function, const CheckLocation& location)
156 {
157  try
158  {
159  function.run();
160  }
161  catch (cl::Error& error)
162  {
163  throw WrapClError(error, location);
164  }
165 }
166 
167 template <typename DataType, typename PayloadType>
168 DataType* GetOutputTensorData(unsigned int idx, const PayloadType& data)
169 {
170  ITensorHandle* tensorHandle = data.m_Outputs[idx];
171  return reinterpret_cast<DataType*>(tensorHandle->Map());
172 }
173 
174 } //namespace armnn
std::string GetConvolutionMethodString(arm_compute::ConvolutionMethod &convolutionMethod)
#define ARMNN_SCOPED_PROFILING_EVENT_CL(name)
void RunClFunction(arm_compute::IFunction &function, const CheckLocation &location)
std::array< unsigned int, MaxNumOfTensorDimensions > Coordinates
virtual const char * what() const noexcept override
Definition: Exceptions.cpp:32
Copyright (c) 2021 ARM Limited and Contributors.
const TensorInfo & GetTensorInfo() const
DataType
Definition: Types.hpp:48
#define ARMNN_ASSERT_MSG(COND, MSG)
Definition: Assert.hpp:15
DataType GetDataType() const
Definition: Tensor.hpp:198
RuntimeException WrapClError(const cl::Error &clError, const CheckLocation &location)
#define ARMNN_ASSERT(COND)
Definition: Assert.hpp:14
auto SetClSliceData(const std::vector< unsigned int > &m_begin, const std::vector< unsigned int > &m_size)
virtual const void * Map(bool blocking=true) const =0
Map the tensor data for access.
void CopyArmComputeClTensorData(arm_compute::CLTensor &dstTensor, const T *srcData)
DataType * GetOutputTensorData(unsigned int idx, const PayloadType &data)
void InitializeArmComputeClTensorData(arm_compute::CLTensor &clTensor, const ConstTensorHandle *handle)
half_float::half Half
Definition: Half.hpp:18
auto SetClStridedSliceData(const std::vector< int > &m_begin, const std::vector< int > &m_end, const std::vector< int > &m_stride)
const T * GetConstTensor() const