blob: 3a972d3f398488cfac2ec4a18c05a5ae0d16d05f [file] [log] [blame]
telsoa01c577f2c2018-08-31 09:22:23 +01001//
Teresa Charlin588cbdf2022-01-19 15:55:37 +00002// Copyright © 2017 Arm Ltd and Contributors. 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>
Colm Donelan0c479742021-12-10 12:43:54 +000015#include <armnn/backends/TensorHandle.hpp>
Matteo Martincigh747ef822018-12-18 09:26:39 +000016#include <backendsCommon/WorkloadUtils.hpp>
Colm Donelan0c479742021-12-10 12:43:54 +000017#include <armnn/backends/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{
Cathal Corbett4452baf2022-05-13 09:55:59 +010033 // The CL implemented workload does support both const and non const
34 // weights. However, in the case of non const weights we'd have to call
35 // prepare or configure for each inference which we're not setup to do just yet.
36 if (!weights.IsConstant())
37 {
38 return arm_compute::Status{arm_compute::ErrorCode::RUNTIME_ERROR,
39 "ArmNN ClDepthwiseConv2dWorkload does not support non constant weights."};
40 }
41
Matteo Martincigh747ef822018-12-18 09:26:39 +000042 const arm_compute::TensorInfo aclInputInfo = BuildArmComputeTensorInfo(input, descriptor.m_DataLayout);
Nikhil Raja05c2102018-09-25 16:16:13 +010043 const arm_compute::TensorInfo aclOutputInfo = BuildArmComputeTensorInfo(output, descriptor.m_DataLayout);
Matteo Martincigh747ef822018-12-18 09:26:39 +000044
Cathal Corbett4b19d222022-05-11 20:12:17 +010045 // ArmNN format for weights for depthwise is [1, H, W, C] independently of the input/output layout
46 //
47 // ACL format for weights for depthwise is:
48 // - [1, H, W, C] for [N, H, W, C] input/output layout (matches with ArmNN)
49 // - [1, C, H, W] for [N, C, H, W] input/output layout
50 //
51 // Therefore ArmNN weights have to be permuted when input/output layout is [N, C, H, W] to pass them to ACL.
52 // The PermuteDepthwiseConv2dWeights backend optimization takes care of this, but it has not been performed yet,
53 // so we do the permute here for the TensorInfo weights.
Jan Eilers53ef7952021-06-02 12:01:25 +010054 unsigned int aclDepthMultiplier;
55 TensorInfo weightsPermuted;
56 std::tie(weightsPermuted, aclDepthMultiplier) = Convert1HWOTensorInfoToAcl(weights, input,descriptor.m_DataLayout);
Matteo Martincigh747ef822018-12-18 09:26:39 +000057
58 // Convert the weights into the compute library format
Cathal Corbett4452baf2022-05-13 09:55:59 +010059 arm_compute::TensorInfo aclWeightsInfo = BuildArmComputeTensorInfo(weightsPermuted, descriptor.m_DataLayout);
60 aclWeightsInfo.set_are_values_constant(weights.IsConstant());
telsoa01c577f2c2018-08-31 09:22:23 +010061
62 arm_compute::TensorInfo aclBiasesInfo;
Cathal Corbett4b19d222022-05-11 20:12:17 +010063 arm_compute::TensorInfo* optionalAclBiasesInfo = nullptr;
telsoa01c577f2c2018-08-31 09:22:23 +010064 if (descriptor.m_BiasEnabled)
65 {
Narumol Prangnawaratac2770a2020-04-01 16:51:23 +010066 ARMNN_ASSERT(biases.has_value());
Cathal Corbett4452baf2022-05-13 09:55:59 +010067 // Same for bias as weights. We don't currently support non const.
68 if (!biases.value().IsConstant())
69 {
70 return arm_compute::Status{arm_compute::ErrorCode::RUNTIME_ERROR,
71 "ArmNN ClDepthwiseConv2dWorkload does not support non constant bias."};
72 }
David Beck5eec11d2018-10-04 15:43:17 +010073 aclBiasesInfo = BuildArmComputeTensorInfo(biases.value(), descriptor.m_DataLayout);
Cathal Corbett4452baf2022-05-13 09:55:59 +010074 aclBiasesInfo.set_are_values_constant(biases.value().IsConstant());
telsoa01c577f2c2018-08-31 09:22:23 +010075 optionalAclBiasesInfo = &aclBiasesInfo;
76 }
77
78 const arm_compute::PadStrideInfo aclPadStrideInfo = BuildArmComputePadStrideInfo(descriptor);
Pablo Tellof0bd6832019-04-26 17:58:13 +010079 const arm_compute::Size2D aclDilationInfo = BuildArmComputeSize2D(
80 descriptor.m_DilationX,
81 descriptor.m_DilationY);
telsoa01c577f2c2018-08-31 09:22:23 +010082
Mike Kelly07810fc2020-11-12 10:58:48 +000083 const arm_compute::ActivationLayerInfo activationInfo = ConvertActivationDescriptorToAclActivationLayerInfo(
84 activationDescriptor);
85
telsoa01c577f2c2018-08-31 09:22:23 +010086 return arm_compute::CLDepthwiseConvolutionLayer::validate(&aclInputInfo,
87 &aclWeightsInfo,
88 optionalAclBiasesInfo,
89 &aclOutputInfo,
90 aclPadStrideInfo,
Pablo Tellof0bd6832019-04-26 17:58:13 +010091 aclDepthMultiplier,
Mike Kelly07810fc2020-11-12 10:58:48 +000092 activationInfo,
Pablo Tellof0bd6832019-04-26 17:58:13 +010093 aclDilationInfo);
94
telsoa01c577f2c2018-08-31 09:22:23 +010095}
96
Matthew Benthamd8777392018-10-08 09:38:55 +010097ClDepthwiseConvolutionWorkload::ClDepthwiseConvolutionWorkload(
telsoa01c577f2c2018-08-31 09:22:23 +010098 const DepthwiseConvolution2dQueueDescriptor& descriptor,
Sadik Armagane9444752020-12-02 11:28:58 +000099 const WorkloadInfo& info,
100 const arm_compute::CLCompileContext& clCompileContext)
Teresa Charlin588cbdf2022-01-19 15:55:37 +0000101 : ClBaseWorkload<DepthwiseConvolution2dQueueDescriptor>(descriptor, info)
telsoa01c577f2c2018-08-31 09:22:23 +0100102{
Keith Davisbcd860a2021-08-05 14:20:33 +0100103 // Add details for profiling output
104 WorkloadInfo detailsInfo;
105
106 detailsInfo.m_InputTensorInfos = info.m_InputTensorInfos;
107 detailsInfo.m_OutputTensorInfos = info.m_OutputTensorInfos;
108 detailsInfo.m_WeightsTensorInfo = armnn::Optional<armnn::TensorInfo>(descriptor.m_Weight->GetTensorInfo());
109 if (descriptor.m_Parameters.m_BiasEnabled)
110 {
111 detailsInfo.m_BiasTensorInfo = armnn::Optional<armnn::TensorInfo>(descriptor.m_Bias->GetTensorInfo());
112 }
113
114 // Report Profiling Details
115 ARMNN_REPORT_PROFILING_WORKLOAD_DESC("ClDepthwiseConvolutionWorkload_Construct",
116 descriptor.m_Parameters,
117 detailsInfo,
Cathal Corbett4b19d222022-05-11 20:12:17 +0100118 GetGuid());
Keith Davisbcd860a2021-08-05 14:20:33 +0100119
Cathal Corbett4b19d222022-05-11 20:12:17 +0100120 m_Data.ValidateInputsOutputs("ClDepthwiseConv2dWorkload", descriptor.m_Parameters.GetNumInputs(), 1);
Matteo Martincigh747ef822018-12-18 09:26:39 +0000121
Cathal Corbett4b19d222022-05-11 20:12:17 +0100122 arm_compute::ICLTensor& input = PolymorphicDowncast<IClTensorHandle*>(m_Data.m_Inputs[0])->GetTensor();
123 arm_compute::ICLTensor& output = PolymorphicDowncast<IClTensorHandle*>(m_Data.m_Outputs[0])->GetTensor();
124 arm_compute::ICLTensor& weights = PolymorphicDowncast<IClTensorHandle*>(m_Data.m_Inputs[1])->GetTensor();
125 arm_compute::ITensorInfo* weightsInfo = weights.info();
126 arm_compute::ITensorInfo* inputInfo = input.info();
127 auto weightsShape = weightsInfo->tensor_shape();
128 auto inputShape = inputInfo->tensor_shape();
telsoa01c577f2c2018-08-31 09:22:23 +0100129
Cathal Corbett4b19d222022-05-11 20:12:17 +0100130 // The PermuteDepthwiseConv2dWeights backend optimization has been performed,
131 // converting weights to have the same data layout as input.
132 unsigned int depthMultiplier =
133 ComputeDepthwiseConv2dDepthMultiplier(m_Data.m_Parameters.m_DataLayout, weightsShape, inputShape);
134
135 arm_compute::ICLTensor* bias = nullptr;
telsoa01c577f2c2018-08-31 09:22:23 +0100136 if (m_Data.m_Parameters.m_BiasEnabled)
137 {
Cathal Corbett4b19d222022-05-11 20:12:17 +0100138 bias = &PolymorphicDowncast<IClTensorHandle*>(m_Data.m_Inputs[2])->GetTensor();
telsoa01c577f2c2018-08-31 09:22:23 +0100139 }
140
Pablo Tellof0bd6832019-04-26 17:58:13 +0100141 const arm_compute::Size2D aclDilationInfo = BuildArmComputeSize2D(
142 m_Data.m_Parameters.m_DilationX,
143 m_Data.m_Parameters.m_DilationY);
144
Nikhil Rajcec6b652018-10-12 13:51:57 +0100145 arm_compute::DataLayout aclDataLayout = ConvertDataLayout(m_Data.m_Parameters.m_DataLayout);
146 input.info()->set_data_layout(aclDataLayout);
Cathal Corbett4b19d222022-05-11 20:12:17 +0100147 weights.info()->set_data_layout(aclDataLayout);
Nikhil Rajcec6b652018-10-12 13:51:57 +0100148 output.info()->set_data_layout(aclDataLayout);
149
Aron Virginas-Tar6f3785d2019-07-22 15:30:22 +0100150 arm_compute::PadStrideInfo padStrideInfo = BuildArmComputePadStrideInfo(m_Data.m_Parameters);
Pablo Tellof0bd6832019-04-26 17:58:13 +0100151
Mike Kelly07810fc2020-11-12 10:58:48 +0000152 const arm_compute::ActivationLayerInfo activationInfo = ConvertAdditionalInfoToAclActivationLayerInfo(descriptor);
153
Aron Virginas-Tarf4c502f2019-11-14 16:21:38 +0000154 m_DepthwiseConvolutionLayer = std::make_unique<arm_compute::CLDepthwiseConvolutionLayer>();
telsoa01c577f2c2018-08-31 09:22:23 +0100155
Kevin May9f6862d2021-10-22 15:42:28 +0100156 {
157 ARMNN_SCOPED_PROFILING_EVENT(Compute::Undefined, "ClDepthwiseConvolutionWorkload_configure");
158 static_cast<arm_compute::CLDepthwiseConvolutionLayer*>(m_DepthwiseConvolutionLayer.get())->configure(
159 clCompileContext,
160 &input,
Cathal Corbett4b19d222022-05-11 20:12:17 +0100161 &weights,
162 bias,
Kevin May9f6862d2021-10-22 15:42:28 +0100163 &output,
164 padStrideInfo,
165 depthMultiplier,
166 activationInfo,
167 aclDilationInfo);
168 }
Narumol Prangnawaratac2770a2020-04-01 16:51:23 +0100169 ARMNN_ASSERT(m_DepthwiseConvolutionLayer);
telsoa01c577f2c2018-08-31 09:22:23 +0100170}
171
Matthew Benthamd8777392018-10-08 09:38:55 +0100172void ClDepthwiseConvolutionWorkload::Execute() const
173{
Cathal Corbett4b19d222022-05-11 20:12:17 +0100174 ARMNN_SCOPED_PROFILING_EVENT_CL_GUID("ClDepthwiseConvolutionWorkload_Execute", 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