Release 18.08
[platform/upstream/armnn.git] / src / armnn / backends / NeonWorkloads / NeonDepthwiseConvolutionUint8Workload.cpp
1 //
2 // Copyright © 2017 Arm Ltd. All rights reserved.
3 // See LICENSE file in the project root for full license information.
4 //
5
6 #include "NeonDepthwiseConvolutionUint8Workload.hpp"
7 #include "backends/NeonLayerSupport.hpp"
8 #include "backends/CpuTensorHandle.hpp"
9 #include "backends/ArmComputeTensorUtils.hpp"
10
11
12 namespace armnn
13 {
14 using namespace armcomputetensorutils;
15
16 NeonDepthwiseConvolutionUint8Workload::NeonDepthwiseConvolutionUint8Workload(
17     const DepthwiseConvolution2dQueueDescriptor& descriptor,
18     const WorkloadInfo& info)
19     : Uint8Workload<DepthwiseConvolution2dQueueDescriptor>(descriptor, info)
20 {
21     const TensorInfo& weightInfo = m_Data.m_Weight->GetTensorInfo();
22
23     m_KernelTensor = std::make_unique<arm_compute::Tensor>();
24     BuildArmComputeTensor(*m_KernelTensor, weightInfo);
25
26     if (m_Data.m_Parameters.m_BiasEnabled)
27     {
28         m_BiasTensor = std::make_unique<arm_compute::Tensor>();
29         BuildArmComputeTensor(*m_BiasTensor, m_Data.m_Bias->GetTensorInfo());
30     }
31
32     arm_compute::PadStrideInfo padStrideInfo(m_Data.m_Parameters.m_StrideX,
33                                              m_Data.m_Parameters.m_StrideY,
34                                              m_Data.m_Parameters.m_PadLeft,
35                                              m_Data.m_Parameters.m_PadRight,
36                                              m_Data.m_Parameters.m_PadTop,
37                                              m_Data.m_Parameters.m_PadBottom,
38                                              arm_compute::DimensionRoundingType::FLOOR);
39
40     m_Data.ValidateInputsOutputs("NeonDepthwiseConvolutionUint8Workload", 1, 1);
41
42     arm_compute::ITensor& input  = static_cast<INeonTensorHandle*>(m_Data.m_Inputs[0])->GetTensor();
43     arm_compute::ITensor& output = static_cast<INeonTensorHandle*>(m_Data.m_Outputs[0])->GetTensor();
44
45     bool use3x3Optimisation = weightInfo.GetShape()[3] == 3 && weightInfo.GetShape()[2] == 3;
46     if (use3x3Optimisation)
47     {
48         m_pDepthwiseConvolutionLayer = std::make_unique<arm_compute::NEDepthwiseConvolutionLayer3x3>();
49         static_cast<arm_compute::NEDepthwiseConvolutionLayer3x3*>(
50             m_pDepthwiseConvolutionLayer.get())->configure(&input,
51                                                            m_KernelTensor.get(),
52                                                            m_BiasTensor.get(),
53                                                            &output,
54                                                            padStrideInfo);
55     }
56     else
57     {
58         m_pDepthwiseConvolutionLayer = std::make_unique<arm_compute::NEDepthwiseConvolutionLayer>();
59         static_cast<arm_compute::NEDepthwiseConvolutionLayer*>(
60             m_pDepthwiseConvolutionLayer.get())->configure(&input,
61                                                            m_KernelTensor.get(),
62                                                            m_BiasTensor.get(),
63                                                            &output,
64                                                            padStrideInfo);
65     }
66
67     BOOST_ASSERT(m_pDepthwiseConvolutionLayer);
68
69     InitialiseArmComputeTensorData(*m_KernelTensor, m_Data.m_Weight->GetConstTensor<uint8_t>());
70
71     if (m_BiasTensor)
72     {
73         InitialiseArmComputeTensorData(*m_BiasTensor, m_Data.m_Bias->GetConstTensor<int32_t>());
74     }
75
76     m_pDepthwiseConvolutionLayer->prepare();
77     FreeUnusedTensors();
78 }
79
80 void NeonDepthwiseConvolutionUint8Workload::Execute() const
81 {
82     ARMNN_SCOPED_PROFILING_EVENT_NEON("NeonDepthwiseConvolutionUint8Workload_Execute");
83     BOOST_ASSERT(m_pDepthwiseConvolutionLayer);
84
85     m_pDepthwiseConvolutionLayer->run();
86 }
87
88 void NeonDepthwiseConvolutionUint8Workload::FreeUnusedTensors()
89 {
90     FreeTensorIfUnused(m_KernelTensor);
91     FreeTensorIfUnused(m_BiasTensor);
92 }
93
94 } //namespace armnn