ArmNN
 21.08
NeonWorkloadUtils.hpp
Go to the documentation of this file.
1 //
2 // Copyright © 2017 Arm Ltd. All rights reserved.
3 // SPDX-License-Identifier: MIT
4 //
5 #pragma once
6 
10 #include <neon/NeonTimer.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 
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>
54 void CopyArmComputeTensorData(arm_compute::Tensor& dstTensor, const T* srcData)
55 {
56  InitialiseArmComputeTensorEmpty(dstTensor);
57  CopyArmComputeITensorData(srcData, dstTensor);
58 }
59 
60 inline void InitializeArmComputeTensorData(arm_compute::Tensor& tensor,
61  const ConstTensorHandle* handle)
62 {
63  ARMNN_ASSERT(handle);
64 
65  switch(handle->GetTensorInfo().GetDataType())
66  {
67  case DataType::Float16:
69  break;
70  case DataType::Float32:
71  CopyArmComputeTensorData(tensor, handle->GetConstTensor<float>());
72  break;
73  case DataType::QAsymmU8:
74  CopyArmComputeTensorData(tensor, handle->GetConstTensor<uint8_t>());
75  break;
79  case DataType::QSymmS8:
80  case DataType::QAsymmS8:
81  CopyArmComputeTensorData(tensor, handle->GetConstTensor<int8_t>());
82  break;
84  case DataType::Signed32:
85  CopyArmComputeTensorData(tensor, handle->GetConstTensor<int32_t>());
86  break;
87  case DataType::QSymmS16:
88  CopyArmComputeTensorData(tensor, handle->GetConstTensor<int16_t>());
89  break;
90  default:
91  ARMNN_ASSERT_MSG(false, "Unexpected tensor type.");
92  }
93 };
94 
95 inline auto SetNeonStridedSliceData(const std::vector<int>& m_begin,
96  const std::vector<int>& m_end,
97  const std::vector<int>& m_stride)
98 {
101  arm_compute::Coordinates strides;
102 
103  unsigned int num_dims = static_cast<unsigned int>(m_begin.size());
104 
105  for (unsigned int i = 0; i < num_dims; i++)
106  {
107  unsigned int revertedIndex = num_dims - i - 1;
108 
109  starts.set(i, static_cast<int>(m_begin[revertedIndex]));
110  ends.set(i, static_cast<int>(m_end[revertedIndex]));
111  strides.set(i, static_cast<int>(m_stride[revertedIndex]));
112  }
113 
114  return std::make_tuple(starts, ends, strides);
115 }
116 
117 inline auto SetNeonSliceData(const std::vector<unsigned int>& m_begin,
118  const std::vector<unsigned int>& m_size)
119 {
120  // This function must translate the size vector given to an end vector
121  // expected by the ACL NESlice workload
124 
125  unsigned int num_dims = static_cast<unsigned int>(m_begin.size());
126 
127  // For strided slices, we have the relationship size = (end - begin) / stride
128  // For slice, we assume stride to be a vector of all ones, yielding the formula
129  // size = (end - begin) therefore we know end = size + begin
130  for (unsigned int i = 0; i < num_dims; i++)
131  {
132  unsigned int revertedIndex = num_dims - i - 1;
133 
134  starts.set(i, static_cast<int>(m_begin[revertedIndex]));
135  ends.set(i, static_cast<int>(m_begin[revertedIndex] + m_size[revertedIndex]));
136  }
137 
138  return std::make_tuple(starts, ends);
139 }
140 
141 template <typename DataType, typename PayloadType>
142 DataType* GetOutputTensorData(unsigned int idx, const PayloadType& data)
143 {
144  ITensorHandle* tensorHandle = data.m_Outputs[idx];
145  return reinterpret_cast<DataType*>(tensorHandle->Map());
146 }
147 
148 } //namespace armnn
std::string GetConvolutionMethodString(arm_compute::ConvolutionMethod &convolutionMethod)
#define ARMNN_NO_DEPRECATE_WARN_BEGIN
Definition: Deprecated.hpp:33
std::array< unsigned int, MaxNumOfTensorDimensions > Coordinates
Copyright (c) 2021 ARM Limited and Contributors.
auto SetNeonStridedSliceData(const std::vector< int > &m_begin, const std::vector< int > &m_end, const std::vector< int > &m_stride)
const TensorInfo & GetTensorInfo() const
DataType
Definition: Types.hpp:35
#define ARMNN_NO_DEPRECATE_WARN_END
Definition: Deprecated.hpp:34
#define ARMNN_ASSERT_MSG(COND, MSG)
Definition: Assert.hpp:15
DataType GetDataType() const
Definition: Tensor.hpp:198
auto SetNeonSliceData(const std::vector< unsigned int > &m_begin, const std::vector< unsigned int > &m_size)
#define ARMNN_FALLTHROUGH
Definition: Utils.hpp:36
#define ARMNN_ASSERT(COND)
Definition: Assert.hpp:14
virtual const void * Map(bool blocking=true) const =0
Map the tensor data for access.
void CopyArmComputeTensorData(arm_compute::Tensor &dstTensor, const T *srcData)
DataType * GetOutputTensorData(unsigned int idx, const PayloadType &data)
void InitializeArmComputeTensorData(arm_compute::Tensor &tensor, const ConstTensorHandle *handle)
half_float::half Half
Definition: Half.hpp:16
const T * GetConstTensor() const