blob: 6fa9ddc6b0bcc485f53f0c967e758dda7f87747c [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
8#include "TypeUtils.hpp"
Matthew Benthamd8777392018-10-08 09:38:55 +01009#include "ClWorkloadUtils.hpp"
telsoa01c577f2c2018-08-31 09:22:23 +010010
David Beck711fa312018-09-24 10:46:38 +010011#include <backends/aclCommon/ArmComputeUtils.hpp>
12#include <backends/aclCommon/ArmComputeTensorUtils.hpp>
David Beckac42efd2018-09-26 17:41:13 +010013#include <backends/cl/ClTensorHandle.hpp>
David Beck711fa312018-09-24 10:46:38 +010014#include <backends/CpuTensorHandle.hpp>
telsoa01c577f2c2018-08-31 09:22:23 +010015
Matthew Benthamd8777392018-10-08 09:38:55 +010016#include <arm_compute/runtime/CL/functions/CLDepthwiseConvolutionLayer.h>
17
telsoa01c577f2c2018-08-31 09:22:23 +010018namespace armnn
19{
20
21using namespace armcomputetensorutils;
22
23arm_compute::Status ClDepthwiseConvolutionWorkloadValidate(const TensorInfo& input,
24 const TensorInfo& output,
25 const DepthwiseConvolution2dDescriptor& descriptor,
26 const TensorInfo& weights,
David Beck5eec11d2018-10-04 15:43:17 +010027 const Optional<TensorInfo>& biases)
telsoa01c577f2c2018-08-31 09:22:23 +010028{
Nikhil Raja05c2102018-09-25 16:16:13 +010029 const arm_compute::TensorInfo aclInputInfo = BuildArmComputeTensorInfo(input, descriptor.m_DataLayout);
30 const arm_compute::TensorInfo aclOutputInfo = BuildArmComputeTensorInfo(output, descriptor.m_DataLayout);
31 const arm_compute::TensorInfo aclWeightsInfo = BuildArmComputeTensorInfo(weights, descriptor.m_DataLayout);
telsoa01c577f2c2018-08-31 09:22:23 +010032
33 arm_compute::TensorInfo aclBiasesInfo;
34 arm_compute::TensorInfo *optionalAclBiasesInfo = nullptr;
arovir01a6824102018-08-28 17:40:45 +010035
telsoa01c577f2c2018-08-31 09:22:23 +010036 if (descriptor.m_BiasEnabled)
37 {
David Beck5eec11d2018-10-04 15:43:17 +010038 BOOST_ASSERT(biases.has_value());
arovir01a6824102018-08-28 17:40:45 +010039
David Beck5eec11d2018-10-04 15:43:17 +010040 aclBiasesInfo = BuildArmComputeTensorInfo(biases.value(), descriptor.m_DataLayout);
telsoa01c577f2c2018-08-31 09:22:23 +010041 optionalAclBiasesInfo = &aclBiasesInfo;
42 }
43
44 const arm_compute::PadStrideInfo aclPadStrideInfo = BuildArmComputePadStrideInfo(descriptor);
45 const unsigned int aclDepthMultiplier = weights.GetShape()[0];
46
47 return arm_compute::CLDepthwiseConvolutionLayer::validate(&aclInputInfo,
48 &aclWeightsInfo,
49 optionalAclBiasesInfo,
50 &aclOutputInfo,
51 aclPadStrideInfo,
52 aclDepthMultiplier);
53}
54
Matthew Benthamd8777392018-10-08 09:38:55 +010055ClDepthwiseConvolutionWorkload::ClDepthwiseConvolutionWorkload(
telsoa01c577f2c2018-08-31 09:22:23 +010056 const DepthwiseConvolution2dQueueDescriptor& descriptor,
57 const WorkloadInfo& info)
Matthew Benthamd8777392018-10-08 09:38:55 +010058 : BaseWorkload<DepthwiseConvolution2dQueueDescriptor>(descriptor, info)
telsoa01c577f2c2018-08-31 09:22:23 +010059{
60 auto& weightInfo = m_Data.m_Weight->GetTensorInfo();
61
62 m_KernelTensor = std::make_unique<arm_compute::CLTensor>();
Nikhil Rajcec6b652018-10-12 13:51:57 +010063 BuildArmComputeTensor(*m_KernelTensor, weightInfo, m_Data.m_Parameters.m_DataLayout);
telsoa01c577f2c2018-08-31 09:22:23 +010064
65 if (m_Data.m_Parameters.m_BiasEnabled)
66 {
67 m_BiasTensor = std::make_unique<arm_compute::CLTensor>();
Nikhil Rajcec6b652018-10-12 13:51:57 +010068 BuildArmComputeTensor(*m_BiasTensor, m_Data.m_Bias->GetTensorInfo(), m_Data.m_Parameters.m_DataLayout);
telsoa01c577f2c2018-08-31 09:22:23 +010069 }
70
71 arm_compute::PadStrideInfo padStrideInfo(m_Data.m_Parameters.m_StrideX,
72 m_Data.m_Parameters.m_StrideY,
73 m_Data.m_Parameters.m_PadLeft,
74 m_Data.m_Parameters.m_PadRight,
75 m_Data.m_Parameters.m_PadTop,
76 m_Data.m_Parameters.m_PadBottom,
77 arm_compute::DimensionRoundingType::FLOOR);
78
Matthew Benthamd8777392018-10-08 09:38:55 +010079 std::string name = std::string("ClDepthwiseConvolutionWorkload");
telsoa01c577f2c2018-08-31 09:22:23 +010080 m_Data.ValidateInputsOutputs(name, 1, 1);
81
82 arm_compute::ICLTensor& input = static_cast<IClTensorHandle*>(m_Data.m_Inputs[0])->GetTensor();
83 arm_compute::ICLTensor& output = static_cast<IClTensorHandle*>(m_Data.m_Outputs[0])->GetTensor();
84
Nikhil Rajcec6b652018-10-12 13:51:57 +010085 arm_compute::DataLayout aclDataLayout = ConvertDataLayout(m_Data.m_Parameters.m_DataLayout);
86 input.info()->set_data_layout(aclDataLayout);
87 output.info()->set_data_layout(aclDataLayout);
88
telsoa01c577f2c2018-08-31 09:22:23 +010089 const unsigned int depthMultiplier = weightInfo.GetShape()[0];
90
91 //Check for optimisation opportunities.
92 bool use3x3Optimisation = (weightInfo.GetShape()[3] == 3) && (weightInfo.GetShape()[2] == 3);
93 if (use3x3Optimisation)
94 {
95 m_DepthwiseConvolutionLayer = std::make_unique<arm_compute::CLDepthwiseConvolutionLayer3x3>();
96 static_cast<arm_compute::CLDepthwiseConvolutionLayer3x3*>(m_DepthwiseConvolutionLayer.get())->configure(
97 &input,
98 m_KernelTensor.get(),
99 m_BiasTensor.get(),
100 &output,
101 padStrideInfo,
102 depthMultiplier);
103 }
104 else
105 {
106 m_DepthwiseConvolutionLayer = std::make_unique<arm_compute::CLDepthwiseConvolutionLayer>();
107 static_cast<arm_compute::CLDepthwiseConvolutionLayer*>(m_DepthwiseConvolutionLayer.get())->configure(
108 &input,
109 m_KernelTensor.get(),
110 m_BiasTensor.get(),
111 &output,
112 padStrideInfo,
113 depthMultiplier);
114 }
115
116 BOOST_ASSERT(m_DepthwiseConvolutionLayer);
Matthew Benthamd8777392018-10-08 09:38:55 +0100117
118 InitializeArmComputeClTensorData(*m_KernelTensor, m_Data.m_Weight);
119
120 if (m_BiasTensor)
121 {
122 InitializeArmComputeClTensorData(*m_BiasTensor, m_Data.m_Bias);
123 }
124
125 m_DepthwiseConvolutionLayer->prepare();
126 FreeUnusedTensors();
telsoa01c577f2c2018-08-31 09:22:23 +0100127}
128
Matthew Benthamd8777392018-10-08 09:38:55 +0100129void ClDepthwiseConvolutionWorkload::FreeUnusedTensors()
telsoa01c577f2c2018-08-31 09:22:23 +0100130{
131 FreeTensorIfUnused(m_KernelTensor);
132 FreeTensorIfUnused(m_BiasTensor);
133}
134
Matthew Benthamd8777392018-10-08 09:38:55 +0100135void ClDepthwiseConvolutionWorkload::Execute() const
136{
137 ARMNN_SCOPED_PROFILING_EVENT_CL("ClDepthwiseConvolutionWorkload_Execute");
138 BOOST_ASSERT(m_DepthwiseConvolutionLayer);
139
140 m_DepthwiseConvolutionLayer->run();
141}
telsoa01c577f2c2018-08-31 09:22:23 +0100142
143} // namespace armnn