• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright © 2017 Arm Ltd. All rights reserved.
3 // SPDX-License-Identifier: MIT
4 //
5 
6 #include "ClConvolution2dWorkload.hpp"
7 
8 #include "ClWorkloadUtils.hpp"
9 
10 #include <cl/ClLayerSupport.hpp>
11 #include <cl/ClTensorHandle.hpp>
12 #include <cl/ClLayerSupport.hpp>
13 #include <aclCommon/ArmComputeUtils.hpp>
14 #include <aclCommon/ArmComputeTensorUtils.hpp>
15 #include <backendsCommon/CpuTensorHandle.hpp>
16 
17 #include <arm_compute/runtime/CL/functions/CLConvolutionLayer.h>
18 
19 namespace armnn
20 {
21 using namespace armcomputetensorutils;
22 
ClConvolution2dWorkloadValidate(const TensorInfo & input,const TensorInfo & output,const Convolution2dDescriptor & descriptor,const TensorInfo & weights,const Optional<TensorInfo> & biases,bool isFastMathEnabled,const ActivationDescriptor * activationDescriptor)23 arm_compute::Status ClConvolution2dWorkloadValidate(const TensorInfo& input,
24                                                     const TensorInfo& output,
25                                                     const Convolution2dDescriptor& descriptor,
26                                                     const TensorInfo& weights,
27                                                     const Optional<TensorInfo>& biases,
28                                                     bool isFastMathEnabled,
29                                                     const ActivationDescriptor* activationDescriptor)
30 {
31     const arm_compute::TensorInfo aclInputInfo = BuildArmComputeTensorInfo(input, descriptor.m_DataLayout);
32     const arm_compute::TensorInfo aclOutputInfo = BuildArmComputeTensorInfo(output, descriptor.m_DataLayout);
33     const arm_compute::TensorInfo aclWeightsInfo = BuildArmComputeTensorInfo(weights, descriptor.m_DataLayout);
34 
35     const arm_compute::Size2D aclDilationInfo = BuildArmComputeSize2D(descriptor.m_DilationX,
36                                                                       descriptor.m_DilationY);
37 
38     arm_compute::TensorInfo aclBiasesInfo;
39     arm_compute::TensorInfo *optionalAclBiasesInfo = nullptr;
40 
41     if (descriptor.m_BiasEnabled)
42     {
43         ARMNN_ASSERT(biases.has_value());
44 
45         aclBiasesInfo = BuildArmComputeTensorInfo(biases.value(), descriptor.m_DataLayout);
46         optionalAclBiasesInfo = &aclBiasesInfo;
47     }
48 
49     arm_compute::PadStrideInfo layerInfo = BuildArmComputePadStrideInfo(descriptor);
50 
51     const arm_compute::ActivationLayerInfo activationInfo = ConvertActivationDescriptorToAclActivationLayerInfo(
52             activationDescriptor);
53 
54     return arm_compute::CLConvolutionLayer::validate(&aclInputInfo,
55                                                      &aclWeightsInfo,
56                                                      optionalAclBiasesInfo,
57                                                      &aclOutputInfo,
58                                                      layerInfo,
59                                                      arm_compute::WeightsInfo(),
60                                                      aclDilationInfo,
61                                                      activationInfo,
62                                                      isFastMathEnabled);
63 }
64 
ClConvolution2dWorkload(const Convolution2dQueueDescriptor & descriptor,const WorkloadInfo & info,std::shared_ptr<arm_compute::MemoryManagerOnDemand> & memoryManager,const bool isFastMathEnabled)65 ClConvolution2dWorkload::ClConvolution2dWorkload(const Convolution2dQueueDescriptor& descriptor,
66                                                  const WorkloadInfo& info,
67                                                  std::shared_ptr<arm_compute::MemoryManagerOnDemand>& memoryManager,
68                                                  const bool isFastMathEnabled)
69     : BaseWorkload<Convolution2dQueueDescriptor>(descriptor, info)
70     , m_ConvolutionLayer(memoryManager)
71 {
72     // todo: check tensor shapes match.
73     const TensorInfo& weightInfo = m_Data.m_Weight->GetTensorInfo();
74 
75     m_KernelTensor = std::make_unique<arm_compute::CLTensor>();
76     BuildArmComputeTensor(*m_KernelTensor, weightInfo, m_Data.m_Parameters.m_DataLayout);
77 
78     const arm_compute::Size2D aclDilationInfo = BuildArmComputeSize2D(m_Data.m_Parameters.m_DilationX,
79                                                                       m_Data.m_Parameters.m_DilationY);
80 
81     if (m_Data.m_Parameters.m_BiasEnabled)
82     {
83         m_BiasTensor = std::make_unique<arm_compute::CLTensor>();
84         BuildArmComputeTensor(*m_BiasTensor, m_Data.m_Bias->GetTensorInfo(), m_Data.m_Parameters.m_DataLayout);
85     }
86 
87     m_Data.ValidateInputsOutputs("ClConvolution2dWorkload", 1, 1);
88 
89     arm_compute::ICLTensor& input  = static_cast<IClTensorHandle*>(m_Data.m_Inputs[0])->GetTensor();
90     arm_compute::ICLTensor& output = static_cast<IClTensorHandle*>(m_Data.m_Outputs[0])->GetTensor();
91 
92     arm_compute::DataLayout aclDataLayout = ConvertDataLayout(m_Data.m_Parameters.m_DataLayout);
93     input.info()->set_data_layout(aclDataLayout);
94     output.info()->set_data_layout(aclDataLayout);
95 
96     arm_compute::PadStrideInfo padStrideInfo = BuildArmComputePadStrideInfo(m_Data.m_Parameters);
97 
98     const arm_compute::ActivationLayerInfo activationInfo = ConvertAdditionalInfoToAclActivationLayerInfo(descriptor);
99 
100     m_ConvolutionLayer.configure(&input,
101                                  m_KernelTensor.get(),
102                                  m_BiasTensor.get(),
103                                  &output,
104                                  padStrideInfo,
105                                  arm_compute::WeightsInfo(),
106                                  aclDilationInfo,
107                                  activationInfo,
108                                  isFastMathEnabled);
109 
110     m_ConvolutionMethod =
111         m_ConvolutionLayer.get_convolution_method(input.info(),
112                                                   m_KernelTensor->info(),
113                                                   output.info(),
114                                                   padStrideInfo,
115                                                   arm_compute::WeightsInfo(),
116                                                   activationInfo,
117                                                   arm_compute::CLScheduler::get().target(),
118                                                   aclDilationInfo,
119                                                   isFastMathEnabled);
120 
121     InitializeArmComputeClTensorData(*m_KernelTensor, m_Data.m_Weight);
122 
123     if (m_BiasTensor)
124     {
125         InitializeArmComputeClTensorData(*m_BiasTensor, m_Data.m_Bias);
126     }
127 
128     // Force Compute Library to perform the necessary copying and reshaping, after which
129     // delete all the input tensors that will no longer be needed
130     m_ConvolutionLayer.prepare();
131     FreeUnusedTensors();
132 }
133 
Execute() const134 void ClConvolution2dWorkload::Execute() const
135 {
136     ARMNN_SCOPED_PROFILING_EVENT_CL("ClConvolution2dWorkload_Execute");
137     RunClFunction(m_ConvolutionLayer, CHECK_LOCATION());
138 }
139 
GetConvolutionMethod() const140 arm_compute::ConvolutionMethod ClConvolution2dWorkload::GetConvolutionMethod() const
141 {
142     return m_ConvolutionMethod;
143 }
144 
FreeUnusedTensors()145 void ClConvolution2dWorkload::FreeUnusedTensors()
146 {
147     FreeTensorIfUnused(m_KernelTensor);
148     FreeTensorIfUnused(m_BiasTensor);
149 }
150 
151 } //namespace armnn
152