• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright © 2017 Arm Ltd. All rights reserved.
3 // SPDX-License-Identifier: MIT
4 //
5 #pragma once
6 
7 #include <Half.hpp>
8 
9 #include <aclCommon/ArmComputeTensorUtils.hpp>
10 #include <cl/OpenClTimer.hpp>
11 #include <backendsCommon/CpuTensorHandle.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                                                   name, \
23                                                   armnn::OpenClTimer(), \
24                                                   armnn::WallClockTimer())
25 
26 namespace armnn
27 {
28 
29 template <typename T>
CopyArmComputeClTensorData(arm_compute::CLTensor & dstTensor,const T * srcData)30 void CopyArmComputeClTensorData(arm_compute::CLTensor& dstTensor, const T* srcData)
31 {
32     {
33         ARMNN_SCOPED_PROFILING_EVENT_CL("MapClTensorForWriting");
34         dstTensor.map(true);
35     }
36 
37     {
38         ARMNN_SCOPED_PROFILING_EVENT_CL("CopyToClTensor");
39         armcomputetensorutils::CopyArmComputeITensorData<T>(srcData, dstTensor);
40     }
41 
42     dstTensor.unmap();
43 }
44 
SetClStridedSliceData(const std::vector<int> & m_begin,const std::vector<int> & m_end,const std::vector<int> & m_stride)45 inline auto SetClStridedSliceData(const std::vector<int>& m_begin,
46                                   const std::vector<int>& m_end,
47                                   const std::vector<int>& m_stride)
48 {
49     arm_compute::Coordinates starts;
50     arm_compute::Coordinates ends;
51     arm_compute::Coordinates strides;
52 
53     unsigned int num_dims = static_cast<unsigned int>(m_begin.size());
54 
55     for (unsigned int i = 0; i < num_dims; i++) {
56         unsigned int revertedIndex = num_dims - i - 1;
57 
58         starts.set(i, static_cast<int>(m_begin[revertedIndex]));
59         ends.set(i, static_cast<int>(m_end[revertedIndex]));
60         strides.set(i, static_cast<int>(m_stride[revertedIndex]));
61     }
62 
63     return std::make_tuple(starts, ends, strides);
64 }
65 
SetClSliceData(const std::vector<unsigned int> & m_begin,const std::vector<unsigned int> & m_size)66 inline auto SetClSliceData(const std::vector<unsigned int>& m_begin,
67                            const std::vector<unsigned int>& m_size)
68 {
69     // This function must translate the size vector given to an end vector
70     // expected by the ACL NESlice workload
71     arm_compute::Coordinates starts;
72     arm_compute::Coordinates ends;
73 
74     unsigned int num_dims = static_cast<unsigned int>(m_begin.size());
75 
76     // For strided slices, we have the relationship size = (end - begin) / stride
77     // For slice, we assume stride to be a vector of all ones, yielding the formula
78     // size = (end - begin) therefore we know end = size + begin
79     for (unsigned int i = 0; i < num_dims; i++)
80     {
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_begin[revertedIndex] + m_size[revertedIndex]));
85     }
86 
87     return std::make_tuple(starts, ends);
88 }
89 
InitializeArmComputeClTensorData(arm_compute::CLTensor & clTensor,const ConstCpuTensorHandle * handle)90 inline void InitializeArmComputeClTensorData(arm_compute::CLTensor& clTensor,
91                                              const ConstCpuTensorHandle* handle)
92 {
93     ARMNN_ASSERT(handle);
94 
95     armcomputetensorutils::InitialiseArmComputeTensorEmpty(clTensor);
96     switch(handle->GetTensorInfo().GetDataType())
97     {
98         case DataType::Float16:
99             CopyArmComputeClTensorData(clTensor, handle->GetConstTensor<armnn::Half>());
100             break;
101         case DataType::Float32:
102             CopyArmComputeClTensorData(clTensor, handle->GetConstTensor<float>());
103             break;
104         case DataType::QAsymmU8:
105             CopyArmComputeClTensorData(clTensor, handle->GetConstTensor<uint8_t>());
106             break;
107         ARMNN_NO_DEPRECATE_WARN_BEGIN
108         case DataType::QuantizedSymm8PerAxis:
109             ARMNN_FALLTHROUGH;
110         case DataType::QAsymmS8:
111         case DataType::QSymmS8:
112             CopyArmComputeClTensorData(clTensor, handle->GetConstTensor<int8_t>());
113             break;
114         case DataType::QSymmS16:
115             CopyArmComputeClTensorData(clTensor, handle->GetConstTensor<int16_t>());
116             break;
117         ARMNN_NO_DEPRECATE_WARN_END
118         case DataType::Signed32:
119             CopyArmComputeClTensorData(clTensor, handle->GetConstTensor<int32_t>());
120             break;
121         default:
122             ARMNN_ASSERT_MSG(false, "Unexpected tensor type.");
123     }
124 };
125 
WrapClError(const cl::Error & clError,const CheckLocation & location)126 inline RuntimeException WrapClError(const cl::Error& clError, const CheckLocation& location)
127 {
128     std::stringstream message;
129     message << "CL error: " << clError.what() << ". Error code: " << clError.err();
130 
131     return RuntimeException(message.str(), location);
132 }
133 
RunClFunction(arm_compute::IFunction & function,const CheckLocation & location)134 inline void RunClFunction(arm_compute::IFunction& function, const CheckLocation& location)
135 {
136     try
137     {
138         function.run();
139     }
140     catch (cl::Error& error)
141     {
142         throw WrapClError(error, location);
143     }
144 }
145 
146 } //namespace armnn
147