blob: ad509076b4594021a3d1c9f92f5a03b746ccc755 [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
James Conroy1f58f032021-04-27 17:13:27 +010017#include <backendsCommon/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{
Matteo Martincigh747ef822018-12-18 09:26:39 +000036 const arm_compute::TensorInfo aclInputInfo = BuildArmComputeTensorInfo(input, descriptor.m_DataLayout);
37 const arm_compute::TensorInfo aclOutputInfo = BuildArmComputeTensorInfo(output, descriptor.m_DataLayout);
38
39 // ArmNN's weight format is [ M, I, H, W ]
40 const unsigned int aclDepthMultiplier = weights.GetShape()[0];
41
42 // Convert the weight format from ArmNN's [ M, I, H, W ] (does NOT depend on the data layout) to either
43 // [ 1, H, W, I * M ] (if NHWC) or [ 1, I * M, H, W ] (if NCHW), as required by the compute library
44 TensorInfo weightsPermuted = ConvertWeightTensorInfoFromArmnnToAcl(weights, descriptor.m_DataLayout);
45
46 // Convert the weights into the compute library format
47 const arm_compute::TensorInfo aclWeightsInfo = BuildArmComputeTensorInfo(weightsPermuted, descriptor.m_DataLayout);
Nattapat Chaimanowong77140882018-10-17 11:12:19 +010048
49 arm_compute::TensorInfo aclBiasesInfo;
50 arm_compute::TensorInfo *optionalAclBiasesInfo = nullptr;
51
52 if (descriptor.m_BiasEnabled)
53 {
Narumol Prangnawaratac2770a2020-04-01 16:51:23 +010054 ARMNN_ASSERT(biases.has_value());
Nattapat Chaimanowong77140882018-10-17 11:12:19 +010055
56 aclBiasesInfo = BuildArmComputeTensorInfo(biases.value(), descriptor.m_DataLayout);
57 optionalAclBiasesInfo = &aclBiasesInfo;
58 }
59
Pablo Tellof0bd6832019-04-26 17:58:13 +010060 arm_compute::PadStrideInfo aclPadStrideInfo = BuildArmComputePadStrideInfo(descriptor);
61 const arm_compute::Size2D aclDilationInfo = BuildArmComputeSize2D(
62 descriptor.m_DilationX,descriptor.m_DilationY);
Nattapat Chaimanowong77140882018-10-17 11:12:19 +010063
Mike Kelly07810fc2020-11-12 10:58:48 +000064 const arm_compute::ActivationLayerInfo activationInfo = ConvertActivationDescriptorToAclActivationLayerInfo(
65 activationDescriptor);
66
Nattapat Chaimanowong77140882018-10-17 11:12:19 +010067 return arm_compute::NEDepthwiseConvolutionLayer::validate(&aclInputInfo,
68 &aclWeightsInfo,
69 optionalAclBiasesInfo,
70 &aclOutputInfo,
71 aclPadStrideInfo,
Pablo Tellof0bd6832019-04-26 17:58:13 +010072 aclDepthMultiplier,
Mike Kelly07810fc2020-11-12 10:58:48 +000073 activationInfo,
Pablo Tellof0bd6832019-04-26 17:58:13 +010074 aclDilationInfo);
Nattapat Chaimanowong77140882018-10-17 11:12:19 +010075}
76
77NeonDepthwiseConvolutionWorkload::NeonDepthwiseConvolutionWorkload(
telsoa014fcda012018-03-09 14:13:49 +000078 const DepthwiseConvolution2dQueueDescriptor& descriptor,
79 const WorkloadInfo& info)
Nattapat Chaimanowong77140882018-10-17 11:12:19 +010080 : BaseWorkload<DepthwiseConvolution2dQueueDescriptor>(descriptor, info)
telsoa014fcda012018-03-09 14:13:49 +000081{
Matteo Martincigh747ef822018-12-18 09:26:39 +000082 // ArmNN's weight format is [ M, I, H, W ]
83 auto& weightInfo = m_Data.m_Weight->GetTensorInfo();
telsoa014fcda012018-03-09 14:13:49 +000084
Matteo Martincigh747ef822018-12-18 09:26:39 +000085 // Allocate a buffer for the swizzling of the weight tensor
86 std::unique_ptr<unsigned char[]> permuteBuffer(new unsigned char[m_Data.m_Weight->GetTensorInfo().GetNumBytes()]);
87
88 // Convert the weight format from ArmNN's [ M, I, H, W ] (does NOT depend on the data layout) to either
89 // [ 1, H, W, I * M ] (if NHWC) or [ 1, I * M, H, W ] (if NCHW), as required by the compute library
90 ConstTensor weightPermuted = ConvertWeightTensorFromArmnnToAcl(m_Data.m_Weight,
91 m_Data.m_Parameters.m_DataLayout,
92 permuteBuffer.get());
93
94 // Convert the weights into the compute library format
telsoa01c577f2c2018-08-31 09:22:23 +010095 m_KernelTensor = std::make_unique<arm_compute::Tensor>();
Matteo Martincigh747ef822018-12-18 09:26:39 +000096 BuildArmComputeTensor(*m_KernelTensor, weightPermuted.GetInfo(), m_Data.m_Parameters.m_DataLayout);
Mohamed Nour Abouelseoud7e7261e2018-11-27 17:35:35 +000097
telsoa014fcda012018-03-09 14:13:49 +000098 if (m_Data.m_Parameters.m_BiasEnabled)
99 {
telsoa01c577f2c2018-08-31 09:22:23 +0100100 m_BiasTensor = std::make_unique<arm_compute::Tensor>();
Nikhil Rajcec6b652018-10-12 13:51:57 +0100101 BuildArmComputeTensor(*m_BiasTensor, m_Data.m_Bias->GetTensorInfo(), m_Data.m_Parameters.m_DataLayout);
telsoa014fcda012018-03-09 14:13:49 +0000102 }
103
Pablo Tellof0bd6832019-04-26 17:58:13 +0100104 const arm_compute::Size2D aclDilationInfo = BuildArmComputeSize2D(
105 m_Data.m_Parameters.m_DilationX, m_Data.m_Parameters.m_DilationY);
106
Nattapat Chaimanowong77140882018-10-17 11:12:19 +0100107 m_Data.ValidateInputsOutputs("NeonDepthwiseConvolutionWorkload", 1, 1);
telsoa014fcda012018-03-09 14:13:49 +0000108
Derek Lambertic81855f2019-06-13 17:34:19 +0100109 IAclTensorHandle* inputTensorHandle = static_cast<IAclTensorHandle*>(m_Data.m_Inputs[0]);
110 IAclTensorHandle* outputTensorHandle = static_cast<IAclTensorHandle*>(m_Data.m_Outputs[0]);
Matteo Martincigh747ef822018-12-18 09:26:39 +0000111
Mohamed Nour Abouelseoud7e7261e2018-11-27 17:35:35 +0000112 arm_compute::ITensor& input = inputTensorHandle->GetTensor();
113 arm_compute::ITensor& output = outputTensorHandle->GetTensor();
telsoa014fcda012018-03-09 14:13:49 +0000114
Nikhil Rajcec6b652018-10-12 13:51:57 +0100115 arm_compute::DataLayout aclDataLayout = ConvertDataLayout(m_Data.m_Parameters.m_DataLayout);
116 input.info()->set_data_layout(aclDataLayout);
117 output.info()->set_data_layout(aclDataLayout);
118
Bruno Goncalves22972f02019-04-26 21:03:24 -0300119 // Get the depth multiplier
Matteo Martincigh747ef822018-12-18 09:26:39 +0000120 const unsigned int depthMultiplier = weightInfo.GetShape()[0];
Mohamed Nour Abouelseoud7e7261e2018-11-27 17:35:35 +0000121
Aron Virginas-Tar6f3785d2019-07-22 15:30:22 +0100122 arm_compute::PadStrideInfo padStrideInfo = BuildArmComputePadStrideInfo(m_Data.m_Parameters);
123
Mike Kelly07810fc2020-11-12 10:58:48 +0000124 const arm_compute::ActivationLayerInfo activationInfo = ConvertAdditionalInfoToAclActivationLayerInfo(descriptor);
125
Aron Virginas-Tarf4c502f2019-11-14 16:21:38 +0000126 m_pDepthwiseConvolutionLayer = std::make_unique<arm_compute::NEDepthwiseConvolutionLayer>();
127 static_cast<arm_compute::NEDepthwiseConvolutionLayer*>(
128 m_pDepthwiseConvolutionLayer.get())->configure(&input,
Mike Kelly07810fc2020-11-12 10:58:48 +0000129 m_KernelTensor.get(),
130 m_BiasTensor.get(),
131 &output,
132 padStrideInfo,
133 depthMultiplier,
134 activationInfo,
135 aclDilationInfo);
telsoa014fcda012018-03-09 14:13:49 +0000136
Narumol Prangnawaratac2770a2020-04-01 16:51:23 +0100137 ARMNN_ASSERT(m_pDepthwiseConvolutionLayer);
telsoa014fcda012018-03-09 14:13:49 +0000138
James Conroy1f58f032021-04-27 17:13:27 +0100139 ScopedTensorHandle weightsPermutedHandle(weightPermuted);
Matteo Martincigh747ef822018-12-18 09:26:39 +0000140 InitializeArmComputeTensorData(*m_KernelTensor, &weightsPermutedHandle);
telsoa014fcda012018-03-09 14:13:49 +0000141
Mohamed Nour Abouelseoud7e7261e2018-11-27 17:35:35 +0000142 if (m_Data.m_Parameters.m_BiasEnabled)
telsoa014fcda012018-03-09 14:13:49 +0000143 {
Nattapat Chaimanowong177d8d22018-10-16 13:21:27 +0100144 InitializeArmComputeTensorData(*m_BiasTensor, m_Data.m_Bias);
telsoa014fcda012018-03-09 14:13:49 +0000145 }
telsoa01c577f2c2018-08-31 09:22:23 +0100146
147 m_pDepthwiseConvolutionLayer->prepare();
148 FreeUnusedTensors();
telsoa014fcda012018-03-09 14:13:49 +0000149}
150
Nattapat Chaimanowong77140882018-10-17 11:12:19 +0100151void NeonDepthwiseConvolutionWorkload::Execute() const
telsoa014fcda012018-03-09 14:13:49 +0000152{
Nattapat Chaimanowong77140882018-10-17 11:12:19 +0100153 ARMNN_SCOPED_PROFILING_EVENT_NEON("NeonDepthwiseConvolutionWorkload_Execute");
Narumol Prangnawaratac2770a2020-04-01 16:51:23 +0100154 ARMNN_ASSERT(m_pDepthwiseConvolutionLayer);
telsoa014fcda012018-03-09 14:13:49 +0000155
156 m_pDepthwiseConvolutionLayer->run();
157}
158
Nattapat Chaimanowong77140882018-10-17 11:12:19 +0100159void NeonDepthwiseConvolutionWorkload::FreeUnusedTensors()
telsoa01c577f2c2018-08-31 09:22:23 +0100160{
161 FreeTensorIfUnused(m_KernelTensor);
162 FreeTensorIfUnused(m_BiasTensor);
163}
164
telsoa014fcda012018-03-09 14:13:49 +0000165} //namespace armnn