blob: 91c0018c93d00c994aefdd043648d3ecd78fe512 [file] [log] [blame]
telsoa01c577f2c2018-08-31 09:22:23 +01001//
2// Copyright © 2017 Arm Ltd. All rights reserved.
David Beckecb56cd2018-09-05 12:52:57 +01003// SPDX-License-Identifier: MIT
telsoa01c577f2c2018-08-31 09:22:23 +01004//
5
Matthew Benthamd8777392018-10-08 09:38:55 +01006#include "ClDepthwiseConvolutionWorkload.hpp"
telsoa01c577f2c2018-08-31 09:22:23 +01007
Aron Virginas-Tard4f0fea2019-04-09 14:08:06 +01008#include <ResolveType.hpp>
Matthew Benthamd8777392018-10-08 09:38:55 +01009#include "ClWorkloadUtils.hpp"
telsoa01c577f2c2018-08-31 09:22:23 +010010
Mike Kelly07810fc2020-11-12 10:58:48 +000011#include <armnn/Exceptions.hpp>
Aron Virginas-Tarc9cc8042018-11-01 16:15:57 +000012#include <aclCommon/ArmComputeUtils.hpp>
13#include <aclCommon/ArmComputeTensorUtils.hpp>
14#include <cl/ClTensorHandle.hpp>
James Conroy1f58f032021-04-27 17:13:27 +010015#include <backendsCommon/TensorHandle.hpp>
Matteo Martincigh747ef822018-12-18 09:26:39 +000016#include <backendsCommon/WorkloadUtils.hpp>
Mike Kelly07810fc2020-11-12 10:58:48 +000017#include <backendsCommon/WorkloadData.hpp>
telsoa01c577f2c2018-08-31 09:22:23 +010018
Matthew Benthamd8777392018-10-08 09:38:55 +010019#include <arm_compute/runtime/CL/functions/CLDepthwiseConvolutionLayer.h>
20
telsoa01c577f2c2018-08-31 09:22:23 +010021namespace armnn
22{
23
24using namespace armcomputetensorutils;
25
26arm_compute::Status ClDepthwiseConvolutionWorkloadValidate(const TensorInfo& input,
Matteo Martincigh747ef822018-12-18 09:26:39 +000027 const TensorInfo& output,
28 const DepthwiseConvolution2dDescriptor& descriptor,
29 const TensorInfo& weights,
Mike Kelly07810fc2020-11-12 10:58:48 +000030 const Optional<TensorInfo>& biases,
31 const ActivationDescriptor* activationDescriptor)
telsoa01c577f2c2018-08-31 09:22:23 +010032{
Matteo Martincigh747ef822018-12-18 09:26:39 +000033 const arm_compute::TensorInfo aclInputInfo = BuildArmComputeTensorInfo(input, descriptor.m_DataLayout);
Nikhil Raja05c2102018-09-25 16:16:13 +010034 const arm_compute::TensorInfo aclOutputInfo = BuildArmComputeTensorInfo(output, descriptor.m_DataLayout);
Matteo Martincigh747ef822018-12-18 09:26:39 +000035
Jan Eilers53ef7952021-06-02 12:01:25 +010036 // ArmNN's weight format is usually [ M, I, H, W ] but for depthwise its [ 1, H, W, I*M]
37 // Permute to [ 1, I * M, H, W ] (if NCHW) as required by the compute library
38 unsigned int aclDepthMultiplier;
39 TensorInfo weightsPermuted;
40 std::tie(weightsPermuted, aclDepthMultiplier) = Convert1HWOTensorInfoToAcl(weights, input,descriptor.m_DataLayout);
Matteo Martincigh747ef822018-12-18 09:26:39 +000041
42 // Convert the weights into the compute library format
43 const arm_compute::TensorInfo aclWeightsInfo = BuildArmComputeTensorInfo(weightsPermuted, descriptor.m_DataLayout);
telsoa01c577f2c2018-08-31 09:22:23 +010044
45 arm_compute::TensorInfo aclBiasesInfo;
46 arm_compute::TensorInfo *optionalAclBiasesInfo = nullptr;
arovir01a6824102018-08-28 17:40:45 +010047
telsoa01c577f2c2018-08-31 09:22:23 +010048 if (descriptor.m_BiasEnabled)
49 {
Narumol Prangnawaratac2770a2020-04-01 16:51:23 +010050 ARMNN_ASSERT(biases.has_value());
arovir01a6824102018-08-28 17:40:45 +010051
David Beck5eec11d2018-10-04 15:43:17 +010052 aclBiasesInfo = BuildArmComputeTensorInfo(biases.value(), descriptor.m_DataLayout);
telsoa01c577f2c2018-08-31 09:22:23 +010053 optionalAclBiasesInfo = &aclBiasesInfo;
54 }
55
56 const arm_compute::PadStrideInfo aclPadStrideInfo = BuildArmComputePadStrideInfo(descriptor);
Pablo Tellof0bd6832019-04-26 17:58:13 +010057 const arm_compute::Size2D aclDilationInfo = BuildArmComputeSize2D(
58 descriptor.m_DilationX,
59 descriptor.m_DilationY);
telsoa01c577f2c2018-08-31 09:22:23 +010060
Mike Kelly07810fc2020-11-12 10:58:48 +000061 const arm_compute::ActivationLayerInfo activationInfo = ConvertActivationDescriptorToAclActivationLayerInfo(
62 activationDescriptor);
63
telsoa01c577f2c2018-08-31 09:22:23 +010064 return arm_compute::CLDepthwiseConvolutionLayer::validate(&aclInputInfo,
65 &aclWeightsInfo,
66 optionalAclBiasesInfo,
67 &aclOutputInfo,
68 aclPadStrideInfo,
Pablo Tellof0bd6832019-04-26 17:58:13 +010069 aclDepthMultiplier,
Mike Kelly07810fc2020-11-12 10:58:48 +000070 activationInfo,
Pablo Tellof0bd6832019-04-26 17:58:13 +010071 aclDilationInfo);
72
telsoa01c577f2c2018-08-31 09:22:23 +010073}
74
Matthew Benthamd8777392018-10-08 09:38:55 +010075ClDepthwiseConvolutionWorkload::ClDepthwiseConvolutionWorkload(
telsoa01c577f2c2018-08-31 09:22:23 +010076 const DepthwiseConvolution2dQueueDescriptor& descriptor,
Sadik Armagane9444752020-12-02 11:28:58 +000077 const WorkloadInfo& info,
78 const arm_compute::CLCompileContext& clCompileContext)
Matthew Benthamd8777392018-10-08 09:38:55 +010079 : BaseWorkload<DepthwiseConvolution2dQueueDescriptor>(descriptor, info)
telsoa01c577f2c2018-08-31 09:22:23 +010080{
Keith Davisbcd860a2021-08-05 14:20:33 +010081 // Add details for profiling output
82 WorkloadInfo detailsInfo;
83
84 detailsInfo.m_InputTensorInfos = info.m_InputTensorInfos;
85 detailsInfo.m_OutputTensorInfos = info.m_OutputTensorInfos;
86 detailsInfo.m_WeightsTensorInfo = armnn::Optional<armnn::TensorInfo>(descriptor.m_Weight->GetTensorInfo());
87 if (descriptor.m_Parameters.m_BiasEnabled)
88 {
89 detailsInfo.m_BiasTensorInfo = armnn::Optional<armnn::TensorInfo>(descriptor.m_Bias->GetTensorInfo());
90 }
91
92 // Report Profiling Details
93 ARMNN_REPORT_PROFILING_WORKLOAD_DESC("ClDepthwiseConvolutionWorkload_Construct",
94 descriptor.m_Parameters,
95 detailsInfo,
96 this->GetGuid());
97
Jan Eilers53ef7952021-06-02 12:01:25 +010098 // ArmNN's weight format is usually [ M, I, H, W ] but for depthwise its [ 1, H, W, I*M]
99 // Permute to [ 1, I * M, H, W ] (if NCHW), as required by the compute library
100 ConstTensor weightPermuted;
101 unsigned int depthMultiplier;
Matteo Martincigh747ef822018-12-18 09:26:39 +0000102 std::unique_ptr<unsigned char[]> permuteBuffer(new unsigned char[m_Data.m_Weight->GetTensorInfo().GetNumBytes()]);
Jan Eilers53ef7952021-06-02 12:01:25 +0100103 std::tie(weightPermuted, depthMultiplier) = Convert1HWOTensorToAcl(m_Data.m_Weight,
Keith Davisbcd860a2021-08-05 14:20:33 +0100104 info.m_InputTensorInfos[0],
105 m_Data.m_Parameters.m_DataLayout,
106 permuteBuffer.get());
Matteo Martincigh747ef822018-12-18 09:26:39 +0000107
108 // Convert the weights into the compute library format
telsoa01c577f2c2018-08-31 09:22:23 +0100109 m_KernelTensor = std::make_unique<arm_compute::CLTensor>();
Matteo Martincigh747ef822018-12-18 09:26:39 +0000110 BuildArmComputeTensor(*m_KernelTensor, weightPermuted.GetInfo(), m_Data.m_Parameters.m_DataLayout);
telsoa01c577f2c2018-08-31 09:22:23 +0100111
112 if (m_Data.m_Parameters.m_BiasEnabled)
113 {
114 m_BiasTensor = std::make_unique<arm_compute::CLTensor>();
Nikhil Rajcec6b652018-10-12 13:51:57 +0100115 BuildArmComputeTensor(*m_BiasTensor, m_Data.m_Bias->GetTensorInfo(), m_Data.m_Parameters.m_DataLayout);
telsoa01c577f2c2018-08-31 09:22:23 +0100116 }
117
Pablo Tellof0bd6832019-04-26 17:58:13 +0100118 const arm_compute::Size2D aclDilationInfo = BuildArmComputeSize2D(
119 m_Data.m_Parameters.m_DilationX,
120 m_Data.m_Parameters.m_DilationY);
121
122
Matthew Benthamd8777392018-10-08 09:38:55 +0100123 std::string name = std::string("ClDepthwiseConvolutionWorkload");
telsoa01c577f2c2018-08-31 09:22:23 +0100124 m_Data.ValidateInputsOutputs(name, 1, 1);
125
126 arm_compute::ICLTensor& input = static_cast<IClTensorHandle*>(m_Data.m_Inputs[0])->GetTensor();
127 arm_compute::ICLTensor& output = static_cast<IClTensorHandle*>(m_Data.m_Outputs[0])->GetTensor();
128
Nikhil Rajcec6b652018-10-12 13:51:57 +0100129 arm_compute::DataLayout aclDataLayout = ConvertDataLayout(m_Data.m_Parameters.m_DataLayout);
130 input.info()->set_data_layout(aclDataLayout);
131 output.info()->set_data_layout(aclDataLayout);
132
Aron Virginas-Tar6f3785d2019-07-22 15:30:22 +0100133 arm_compute::PadStrideInfo padStrideInfo = BuildArmComputePadStrideInfo(m_Data.m_Parameters);
Pablo Tellof0bd6832019-04-26 17:58:13 +0100134
Mike Kelly07810fc2020-11-12 10:58:48 +0000135 const arm_compute::ActivationLayerInfo activationInfo = ConvertAdditionalInfoToAclActivationLayerInfo(descriptor);
136
Aron Virginas-Tarf4c502f2019-11-14 16:21:38 +0000137 m_DepthwiseConvolutionLayer = std::make_unique<arm_compute::CLDepthwiseConvolutionLayer>();
telsoa01c577f2c2018-08-31 09:22:23 +0100138
Kevin May9f6862d2021-10-22 15:42:28 +0100139 {
140 ARMNN_SCOPED_PROFILING_EVENT(Compute::Undefined, "ClDepthwiseConvolutionWorkload_configure");
141 static_cast<arm_compute::CLDepthwiseConvolutionLayer*>(m_DepthwiseConvolutionLayer.get())->configure(
142 clCompileContext,
143 &input,
144 m_KernelTensor.get(),
145 m_BiasTensor.get(),
146 &output,
147 padStrideInfo,
148 depthMultiplier,
149 activationInfo,
150 aclDilationInfo);
151 }
Narumol Prangnawaratac2770a2020-04-01 16:51:23 +0100152 ARMNN_ASSERT(m_DepthwiseConvolutionLayer);
Matthew Benthamd8777392018-10-08 09:38:55 +0100153
James Conroy1f58f032021-04-27 17:13:27 +0100154 ScopedTensorHandle weightsPermutedHandle(weightPermuted);
Matteo Martincigh747ef822018-12-18 09:26:39 +0000155 InitializeArmComputeClTensorData(*m_KernelTensor, &weightsPermutedHandle);
Matthew Benthamd8777392018-10-08 09:38:55 +0100156
157 if (m_BiasTensor)
158 {
159 InitializeArmComputeClTensorData(*m_BiasTensor, m_Data.m_Bias);
160 }
161
162 m_DepthwiseConvolutionLayer->prepare();
163 FreeUnusedTensors();
telsoa01c577f2c2018-08-31 09:22:23 +0100164}
165
Matthew Benthamd8777392018-10-08 09:38:55 +0100166void ClDepthwiseConvolutionWorkload::FreeUnusedTensors()
telsoa01c577f2c2018-08-31 09:22:23 +0100167{
168 FreeTensorIfUnused(m_KernelTensor);
169 FreeTensorIfUnused(m_BiasTensor);
170}
171
Matthew Benthamd8777392018-10-08 09:38:55 +0100172void ClDepthwiseConvolutionWorkload::Execute() const
173{
Keith Davisbcd860a2021-08-05 14:20:33 +0100174 ARMNN_SCOPED_PROFILING_EVENT_CL_GUID("ClDepthwiseConvolutionWorkload_Execute", this->GetGuid());
Narumol Prangnawaratac2770a2020-04-01 16:51:23 +0100175 ARMNN_ASSERT(m_DepthwiseConvolutionLayer);
Matthew Benthamd8777392018-10-08 09:38:55 +0100176
Aron Virginas-Tara8e06ed2018-10-19 16:46:15 +0100177 RunClFunction(*m_DepthwiseConvolutionLayer, CHECK_LOCATION());
Matthew Benthamd8777392018-10-08 09:38:55 +0100178}
telsoa01c577f2c2018-08-31 09:22:23 +0100179
180} // namespace armnn