blob: d294705eaa4c225b3dd388bf733e5a28969cf91d [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
Aron Virginas-Tarc9cc8042018-11-01 16:15:57 +00008#include <aclCommon/ArmComputeTensorUtils.hpp>
9#include <neon/NeonLayerSupport.hpp>
10#include <backendsCommon/CpuTensorHandle.hpp>
Mohamed Nour Abouelseoud9337af32018-11-27 17:35:35 +000011#include <backendsCommon/DataLayoutIndexed.hpp>
telsoa014fcda012018-03-09 14:13:49 +000012
13namespace armnn
14{
Nattapat Chaimanowong77140882018-10-17 11:12:19 +010015
telsoa014fcda012018-03-09 14:13:49 +000016using namespace armcomputetensorutils;
17
Nattapat Chaimanowong77140882018-10-17 11:12:19 +010018arm_compute::Status NeonDepthwiseConvolutionWorkloadValidate(const TensorInfo& input,
19 const TensorInfo& output,
20 const DepthwiseConvolution2dDescriptor& descriptor,
21 const TensorInfo& weights,
22 const Optional<TensorInfo>& biases)
23{
24 const arm_compute::TensorInfo aclInputInfo =
25 BuildArmComputeTensorInfo(input, descriptor.m_DataLayout);
26 const arm_compute::TensorInfo aclOutputInfo =
27 BuildArmComputeTensorInfo(output, descriptor.m_DataLayout);
28 const arm_compute::TensorInfo aclWeightsInfo =
29 BuildArmComputeTensorInfo(weights, descriptor.m_DataLayout);
30
31 arm_compute::TensorInfo aclBiasesInfo;
32 arm_compute::TensorInfo *optionalAclBiasesInfo = nullptr;
33
34 if (descriptor.m_BiasEnabled)
35 {
36 BOOST_ASSERT(biases.has_value());
37
38 aclBiasesInfo = BuildArmComputeTensorInfo(biases.value(), descriptor.m_DataLayout);
39 optionalAclBiasesInfo = &aclBiasesInfo;
40 }
41
42 const arm_compute::PadStrideInfo aclPadStrideInfo =
43 BuildArmComputePadStrideInfo(descriptor);
44 const unsigned int aclDepthMultiplier = weights.GetShape()[0];
45
46 return arm_compute::NEDepthwiseConvolutionLayer::validate(&aclInputInfo,
47 &aclWeightsInfo,
48 optionalAclBiasesInfo,
49 &aclOutputInfo,
50 aclPadStrideInfo,
51 aclDepthMultiplier);
52}
53
54NeonDepthwiseConvolutionWorkload::NeonDepthwiseConvolutionWorkload(
telsoa014fcda012018-03-09 14:13:49 +000055 const DepthwiseConvolution2dQueueDescriptor& descriptor,
56 const WorkloadInfo& info)
Nattapat Chaimanowong77140882018-10-17 11:12:19 +010057 : BaseWorkload<DepthwiseConvolution2dQueueDescriptor>(descriptor, info)
telsoa014fcda012018-03-09 14:13:49 +000058{
59 const TensorInfo& weightInfo = m_Data.m_Weight->GetTensorInfo();
60
telsoa01c577f2c2018-08-31 09:22:23 +010061 m_KernelTensor = std::make_unique<arm_compute::Tensor>();
Nikhil Rajcec6b652018-10-12 13:51:57 +010062 BuildArmComputeTensor(*m_KernelTensor, weightInfo, m_Data.m_Parameters.m_DataLayout);
telsoa014fcda012018-03-09 14:13:49 +000063
Mohamed Nour Abouelseoud9337af32018-11-27 17:35:35 +000064 INeonTensorHandle* inputTensorHandle = static_cast<INeonTensorHandle*>(m_Data.m_Inputs[0]);
65 INeonTensorHandle* outputTensorHandle = static_cast<INeonTensorHandle*>(m_Data.m_Outputs[0]);
66 DataLayoutIndexed dataLayoutIndex(m_Data.m_Parameters.m_DataLayout);
67
telsoa014fcda012018-03-09 14:13:49 +000068 if (m_Data.m_Parameters.m_BiasEnabled)
69 {
telsoa01c577f2c2018-08-31 09:22:23 +010070 m_BiasTensor = std::make_unique<arm_compute::Tensor>();
Nikhil Rajcec6b652018-10-12 13:51:57 +010071 BuildArmComputeTensor(*m_BiasTensor, m_Data.m_Bias->GetTensorInfo(), m_Data.m_Parameters.m_DataLayout);
telsoa014fcda012018-03-09 14:13:49 +000072 }
Mohamed Nour Abouelseoud9337af32018-11-27 17:35:35 +000073 else
74 {
75 // Workaround for COMPMID-1813
76 m_BiasTensor = std::make_unique<arm_compute::Tensor>();
77 TensorInfo biasTensorInfo({weightInfo.GetShape()[dataLayoutIndex.GetChannelsIndex()]},
78 weightInfo.GetDataType() == DataType::QuantisedAsymm8 ? DataType::Signed32 :
79 weightInfo.GetDataType(),
80 weightInfo.GetQuantizationScale() *
81 info.m_InputTensorInfos[0].GetQuantizationScale());
82 BuildArmComputeTensor(*m_BiasTensor, biasTensorInfo, m_Data.m_Parameters.m_DataLayout);
83 }
telsoa014fcda012018-03-09 14:13:49 +000084
85 arm_compute::PadStrideInfo padStrideInfo(m_Data.m_Parameters.m_StrideX,
86 m_Data.m_Parameters.m_StrideY,
87 m_Data.m_Parameters.m_PadLeft,
88 m_Data.m_Parameters.m_PadRight,
89 m_Data.m_Parameters.m_PadTop,
90 m_Data.m_Parameters.m_PadBottom,
91 arm_compute::DimensionRoundingType::FLOOR);
92
Nattapat Chaimanowong77140882018-10-17 11:12:19 +010093 m_Data.ValidateInputsOutputs("NeonDepthwiseConvolutionWorkload", 1, 1);
telsoa014fcda012018-03-09 14:13:49 +000094
Mohamed Nour Abouelseoud9337af32018-11-27 17:35:35 +000095 arm_compute::ITensor& input = inputTensorHandle->GetTensor();
96 arm_compute::ITensor& output = outputTensorHandle->GetTensor();
telsoa014fcda012018-03-09 14:13:49 +000097
Nikhil Rajcec6b652018-10-12 13:51:57 +010098 arm_compute::DataLayout aclDataLayout = ConvertDataLayout(m_Data.m_Parameters.m_DataLayout);
99 input.info()->set_data_layout(aclDataLayout);
100 output.info()->set_data_layout(aclDataLayout);
101
Mohamed Nour Abouelseoud9337af32018-11-27 17:35:35 +0000102 bool use3x3Optimisation = weightInfo.GetShape()[dataLayoutIndex.GetWidthIndex()] == 3 &&
103 weightInfo.GetShape()[dataLayoutIndex.GetHeightIndex()] == 3;
104
telsoa014fcda012018-03-09 14:13:49 +0000105 if (use3x3Optimisation)
106 {
107 m_pDepthwiseConvolutionLayer = std::make_unique<arm_compute::NEDepthwiseConvolutionLayer3x3>();
108 static_cast<arm_compute::NEDepthwiseConvolutionLayer3x3*>(
109 m_pDepthwiseConvolutionLayer.get())->configure(&input,
telsoa01c577f2c2018-08-31 09:22:23 +0100110 m_KernelTensor.get(),
111 m_BiasTensor.get(),
telsoa014fcda012018-03-09 14:13:49 +0000112 &output,
113 padStrideInfo);
114 }
115 else
116 {
117 m_pDepthwiseConvolutionLayer = std::make_unique<arm_compute::NEDepthwiseConvolutionLayer>();
118 static_cast<arm_compute::NEDepthwiseConvolutionLayer*>(
119 m_pDepthwiseConvolutionLayer.get())->configure(&input,
telsoa01c577f2c2018-08-31 09:22:23 +0100120 m_KernelTensor.get(),
121 m_BiasTensor.get(),
telsoa014fcda012018-03-09 14:13:49 +0000122 &output,
123 padStrideInfo);
124 }
125
126 BOOST_ASSERT(m_pDepthwiseConvolutionLayer);
127
Nattapat Chaimanowong177d8d22018-10-16 13:21:27 +0100128 InitializeArmComputeTensorData(*m_KernelTensor, m_Data.m_Weight);
telsoa014fcda012018-03-09 14:13:49 +0000129
Mohamed Nour Abouelseoud9337af32018-11-27 17:35:35 +0000130 if (m_Data.m_Parameters.m_BiasEnabled)
telsoa014fcda012018-03-09 14:13:49 +0000131 {
Nattapat Chaimanowong177d8d22018-10-16 13:21:27 +0100132 InitializeArmComputeTensorData(*m_BiasTensor, m_Data.m_Bias);
telsoa014fcda012018-03-09 14:13:49 +0000133 }
Mohamed Nour Abouelseoud9337af32018-11-27 17:35:35 +0000134 else
135 {
136 InitialiseArmComputeTensorEmpty(*m_BiasTensor);
137 }
telsoa01c577f2c2018-08-31 09:22:23 +0100138
139 m_pDepthwiseConvolutionLayer->prepare();
140 FreeUnusedTensors();
telsoa014fcda012018-03-09 14:13:49 +0000141}
142
Nattapat Chaimanowong77140882018-10-17 11:12:19 +0100143void NeonDepthwiseConvolutionWorkload::Execute() const
telsoa014fcda012018-03-09 14:13:49 +0000144{
Nattapat Chaimanowong77140882018-10-17 11:12:19 +0100145 ARMNN_SCOPED_PROFILING_EVENT_NEON("NeonDepthwiseConvolutionWorkload_Execute");
telsoa014fcda012018-03-09 14:13:49 +0000146 BOOST_ASSERT(m_pDepthwiseConvolutionLayer);
147
148 m_pDepthwiseConvolutionLayer->run();
149}
150
Nattapat Chaimanowong77140882018-10-17 11:12:19 +0100151void NeonDepthwiseConvolutionWorkload::FreeUnusedTensors()
telsoa01c577f2c2018-08-31 09:22:23 +0100152{
153 FreeTensorIfUnused(m_KernelTensor);
154 FreeTensorIfUnused(m_BiasTensor);
155}
156
telsoa014fcda012018-03-09 14:13:49 +0000157} //namespace armnn