blob: 655f0c9c3576beba8b0a31e254dd665f94c5a5f6 [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>
15#include <backendsCommon/CpuTensorHandle.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
36 // ArmNN's weight format is [ M, I, H, W ]
37 const unsigned int aclDepthMultiplier = weights.GetShape()[0];
38
39 // Convert the weight format from ArmNN's [ M, I, H, W ] (does NOT depend on the data layout) to either
40 // [ 1, H, W, I * M ] (if NHWC) or [ 1, I * M, H, W ] (if NCHW), as required by the compute library
41 TensorInfo weightsPermuted = ConvertWeightTensorInfoFromArmnnToAcl(weights, descriptor.m_DataLayout);
42
43 // Convert the weights into the compute library format
44 const arm_compute::TensorInfo aclWeightsInfo = BuildArmComputeTensorInfo(weightsPermuted, descriptor.m_DataLayout);
telsoa01c577f2c2018-08-31 09:22:23 +010045
46 arm_compute::TensorInfo aclBiasesInfo;
47 arm_compute::TensorInfo *optionalAclBiasesInfo = nullptr;
arovir01a6824102018-08-28 17:40:45 +010048
telsoa01c577f2c2018-08-31 09:22:23 +010049 if (descriptor.m_BiasEnabled)
50 {
Narumol Prangnawaratac2770a2020-04-01 16:51:23 +010051 ARMNN_ASSERT(biases.has_value());
arovir01a6824102018-08-28 17:40:45 +010052
David Beck5eec11d2018-10-04 15:43:17 +010053 aclBiasesInfo = BuildArmComputeTensorInfo(biases.value(), descriptor.m_DataLayout);
telsoa01c577f2c2018-08-31 09:22:23 +010054 optionalAclBiasesInfo = &aclBiasesInfo;
55 }
56
57 const arm_compute::PadStrideInfo aclPadStrideInfo = BuildArmComputePadStrideInfo(descriptor);
Pablo Tellof0bd6832019-04-26 17:58:13 +010058 const arm_compute::Size2D aclDilationInfo = BuildArmComputeSize2D(
59 descriptor.m_DilationX,
60 descriptor.m_DilationY);
telsoa01c577f2c2018-08-31 09:22:23 +010061
Mike Kelly07810fc2020-11-12 10:58:48 +000062 const arm_compute::ActivationLayerInfo activationInfo = ConvertActivationDescriptorToAclActivationLayerInfo(
63 activationDescriptor);
64
telsoa01c577f2c2018-08-31 09:22:23 +010065 return arm_compute::CLDepthwiseConvolutionLayer::validate(&aclInputInfo,
66 &aclWeightsInfo,
67 optionalAclBiasesInfo,
68 &aclOutputInfo,
69 aclPadStrideInfo,
Pablo Tellof0bd6832019-04-26 17:58:13 +010070 aclDepthMultiplier,
Mike Kelly07810fc2020-11-12 10:58:48 +000071 activationInfo,
Pablo Tellof0bd6832019-04-26 17:58:13 +010072 aclDilationInfo);
73
telsoa01c577f2c2018-08-31 09:22:23 +010074}
75
Matthew Benthamd8777392018-10-08 09:38:55 +010076ClDepthwiseConvolutionWorkload::ClDepthwiseConvolutionWorkload(
telsoa01c577f2c2018-08-31 09:22:23 +010077 const DepthwiseConvolution2dQueueDescriptor& descriptor,
Sadik Armagane9444752020-12-02 11:28:58 +000078 const WorkloadInfo& info,
79 const arm_compute::CLCompileContext& clCompileContext)
Matthew Benthamd8777392018-10-08 09:38:55 +010080 : BaseWorkload<DepthwiseConvolution2dQueueDescriptor>(descriptor, info)
telsoa01c577f2c2018-08-31 09:22:23 +010081{
Matteo Martincigh747ef822018-12-18 09:26:39 +000082 // Allocate a buffer for the swizzling of the weight tensor
83 std::unique_ptr<unsigned char[]> permuteBuffer(new unsigned char[m_Data.m_Weight->GetTensorInfo().GetNumBytes()]);
telsoa01c577f2c2018-08-31 09:22:23 +010084
Matteo Martincigh747ef822018-12-18 09:26:39 +000085 // Convert the weight format from ArmNN's [ M, I, H, W ] (does NOT depend on the data layout) to either
86 // [ 1, H, W, I * M ] (if NHWC) or [ 1, I * M, H, W ] (if NCHW), as required by the compute library
87 ConstTensor weightPermuted = ConvertWeightTensorFromArmnnToAcl(m_Data.m_Weight,
88 m_Data.m_Parameters.m_DataLayout,
89 permuteBuffer.get());
90
91 // Convert the weights into the compute library format
telsoa01c577f2c2018-08-31 09:22:23 +010092 m_KernelTensor = std::make_unique<arm_compute::CLTensor>();
Matteo Martincigh747ef822018-12-18 09:26:39 +000093 BuildArmComputeTensor(*m_KernelTensor, weightPermuted.GetInfo(), m_Data.m_Parameters.m_DataLayout);
telsoa01c577f2c2018-08-31 09:22:23 +010094
95 if (m_Data.m_Parameters.m_BiasEnabled)
96 {
97 m_BiasTensor = std::make_unique<arm_compute::CLTensor>();
Nikhil Rajcec6b652018-10-12 13:51:57 +010098 BuildArmComputeTensor(*m_BiasTensor, m_Data.m_Bias->GetTensorInfo(), m_Data.m_Parameters.m_DataLayout);
telsoa01c577f2c2018-08-31 09:22:23 +010099 }
100
Pablo Tellof0bd6832019-04-26 17:58:13 +0100101 const arm_compute::Size2D aclDilationInfo = BuildArmComputeSize2D(
102 m_Data.m_Parameters.m_DilationX,
103 m_Data.m_Parameters.m_DilationY);
104
105
Matthew Benthamd8777392018-10-08 09:38:55 +0100106 std::string name = std::string("ClDepthwiseConvolutionWorkload");
telsoa01c577f2c2018-08-31 09:22:23 +0100107 m_Data.ValidateInputsOutputs(name, 1, 1);
108
109 arm_compute::ICLTensor& input = static_cast<IClTensorHandle*>(m_Data.m_Inputs[0])->GetTensor();
110 arm_compute::ICLTensor& output = static_cast<IClTensorHandle*>(m_Data.m_Outputs[0])->GetTensor();
111
Nikhil Rajcec6b652018-10-12 13:51:57 +0100112 arm_compute::DataLayout aclDataLayout = ConvertDataLayout(m_Data.m_Parameters.m_DataLayout);
113 input.info()->set_data_layout(aclDataLayout);
114 output.info()->set_data_layout(aclDataLayout);
115
Matteo Martincigh747ef822018-12-18 09:26:39 +0000116 // ArmNN's weight format is [ M, I, H, W ]
117 auto& weightInfo = m_Data.m_Weight->GetTensorInfo();
118
119 // Get the depth multiplier
telsoa01c577f2c2018-08-31 09:22:23 +0100120 const unsigned int depthMultiplier = weightInfo.GetShape()[0];
121
Aron Virginas-Tar6f3785d2019-07-22 15:30:22 +0100122 arm_compute::PadStrideInfo padStrideInfo = BuildArmComputePadStrideInfo(m_Data.m_Parameters);
Pablo Tellof0bd6832019-04-26 17:58:13 +0100123
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_DepthwiseConvolutionLayer = std::make_unique<arm_compute::CLDepthwiseConvolutionLayer>();
127 static_cast<arm_compute::CLDepthwiseConvolutionLayer*>(m_DepthwiseConvolutionLayer.get())->configure(
Sadik Armagane9444752020-12-02 11:28:58 +0000128 clCompileContext,
Aron Virginas-Tarf4c502f2019-11-14 16:21:38 +0000129 &input,
130 m_KernelTensor.get(),
131 m_BiasTensor.get(),
132 &output,
133 padStrideInfo,
134 depthMultiplier,
Mike Kelly07810fc2020-11-12 10:58:48 +0000135 activationInfo,
Aron Virginas-Tarf4c502f2019-11-14 16:21:38 +0000136 aclDilationInfo);
telsoa01c577f2c2018-08-31 09:22:23 +0100137
Narumol Prangnawaratac2770a2020-04-01 16:51:23 +0100138 ARMNN_ASSERT(m_DepthwiseConvolutionLayer);
Matthew Benthamd8777392018-10-08 09:38:55 +0100139
Matteo Martincigh747ef822018-12-18 09:26:39 +0000140 ScopedCpuTensorHandle weightsPermutedHandle(weightPermuted);
141 InitializeArmComputeClTensorData(*m_KernelTensor, &weightsPermutedHandle);
Matthew Benthamd8777392018-10-08 09:38:55 +0100142
143 if (m_BiasTensor)
144 {
145 InitializeArmComputeClTensorData(*m_BiasTensor, m_Data.m_Bias);
146 }
147
148 m_DepthwiseConvolutionLayer->prepare();
149 FreeUnusedTensors();
telsoa01c577f2c2018-08-31 09:22:23 +0100150}
151
Matthew Benthamd8777392018-10-08 09:38:55 +0100152void ClDepthwiseConvolutionWorkload::FreeUnusedTensors()
telsoa01c577f2c2018-08-31 09:22:23 +0100153{
154 FreeTensorIfUnused(m_KernelTensor);
155 FreeTensorIfUnused(m_BiasTensor);
156}
157
Matthew Benthamd8777392018-10-08 09:38:55 +0100158void ClDepthwiseConvolutionWorkload::Execute() const
159{
160 ARMNN_SCOPED_PROFILING_EVENT_CL("ClDepthwiseConvolutionWorkload_Execute");
Narumol Prangnawaratac2770a2020-04-01 16:51:23 +0100161 ARMNN_ASSERT(m_DepthwiseConvolutionLayer);
Matthew Benthamd8777392018-10-08 09:38:55 +0100162
Aron Virginas-Tara8e06ed2018-10-19 16:46:15 +0100163 RunClFunction(*m_DepthwiseConvolutionLayer, CHECK_LOCATION());
Matthew Benthamd8777392018-10-08 09:38:55 +0100164}
telsoa01c577f2c2018-08-31 09:22:23 +0100165
166} // namespace armnn