blob: cdb336869988183c58569aa99d48efbf9d5e4f1d [file] [log] [blame]
telsoa014fcda012018-03-09 14:13:49 +00001//
2// Copyright © 2017 Arm Ltd. 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{
Keith Davis2d0679f2021-08-05 11:35:00 +010036 const arm_compute::TensorInfo aclInputInfo = BuildArmComputeTensorInfo(input, descriptor.m_DataLayout);
Matteo Martincigh747ef822018-12-18 09:26:39 +000037 const arm_compute::TensorInfo aclOutputInfo = BuildArmComputeTensorInfo(output, descriptor.m_DataLayout);
38
Jan Eilers53ef7952021-06-02 12:01:25 +010039 // ArmNN's weight format is usually [ M, I, H, W ] but for depthwise its [ 1, H, W, I*M]
40 // Permute to [ 1, I * M, H, W ] (if NCHW), as required by the compute library
41 unsigned int aclDepthMultiplier;
42 TensorInfo weightsPermuted;
Keith Davis2d0679f2021-08-05 11:35:00 +010043 std::tie(weightsPermuted, aclDepthMultiplier) = Convert1HWOTensorInfoToAcl(weights, input, descriptor.m_DataLayout);
Matteo Martincigh747ef822018-12-18 09:26:39 +000044
45 // Convert the weights into the compute library format
46 const arm_compute::TensorInfo aclWeightsInfo = BuildArmComputeTensorInfo(weightsPermuted, descriptor.m_DataLayout);
Nattapat Chaimanowong77140882018-10-17 11:12:19 +010047
48 arm_compute::TensorInfo aclBiasesInfo;
Keith Davis2d0679f2021-08-05 11:35:00 +010049 arm_compute::TensorInfo* optionalAclBiasesInfo = nullptr;
Nattapat Chaimanowong77140882018-10-17 11:12:19 +010050
51 if (descriptor.m_BiasEnabled)
52 {
Narumol Prangnawaratac2770a2020-04-01 16:51:23 +010053 ARMNN_ASSERT(biases.has_value());
Nattapat Chaimanowong77140882018-10-17 11:12:19 +010054
55 aclBiasesInfo = BuildArmComputeTensorInfo(biases.value(), descriptor.m_DataLayout);
56 optionalAclBiasesInfo = &aclBiasesInfo;
57 }
58
Pablo Tellof0bd6832019-04-26 17:58:13 +010059 arm_compute::PadStrideInfo aclPadStrideInfo = BuildArmComputePadStrideInfo(descriptor);
60 const arm_compute::Size2D aclDilationInfo = BuildArmComputeSize2D(
Keith Davis2d0679f2021-08-05 11:35:00 +010061 descriptor.m_DilationX, descriptor.m_DilationY);
Nattapat Chaimanowong77140882018-10-17 11:12:19 +010062
Mike Kelly07810fc2020-11-12 10:58:48 +000063 const arm_compute::ActivationLayerInfo activationInfo = ConvertActivationDescriptorToAclActivationLayerInfo(
Keith Davis2d0679f2021-08-05 11:35:00 +010064 activationDescriptor);
Mike Kelly07810fc2020-11-12 10:58:48 +000065
Nattapat Chaimanowong77140882018-10-17 11:12:19 +010066 return arm_compute::NEDepthwiseConvolutionLayer::validate(&aclInputInfo,
67 &aclWeightsInfo,
68 optionalAclBiasesInfo,
69 &aclOutputInfo,
70 aclPadStrideInfo,
Pablo Tellof0bd6832019-04-26 17:58:13 +010071 aclDepthMultiplier,
Mike Kelly07810fc2020-11-12 10:58:48 +000072 activationInfo,
Pablo Tellof0bd6832019-04-26 17:58:13 +010073 aclDilationInfo);
Nattapat Chaimanowong77140882018-10-17 11:12:19 +010074}
75
76NeonDepthwiseConvolutionWorkload::NeonDepthwiseConvolutionWorkload(
telsoa014fcda012018-03-09 14:13:49 +000077 const DepthwiseConvolution2dQueueDescriptor& descriptor,
78 const WorkloadInfo& info)
Nattapat Chaimanowong77140882018-10-17 11:12:19 +010079 : BaseWorkload<DepthwiseConvolution2dQueueDescriptor>(descriptor, info)
telsoa014fcda012018-03-09 14:13:49 +000080{
Jan Eilers53ef7952021-06-02 12:01:25 +010081 // ArmNN's weight format for depthwise is [ 1, H, W, I*M ]
Matteo Martincigh747ef822018-12-18 09:26:39 +000082 auto& weightInfo = m_Data.m_Weight->GetTensorInfo();
telsoa014fcda012018-03-09 14:13:49 +000083
Jan Eilers53ef7952021-06-02 12:01:25 +010084 ConstTensor weightsPermuted;
85 unsigned int depthMultiplier;
86 std::unique_ptr<unsigned char[]> permuteBuffer(new unsigned char[weightInfo.GetNumBytes()]);
87 std::tie(weightsPermuted, depthMultiplier) = Convert1HWOTensorToAcl(m_Data.m_Weight,
Keith Davis2d0679f2021-08-05 11:35:00 +010088 info.m_InputTensorInfos[0],
89 m_Data.m_Parameters.m_DataLayout,
90 permuteBuffer.get());
Matteo Martincigh747ef822018-12-18 09:26:39 +000091
92 // Convert the weights into the compute library format
telsoa01c577f2c2018-08-31 09:22:23 +010093 m_KernelTensor = std::make_unique<arm_compute::Tensor>();
Jan Eilers53ef7952021-06-02 12:01:25 +010094 BuildArmComputeTensor(*m_KernelTensor, weightsPermuted.GetInfo(), m_Data.m_Parameters.m_DataLayout);
Mohamed Nour Abouelseoud7e7261e2018-11-27 17:35:35 +000095
telsoa014fcda012018-03-09 14:13:49 +000096 if (m_Data.m_Parameters.m_BiasEnabled)
97 {
telsoa01c577f2c2018-08-31 09:22:23 +010098 m_BiasTensor = std::make_unique<arm_compute::Tensor>();
Nikhil Rajcec6b652018-10-12 13:51:57 +010099 BuildArmComputeTensor(*m_BiasTensor, m_Data.m_Bias->GetTensorInfo(), m_Data.m_Parameters.m_DataLayout);
telsoa014fcda012018-03-09 14:13:49 +0000100 }
101
Pablo Tellof0bd6832019-04-26 17:58:13 +0100102 const arm_compute::Size2D aclDilationInfo = BuildArmComputeSize2D(
Keith Davis2d0679f2021-08-05 11:35:00 +0100103 m_Data.m_Parameters.m_DilationX, m_Data.m_Parameters.m_DilationY);
Pablo Tellof0bd6832019-04-26 17:58:13 +0100104
Nattapat Chaimanowong77140882018-10-17 11:12:19 +0100105 m_Data.ValidateInputsOutputs("NeonDepthwiseConvolutionWorkload", 1, 1);
telsoa014fcda012018-03-09 14:13:49 +0000106
Keith Davis2d0679f2021-08-05 11:35:00 +0100107 IAclTensorHandle* inputTensorHandle = static_cast<IAclTensorHandle*>(m_Data.m_Inputs[0]);
Derek Lambertic81855f2019-06-13 17:34:19 +0100108 IAclTensorHandle* outputTensorHandle = static_cast<IAclTensorHandle*>(m_Data.m_Outputs[0]);
Matteo Martincigh747ef822018-12-18 09:26:39 +0000109
Keith Davis2d0679f2021-08-05 11:35:00 +0100110 arm_compute::ITensor& input = inputTensorHandle->GetTensor();
Mohamed Nour Abouelseoud7e7261e2018-11-27 17:35:35 +0000111 arm_compute::ITensor& output = outputTensorHandle->GetTensor();
telsoa014fcda012018-03-09 14:13:49 +0000112
Nikhil Rajcec6b652018-10-12 13:51:57 +0100113 arm_compute::DataLayout aclDataLayout = ConvertDataLayout(m_Data.m_Parameters.m_DataLayout);
114 input.info()->set_data_layout(aclDataLayout);
115 output.info()->set_data_layout(aclDataLayout);
116
Aron Virginas-Tar6f3785d2019-07-22 15:30:22 +0100117 arm_compute::PadStrideInfo padStrideInfo = BuildArmComputePadStrideInfo(m_Data.m_Parameters);
118
Mike Kelly07810fc2020-11-12 10:58:48 +0000119 const arm_compute::ActivationLayerInfo activationInfo = ConvertAdditionalInfoToAclActivationLayerInfo(descriptor);
120
Aron Virginas-Tarf4c502f2019-11-14 16:21:38 +0000121 m_pDepthwiseConvolutionLayer = std::make_unique<arm_compute::NEDepthwiseConvolutionLayer>();
122 static_cast<arm_compute::NEDepthwiseConvolutionLayer*>(
123 m_pDepthwiseConvolutionLayer.get())->configure(&input,
Mike Kelly07810fc2020-11-12 10:58:48 +0000124 m_KernelTensor.get(),
125 m_BiasTensor.get(),
126 &output,
127 padStrideInfo,
128 depthMultiplier,
129 activationInfo,
130 aclDilationInfo);
telsoa014fcda012018-03-09 14:13:49 +0000131
Keith Davis2d0679f2021-08-05 11:35:00 +0100132 // Add details for profiling output
133 WorkloadInfo detailsInfo;
134
135 detailsInfo.m_InputTensorInfos = info.m_InputTensorInfos;
136 detailsInfo.m_OutputTensorInfos = info.m_OutputTensorInfos;
137 detailsInfo.m_WeightsTensorInfo = armnn::Optional<armnn::TensorInfo>(descriptor.m_Weight->GetTensorInfo());
138 if (descriptor.m_Parameters.m_BiasEnabled)
139 {
140 detailsInfo.m_BiasTensorInfo = armnn::Optional<armnn::TensorInfo>(descriptor.m_Bias->GetTensorInfo());
141 }
142
143 // Report Profiling Details
144 ARMNN_REPORT_PROFILING_WORKLOAD_DESC("NeonDepthwiseConvolution2dWorkload_Construct",
145 descriptor.m_Parameters,
146 detailsInfo,
147 this->GetGuid());
148
Narumol Prangnawaratac2770a2020-04-01 16:51:23 +0100149 ARMNN_ASSERT(m_pDepthwiseConvolutionLayer);
telsoa014fcda012018-03-09 14:13:49 +0000150
Jan Eilers53ef7952021-06-02 12:01:25 +0100151 ScopedTensorHandle weightsPermutedHandle(weightsPermuted);
Matteo Martincigh747ef822018-12-18 09:26:39 +0000152 InitializeArmComputeTensorData(*m_KernelTensor, &weightsPermutedHandle);
telsoa014fcda012018-03-09 14:13:49 +0000153
Mohamed Nour Abouelseoud7e7261e2018-11-27 17:35:35 +0000154 if (m_Data.m_Parameters.m_BiasEnabled)
telsoa014fcda012018-03-09 14:13:49 +0000155 {
Nattapat Chaimanowong177d8d22018-10-16 13:21:27 +0100156 InitializeArmComputeTensorData(*m_BiasTensor, m_Data.m_Bias);
telsoa014fcda012018-03-09 14:13:49 +0000157 }
telsoa01c577f2c2018-08-31 09:22:23 +0100158
159 m_pDepthwiseConvolutionLayer->prepare();
160 FreeUnusedTensors();
telsoa014fcda012018-03-09 14:13:49 +0000161}
162
Nattapat Chaimanowong77140882018-10-17 11:12:19 +0100163void NeonDepthwiseConvolutionWorkload::Execute() const
telsoa014fcda012018-03-09 14:13:49 +0000164{
Keith Davis2d0679f2021-08-05 11:35:00 +0100165 ARMNN_SCOPED_PROFILING_EVENT_NEON_GUID("NeonDepthwiseConvolutionWorkload_Execute", this->GetGuid());
Narumol Prangnawaratac2770a2020-04-01 16:51:23 +0100166 ARMNN_ASSERT(m_pDepthwiseConvolutionLayer);
telsoa014fcda012018-03-09 14:13:49 +0000167
168 m_pDepthwiseConvolutionLayer->run();
169}
170
Nattapat Chaimanowong77140882018-10-17 11:12:19 +0100171void NeonDepthwiseConvolutionWorkload::FreeUnusedTensors()
telsoa01c577f2c2018-08-31 09:22:23 +0100172{
173 FreeTensorIfUnused(m_KernelTensor);
174 FreeTensorIfUnused(m_BiasTensor);
175}
176
telsoa014fcda012018-03-09 14:13:49 +0000177} //namespace armnn