MLCE-101: Adding dilation support in conv and dconv
Added support for dilation in DepthwiseConvolution2d in the
Neon and CL backends.
Change-Id: Ie1522b498c07f80d6efcf9dc79e926c8cfa06ca5
Signed-off-by: Pablo Tello <pablo.tello@arm.com>
diff --git a/src/backends/cl/ClLayerSupport.cpp b/src/backends/cl/ClLayerSupport.cpp
index a5c5f2b..73c9e49 100644
--- a/src/backends/cl/ClLayerSupport.cpp
+++ b/src/backends/cl/ClLayerSupport.cpp
@@ -246,6 +246,23 @@
biases);
}
+bool ClLayerSupport::IsDilatedDepthwiseConvolutionSupported(const TensorInfo& input,
+ const TensorInfo& output,
+ const DepthwiseConvolution2dDescriptor& descriptor,
+ const TensorInfo& weights,
+ const Optional<TensorInfo>& biases,
+ Optional<std::string&> reasonIfUnsupported) const
+{
+ FORWARD_WORKLOAD_VALIDATE_FUNC(ClDepthwiseConvolutionWorkloadValidate,
+ reasonIfUnsupported,
+ input,
+ output,
+ descriptor,
+ weights,
+ biases);
+}
+
+
bool ClLayerSupport::IsDivisionSupported(const TensorInfo& input0,
const TensorInfo& input1,
const TensorInfo& output,
diff --git a/src/backends/cl/ClLayerSupport.hpp b/src/backends/cl/ClLayerSupport.hpp
index 6393a11..e9a9e68 100644
--- a/src/backends/cl/ClLayerSupport.hpp
+++ b/src/backends/cl/ClLayerSupport.hpp
@@ -61,6 +61,13 @@
const Optional<TensorInfo>& biases,
Optional<std::string&> reasonIfUnsupported = EmptyOptional()) const override;
+ bool IsDilatedDepthwiseConvolutionSupported(const TensorInfo& input,
+ const TensorInfo& output,
+ const DepthwiseConvolution2dDescriptor& descriptor,
+ const TensorInfo& weights,
+ const Optional<TensorInfo>& biases,
+ Optional<std::string&> reason = EmptyOptional()) const override;
+
bool IsDivisionSupported(const TensorInfo& input0,
const TensorInfo& input1,
const TensorInfo& output,
diff --git a/src/backends/cl/workloads/ClDepthwiseConvolutionWorkload.cpp b/src/backends/cl/workloads/ClDepthwiseConvolutionWorkload.cpp
index 1ff0978..e681e95 100644
--- a/src/backends/cl/workloads/ClDepthwiseConvolutionWorkload.cpp
+++ b/src/backends/cl/workloads/ClDepthwiseConvolutionWorkload.cpp
@@ -52,13 +52,19 @@
}
const arm_compute::PadStrideInfo aclPadStrideInfo = BuildArmComputePadStrideInfo(descriptor);
+ const arm_compute::Size2D aclDilationInfo = BuildArmComputeSize2D(
+ descriptor.m_DilationX,
+ descriptor.m_DilationY);
return arm_compute::CLDepthwiseConvolutionLayer::validate(&aclInputInfo,
&aclWeightsInfo,
optionalAclBiasesInfo,
&aclOutputInfo,
aclPadStrideInfo,
- aclDepthMultiplier);
+ aclDepthMultiplier,
+ arm_compute::ActivationLayerInfo(),
+ aclDilationInfo);
+
}
ClDepthwiseConvolutionWorkload::ClDepthwiseConvolutionWorkload(
@@ -85,7 +91,7 @@
BuildArmComputeTensor(*m_BiasTensor, m_Data.m_Bias->GetTensorInfo(), m_Data.m_Parameters.m_DataLayout);
}
- arm_compute::PadStrideInfo padStrideInfo(m_Data.m_Parameters.m_StrideX,
+ const arm_compute::PadStrideInfo padStrideInfo(m_Data.m_Parameters.m_StrideX,
m_Data.m_Parameters.m_StrideY,
m_Data.m_Parameters.m_PadLeft,
m_Data.m_Parameters.m_PadRight,
@@ -93,6 +99,11 @@
m_Data.m_Parameters.m_PadBottom,
arm_compute::DimensionRoundingType::FLOOR);
+ const arm_compute::Size2D aclDilationInfo = BuildArmComputeSize2D(
+ m_Data.m_Parameters.m_DilationX,
+ m_Data.m_Parameters.m_DilationY);
+
+
std::string name = std::string("ClDepthwiseConvolutionWorkload");
m_Data.ValidateInputsOutputs(name, 1, 1);
@@ -109,6 +120,7 @@
// Get the depth multiplier
const unsigned int depthMultiplier = weightInfo.GetShape()[0];
+
// Check for optimisation opportunities.
bool use3x3Optimisation = (weightInfo.GetShape()[2] == 3) && (weightInfo.GetShape()[3] == 3);
if (use3x3Optimisation)
@@ -120,7 +132,9 @@
m_BiasTensor.get(),
&output,
padStrideInfo,
- depthMultiplier);
+ depthMultiplier,
+ arm_compute::ActivationLayerInfo(),
+ aclDilationInfo);
}
else
{
@@ -131,7 +145,10 @@
m_BiasTensor.get(),
&output,
padStrideInfo,
- depthMultiplier);
+ depthMultiplier,
+ arm_compute::ActivationLayerInfo(),
+ aclDilationInfo);
+
}
BOOST_ASSERT(m_DepthwiseConvolutionLayer);
diff --git a/src/backends/neon/NeonLayerSupport.cpp b/src/backends/neon/NeonLayerSupport.cpp
index 898660c..c257dd3 100644
--- a/src/backends/neon/NeonLayerSupport.cpp
+++ b/src/backends/neon/NeonLayerSupport.cpp
@@ -203,6 +203,22 @@
biases);
}
+bool NeonLayerSupport::IsDilatedDepthwiseConvolutionSupported(const TensorInfo& input,
+ const TensorInfo& output,
+ const DepthwiseConvolution2dDescriptor& descriptor,
+ const TensorInfo& weights,
+ const Optional<TensorInfo>& biases,
+ Optional<std::string&> reasonIfUnsupported) const
+{
+ FORWARD_WORKLOAD_VALIDATE_FUNC(NeonDepthwiseConvolutionWorkloadValidate,
+ reasonIfUnsupported,
+ input,
+ output,
+ descriptor,
+ weights,
+ biases);
+}
+
bool NeonLayerSupport::IsFloorSupported(const TensorInfo& input,
const TensorInfo& output,
Optional<std::string&> reasonIfUnsupported) const
diff --git a/src/backends/neon/NeonLayerSupport.hpp b/src/backends/neon/NeonLayerSupport.hpp
index 27e825a..a5aae0b 100644
--- a/src/backends/neon/NeonLayerSupport.hpp
+++ b/src/backends/neon/NeonLayerSupport.hpp
@@ -56,6 +56,13 @@
const Optional<TensorInfo>& biases,
Optional<std::string&> reasonIfUnsupported = EmptyOptional()) const override;
+ bool IsDilatedDepthwiseConvolutionSupported(const TensorInfo& input,
+ const TensorInfo& output,
+ const DepthwiseConvolution2dDescriptor& descriptor,
+ const TensorInfo& weights,
+ const Optional<TensorInfo>& biases,
+ Optional<std::string&> reason = EmptyOptional()) const override;
+
bool IsFloorSupported(const TensorInfo& input,
const TensorInfo& output,
Optional<std::string&> reasonIfUnsupported = EmptyOptional()) const override;
diff --git a/src/backends/neon/workloads/NeonDepthwiseConvolutionWorkload.cpp b/src/backends/neon/workloads/NeonDepthwiseConvolutionWorkload.cpp
index c915555..0b917fc 100644
--- a/src/backends/neon/workloads/NeonDepthwiseConvolutionWorkload.cpp
+++ b/src/backends/neon/workloads/NeonDepthwiseConvolutionWorkload.cpp
@@ -52,14 +52,18 @@
optionalAclBiasesInfo = &aclBiasesInfo;
}
- const arm_compute::PadStrideInfo aclPadStrideInfo = BuildArmComputePadStrideInfo(descriptor);
+ arm_compute::PadStrideInfo aclPadStrideInfo = BuildArmComputePadStrideInfo(descriptor);
+ const arm_compute::Size2D aclDilationInfo = BuildArmComputeSize2D(
+ descriptor.m_DilationX,descriptor.m_DilationY);
return arm_compute::NEDepthwiseConvolutionLayer::validate(&aclInputInfo,
&aclWeightsInfo,
optionalAclBiasesInfo,
&aclOutputInfo,
aclPadStrideInfo,
- aclDepthMultiplier);
+ aclDepthMultiplier,
+ arm_compute::ActivationLayerInfo(),
+ aclDilationInfo);
}
NeonDepthwiseConvolutionWorkload::NeonDepthwiseConvolutionWorkload(
@@ -97,6 +101,10 @@
m_Data.m_Parameters.m_PadBottom,
arm_compute::DimensionRoundingType::FLOOR);
+
+ const arm_compute::Size2D aclDilationInfo = BuildArmComputeSize2D(
+ m_Data.m_Parameters.m_DilationX, m_Data.m_Parameters.m_DilationY);
+
m_Data.ValidateInputsOutputs("NeonDepthwiseConvolutionWorkload", 1, 1);
INeonTensorHandle* inputTensorHandle = static_cast<INeonTensorHandle*>(m_Data.m_Inputs[0]);
@@ -109,7 +117,7 @@
input.info()->set_data_layout(aclDataLayout);
output.info()->set_data_layout(aclDataLayout);
- // Get the depth multiplier
+ // Get the depth multiplier
const unsigned int depthMultiplier = weightInfo.GetShape()[0];
// Check for optimisation opportunities.
@@ -123,7 +131,9 @@
m_BiasTensor.get(),
&output,
padStrideInfo,
- depthMultiplier);
+ depthMultiplier,
+ arm_compute::ActivationLayerInfo(),
+ aclDilationInfo);
}
else
{
@@ -134,7 +144,9 @@
m_BiasTensor.get(),
&output,
padStrideInfo,
- depthMultiplier);
+ depthMultiplier,
+ arm_compute::ActivationLayerInfo(),
+ aclDilationInfo);
}
BOOST_ASSERT(m_pDepthwiseConvolutionLayer);
diff --git a/src/backends/reference/RefLayerSupport.cpp b/src/backends/reference/RefLayerSupport.cpp
index 8eded84..a1d8e7d 100644
--- a/src/backends/reference/RefLayerSupport.cpp
+++ b/src/backends/reference/RefLayerSupport.cpp
@@ -429,7 +429,29 @@
&TrueFunc<>);
}
-bool RefLayerSupport::IsDivisionSupported(const TensorInfo& input0,
+bool RefLayerSupport::IsDilatedDepthwiseConvolutionSupported(const TensorInfo& input,
+ const TensorInfo& output,
+ const DepthwiseConvolution2dDescriptor& descriptor,
+ const TensorInfo& weights,
+ const Optional<TensorInfo>& biases,
+ Optional<std::string&> reasonIfUnsupported) const
+{
+ if (descriptor.m_DilationY == 1 && descriptor.m_DilationY == 1)
+ {
+ return IsDepthwiseConvolutionSupported(input, output, descriptor, weights, biases, reasonIfUnsupported);
+ }
+ else
+ {
+ if (reasonIfUnsupported)
+ {
+ reasonIfUnsupported.value() = "Reference Depthwise Convolution: Dilation parameters must be 1";
+ }
+ return false;
+ }
+}
+
+
+ bool RefLayerSupport::IsDivisionSupported(const TensorInfo& input0,
const TensorInfo& input1,
const TensorInfo& output,
Optional<std::string&> reasonIfUnsupported) const
diff --git a/src/backends/reference/RefLayerSupport.hpp b/src/backends/reference/RefLayerSupport.hpp
index 53a1abf..9b1a95c 100644
--- a/src/backends/reference/RefLayerSupport.hpp
+++ b/src/backends/reference/RefLayerSupport.hpp
@@ -74,6 +74,14 @@
const DetectionPostProcessDescriptor& descriptor,
Optional<std::string&> reasonIfUnsupported = EmptyOptional()) const override;
+ bool IsDilatedDepthwiseConvolutionSupported(const TensorInfo& input,
+ const TensorInfo& output,
+ const DepthwiseConvolution2dDescriptor& descriptor,
+ const TensorInfo& weights,
+ const Optional<TensorInfo>& biases,
+ Optional<std::string&> reasonIfUnsupported =
+ EmptyOptional()) const override;
+
bool IsDivisionSupported(const TensorInfo& input0,
const TensorInfo& input1,
const TensorInfo& output,