blob: 4c7adef576972f4622fe67aa7cb62bcd4d78c478 [file] [log] [blame]
telsoa014fcda012018-03-09 14:13:49 +00001//
Mike Kelly7cbe7812023-07-25 17:37:33 +01002// Copyright © 2017-2023 Arm Ltd and Contributors. All rights reserved.
David Beckecb56cd2018-09-05 12:52:57 +01003// SPDX-License-Identifier: MIT
telsoa014fcda012018-03-09 14:13:49 +00004//
5
Nattapat Chaimanowong77140882018-10-17 11:12:19 +01006#include "NeonDepthwiseConvolutionWorkload.hpp"
7
Matthew Benthamd80a7122019-01-08 17:52:37 +00008#include "NeonWorkloadUtils.hpp"
9
Matteo Martincighe011d202019-11-28 11:35:47 +000010#include <armnnUtils/DataLayoutIndexed.hpp>
11
Aron Virginas-Tarc9cc8042018-11-01 16:15:57 +000012#include <aclCommon/ArmComputeTensorUtils.hpp>
Mike Kelly07810fc2020-11-12 10:58:48 +000013#include <aclCommon/ArmComputeUtils.hpp>
Matteo Martincighe011d202019-11-28 11:35:47 +000014
Aron Virginas-Tarc9cc8042018-11-01 16:15:57 +000015#include <neon/NeonLayerSupport.hpp>
Matteo Martincighe011d202019-11-28 11:35:47 +000016
Colm Donelan0c479742021-12-10 12:43:54 +000017#include <armnn/backends/TensorHandle.hpp>
Matteo Martincigh747ef822018-12-18 09:26:39 +000018#include <backendsCommon/WorkloadUtils.hpp>
telsoa014fcda012018-03-09 14:13:49 +000019
Matthew Benthamd80a7122019-01-08 17:52:37 +000020#include <arm_compute/runtime/NEON/functions/NEDepthwiseConvolutionLayer.h>
21
22using namespace armnnUtils;
23
telsoa014fcda012018-03-09 14:13:49 +000024namespace armnn
25{
Nattapat Chaimanowong77140882018-10-17 11:12:19 +010026
telsoa014fcda012018-03-09 14:13:49 +000027using namespace armcomputetensorutils;
28
Nattapat Chaimanowong77140882018-10-17 11:12:19 +010029arm_compute::Status NeonDepthwiseConvolutionWorkloadValidate(const TensorInfo& input,
Matteo Martincigh747ef822018-12-18 09:26:39 +000030 const TensorInfo& output,
31 const DepthwiseConvolution2dDescriptor& descriptor,
32 const TensorInfo& weights,
Mike Kelly07810fc2020-11-12 10:58:48 +000033 const Optional<TensorInfo>& biases,
34 const ActivationDescriptor* activationDescriptor)
Nattapat Chaimanowong77140882018-10-17 11:12:19 +010035{
Cathal Corbett4b19d222022-05-11 20:12:17 +010036 const arm_compute::TensorInfo aclInputInfo = BuildArmComputeTensorInfo(input, descriptor.m_DataLayout);
37 const arm_compute::TensorInfo aclOutputInfo = BuildArmComputeTensorInfo(output, descriptor.m_DataLayout);
Matteo Martincigh747ef822018-12-18 09:26:39 +000038
Cathal Corbett4b19d222022-05-11 20:12:17 +010039 // ArmNN format for weights for depthwise is [1, H, W, C] independently of the input/output layout
40 //
41 // ACL format for weights for depthwise is:
42 // - [1, H, W, C] for [N, H, W, C] input/output layout (matches with ArmNN)
43 // - [1, C, H, W] for [N, C, H, W] input/output layout
44 //
45 // Therefore ArmNN weights have to be permuted when input/output layout is [N, C, H, W] to pass them to ACL.
46 // The PermuteDepthwiseConv2dWeights backend optimization takes care of this, but it has not been performed yet,
47 // so we do the permute here for the TensorInfo weights.
Jan Eilers53ef7952021-06-02 12:01:25 +010048 unsigned int aclDepthMultiplier;
49 TensorInfo weightsPermuted;
Keith Davis2d0679f2021-08-05 11:35:00 +010050 std::tie(weightsPermuted, aclDepthMultiplier) = Convert1HWOTensorInfoToAcl(weights, input, descriptor.m_DataLayout);
Matteo Martincigh747ef822018-12-18 09:26:39 +000051
52 // Convert the weights into the compute library format
Cathal Corbett4452baf2022-05-13 09:55:59 +010053 arm_compute::TensorInfo aclWeightsInfo = BuildArmComputeTensorInfo(weightsPermuted, descriptor.m_DataLayout);
54 aclWeightsInfo.set_are_values_constant(weights.IsConstant());
Nattapat Chaimanowong77140882018-10-17 11:12:19 +010055
56 arm_compute::TensorInfo aclBiasesInfo;
Keith Davis2d0679f2021-08-05 11:35:00 +010057 arm_compute::TensorInfo* optionalAclBiasesInfo = nullptr;
Nattapat Chaimanowong77140882018-10-17 11:12:19 +010058 if (descriptor.m_BiasEnabled)
59 {
Teresa Charlin5b701842023-05-16 12:27:28 +010060 if(!biases.has_value())
TeresaARMacedd852023-05-11 15:16:39 +000061 {
62 return arm_compute::Status{arm_compute::ErrorCode::RUNTIME_ERROR,
Teresa Charlin5b701842023-05-16 12:27:28 +010063 "ArmNN NeonDepthwiseConvolutionWorkload has empty bias value."};
TeresaARMacedd852023-05-11 15:16:39 +000064 }
Colm Donelan47016c02023-07-20 10:08:03 +010065 // There's currently a problem with non const bias, so we'll explicitly block it here.
66 if (!biases.value().IsConstant())
67 {
68 return arm_compute::Status{arm_compute::ErrorCode::RUNTIME_ERROR,
69 "ArmNN NeonDepthwiseConvolutionWorkload does not support non constant bias."};
70 }
Nattapat Chaimanowong77140882018-10-17 11:12:19 +010071 aclBiasesInfo = BuildArmComputeTensorInfo(biases.value(), descriptor.m_DataLayout);
Cathal Corbett4452baf2022-05-13 09:55:59 +010072 aclBiasesInfo.set_are_values_constant(biases.value().IsConstant());
Nattapat Chaimanowong77140882018-10-17 11:12:19 +010073 optionalAclBiasesInfo = &aclBiasesInfo;
74 }
75
Teresa Charlin5b701842023-05-16 12:27:28 +010076 const arm_compute::PadStrideInfo aclPadStrideInfo = BuildArmComputePadStrideInfo(descriptor);
77 const arm_compute::Size2D aclDilationInfo = BuildArmComputeSize2D(descriptor.m_DilationX,
78 descriptor.m_DilationY);
Nattapat Chaimanowong77140882018-10-17 11:12:19 +010079
Mike Kelly07810fc2020-11-12 10:58:48 +000080 const arm_compute::ActivationLayerInfo activationInfo = ConvertActivationDescriptorToAclActivationLayerInfo(
Keith Davis2d0679f2021-08-05 11:35:00 +010081 activationDescriptor);
Mike Kelly07810fc2020-11-12 10:58:48 +000082
Nattapat Chaimanowong77140882018-10-17 11:12:19 +010083 return arm_compute::NEDepthwiseConvolutionLayer::validate(&aclInputInfo,
84 &aclWeightsInfo,
85 optionalAclBiasesInfo,
86 &aclOutputInfo,
87 aclPadStrideInfo,
Pablo Tellof0bd6832019-04-26 17:58:13 +010088 aclDepthMultiplier,
Mike Kelly07810fc2020-11-12 10:58:48 +000089 activationInfo,
Pablo Tellof0bd6832019-04-26 17:58:13 +010090 aclDilationInfo);
Nattapat Chaimanowong77140882018-10-17 11:12:19 +010091}
92
93NeonDepthwiseConvolutionWorkload::NeonDepthwiseConvolutionWorkload(
telsoa014fcda012018-03-09 14:13:49 +000094 const DepthwiseConvolution2dQueueDescriptor& descriptor,
95 const WorkloadInfo& info)
Teresa Charlin588cbdf2022-01-19 15:55:37 +000096 : NeonBaseWorkload<DepthwiseConvolution2dQueueDescriptor>(descriptor, info)
telsoa014fcda012018-03-09 14:13:49 +000097{
Cathal Corbett4b19d222022-05-11 20:12:17 +010098 arm_compute::ITensor& input = PolymorphicDowncast<IAclTensorHandle*>(m_Data.m_Inputs[0])->GetTensor();
99 arm_compute::ITensor& output = PolymorphicDowncast<IAclTensorHandle*>(m_Data.m_Outputs[0])->GetTensor();
100 arm_compute::ITensor& weights = PolymorphicDowncast<IAclTensorHandle*>(m_Data.m_Inputs[1])->GetTensor();
Teresa Charlin6fba2942023-04-18 12:48:46 +0100101 weights.info()->set_are_values_constant(info.m_InputTensorInfos[1].IsConstant());
Teresa Charlin5b701842023-05-16 12:27:28 +0100102 arm_compute::ITensor* biasesPtr = nullptr;
telsoa014fcda012018-03-09 14:13:49 +0000103 if (m_Data.m_Parameters.m_BiasEnabled)
104 {
Cathal Corbett4b19d222022-05-11 20:12:17 +0100105 biasesPtr = &PolymorphicDowncast<IAclTensorHandle *>(m_Data.m_Inputs[2])->GetTensor();
Teresa Charlin6fba2942023-04-18 12:48:46 +0100106 biasesPtr->info()->set_are_values_constant(info.m_InputTensorInfos[2].IsConstant());
Colm Donelan47016c02023-07-20 10:08:03 +0100107 // We assume here that NeonDepthwiseConvolutionWorkloadValidate has been called before the constructor.
108 ARMNN_ASSERT(info.m_InputTensorInfos[2].IsConstant() == true);
telsoa014fcda012018-03-09 14:13:49 +0000109 }
110
Teresa Charlin5b701842023-05-16 12:27:28 +0100111 arm_compute::TensorShape weightsShape = weights.info()->tensor_shape();
112 arm_compute::TensorShape inputShape = input.info()->tensor_shape();
Cathal Corbett4b19d222022-05-11 20:12:17 +0100113
114 // The PermuteDepthwiseConv2dWeights backend optimization has been performed,
115 // converting weights to have the same data layout as input.
116 unsigned int depthMultiplier =
117 ComputeDepthwiseConv2dDepthMultiplier(m_Data.m_Parameters.m_DataLayout, weightsShape, inputShape);
118
Teresa Charlin5b701842023-05-16 12:27:28 +0100119 const arm_compute::Size2D aclDilationInfo = BuildArmComputeSize2D(m_Data.m_Parameters.m_DilationX,
120 m_Data.m_Parameters.m_DilationY);
Pablo Tellof0bd6832019-04-26 17:58:13 +0100121
Cathal Corbett4b19d222022-05-11 20:12:17 +0100122 uint32_t numInputs = m_Data.m_Parameters.m_BiasEnabled ? 3: 2;
123 m_Data.ValidateInputsOutputs("NeonDepthwiseConvolutionWorkload", numInputs, 1);
telsoa014fcda012018-03-09 14:13:49 +0000124
Nikhil Rajcec6b652018-10-12 13:51:57 +0100125 arm_compute::DataLayout aclDataLayout = ConvertDataLayout(m_Data.m_Parameters.m_DataLayout);
126 input.info()->set_data_layout(aclDataLayout);
Cathal Corbett4b19d222022-05-11 20:12:17 +0100127 weights.info()->set_data_layout(aclDataLayout);
Nikhil Rajcec6b652018-10-12 13:51:57 +0100128 output.info()->set_data_layout(aclDataLayout);
129
Teresa Charlin5b701842023-05-16 12:27:28 +0100130 const arm_compute::PadStrideInfo padStrideInfo = BuildArmComputePadStrideInfo(m_Data.m_Parameters);
Aron Virginas-Tar6f3785d2019-07-22 15:30:22 +0100131
Mike Kelly07810fc2020-11-12 10:58:48 +0000132 const arm_compute::ActivationLayerInfo activationInfo = ConvertAdditionalInfoToAclActivationLayerInfo(descriptor);
133
Aron Virginas-Tarf4c502f2019-11-14 16:21:38 +0000134 m_pDepthwiseConvolutionLayer = std::make_unique<arm_compute::NEDepthwiseConvolutionLayer>();
135 static_cast<arm_compute::NEDepthwiseConvolutionLayer*>(
136 m_pDepthwiseConvolutionLayer.get())->configure(&input,
Cathal Corbett4b19d222022-05-11 20:12:17 +0100137 &weights,
138 biasesPtr,
Mike Kelly07810fc2020-11-12 10:58:48 +0000139 &output,
140 padStrideInfo,
141 depthMultiplier,
142 activationInfo,
143 aclDilationInfo);
telsoa014fcda012018-03-09 14:13:49 +0000144
Keith Davis2d0679f2021-08-05 11:35:00 +0100145 // Add details for profiling output
146 WorkloadInfo detailsInfo;
147
148 detailsInfo.m_InputTensorInfos = info.m_InputTensorInfos;
149 detailsInfo.m_OutputTensorInfos = info.m_OutputTensorInfos;
Mike Kellyec67a0f2022-11-25 13:55:24 +0000150 detailsInfo.m_WeightsTensorInfo = armnn::Optional<armnn::TensorInfo>(info.m_InputTensorInfos[1]);
Keith Davis2d0679f2021-08-05 11:35:00 +0100151 if (descriptor.m_Parameters.m_BiasEnabled)
152 {
Mike Kellyec67a0f2022-11-25 13:55:24 +0000153 detailsInfo.m_BiasTensorInfo = armnn::Optional<armnn::TensorInfo>(info.m_InputTensorInfos[2]);
Keith Davis2d0679f2021-08-05 11:35:00 +0100154 }
155
156 // Report Profiling Details
157 ARMNN_REPORT_PROFILING_WORKLOAD_DESC("NeonDepthwiseConvolution2dWorkload_Construct",
158 descriptor.m_Parameters,
159 detailsInfo,
Cathal Corbett4b19d222022-05-11 20:12:17 +0100160 GetGuid());
Keith Davis2d0679f2021-08-05 11:35:00 +0100161
Narumol Prangnawaratac2770a2020-04-01 16:51:23 +0100162 ARMNN_ASSERT(m_pDepthwiseConvolutionLayer);
telsoa014fcda012018-03-09 14:13:49 +0000163
telsoa01c577f2c2018-08-31 09:22:23 +0100164 m_pDepthwiseConvolutionLayer->prepare();
telsoa014fcda012018-03-09 14:13:49 +0000165}
166
Nattapat Chaimanowong77140882018-10-17 11:12:19 +0100167void NeonDepthwiseConvolutionWorkload::Execute() const
telsoa014fcda012018-03-09 14:13:49 +0000168{
Mike Kelly7cbe7812023-07-25 17:37:33 +0100169 ARMNN_SCOPED_PROFILING_EVENT_NEON_NAME_GUID("NeonDepthwiseConvolutionWorkload_Execute");
Narumol Prangnawaratac2770a2020-04-01 16:51:23 +0100170 ARMNN_ASSERT(m_pDepthwiseConvolutionLayer);
telsoa014fcda012018-03-09 14:13:49 +0000171
172 m_pDepthwiseConvolutionLayer->run();
173}
174
telsoa014fcda012018-03-09 14:13:49 +0000175} //namespace armnn