aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPablo Tello <pablo.tello@arm.com>2019-04-26 17:58:13 +0100
committerPablo Tello <pablo.tello@arm.com>2019-05-13 16:51:35 +0100
commitf0bd68386cc8598f702b1df2d1ba60094e6a9d97 (patch)
tree4e5a0d2f58bbd7fb095f24bee8932970d14e52a8
parent3f9119a115bfaaf0ad89a46d00e7b9da844aca22 (diff)
downloadarmnn-f0bd68386cc8598f702b1df2d1ba60094e6a9d97.tar.gz
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>
-rw-r--r--include/armnn/Descriptors.hpp12
-rw-r--r--include/armnn/ILayerSupport.hpp8
-rw-r--r--src/armnn/LayerSupport.cpp23
-rw-r--r--src/armnn/layers/DepthwiseConvolution2dLayer.cpp7
-rw-r--r--src/armnnTfLiteParser/TfLiteParser.cpp50
-rw-r--r--src/backends/cl/ClLayerSupport.cpp17
-rw-r--r--src/backends/cl/ClLayerSupport.hpp7
-rw-r--r--src/backends/cl/workloads/ClDepthwiseConvolutionWorkload.cpp25
-rw-r--r--src/backends/neon/NeonLayerSupport.cpp16
-rw-r--r--src/backends/neon/NeonLayerSupport.hpp7
-rw-r--r--src/backends/neon/workloads/NeonDepthwiseConvolutionWorkload.cpp22
-rw-r--r--src/backends/reference/RefLayerSupport.cpp24
-rw-r--r--src/backends/reference/RefLayerSupport.hpp8
13 files changed, 181 insertions, 45 deletions
diff --git a/include/armnn/Descriptors.hpp b/include/armnn/Descriptors.hpp
index 42b017f4cc..cf31599ed1 100644
--- a/include/armnn/Descriptors.hpp
+++ b/include/armnn/Descriptors.hpp
@@ -274,6 +274,8 @@ struct Convolution2dDescriptor
, m_PadBottom(0)
, m_StrideX(0)
, m_StrideY(0)
+ , m_DilationX(1)
+ , m_DilationY(1)
, m_BiasEnabled(false)
, m_DataLayout(DataLayout::NCHW)
{}
@@ -290,6 +292,10 @@ struct Convolution2dDescriptor
uint32_t m_StrideX;
/// Stride value when proceeding through input for the height dimension.
uint32_t m_StrideY;
+ /// Dilation along x axis
+ uint32_t m_DilationX;
+ /// Dilation along y axis
+ uint32_t m_DilationY;
/// Enable/disable bias.
bool m_BiasEnabled;
/// The data layout to be used (NCHW, NHWC).
@@ -306,6 +312,8 @@ struct DepthwiseConvolution2dDescriptor
, m_PadBottom(0)
, m_StrideX(0)
, m_StrideY(0)
+ , m_DilationX(1)
+ , m_DilationY(1)
, m_BiasEnabled(false)
, m_DataLayout(DataLayout::NCHW)
{}
@@ -322,6 +330,10 @@ struct DepthwiseConvolution2dDescriptor
uint32_t m_StrideX;
/// Stride value when proceeding through input for the height dimension.
uint32_t m_StrideY;
+ /// Dilation along x axis
+ uint32_t m_DilationX;
+ /// Dilation along y axis
+ uint32_t m_DilationY;
/// Enable/disable bias.
bool m_BiasEnabled;
/// The data layout to be used (NCHW, NHWC).
diff --git a/include/armnn/ILayerSupport.hpp b/include/armnn/ILayerSupport.hpp
index dc843029c5..b8e48c8704 100644
--- a/include/armnn/ILayerSupport.hpp
+++ b/include/armnn/ILayerSupport.hpp
@@ -87,6 +87,14 @@ public:
const DetectionPostProcessDescriptor& descriptor,
Optional<std::string&> reasonIfUnsupported = EmptyOptional()) const = 0;
+ virtual bool IsDilatedDepthwiseConvolutionSupported(
+ const TensorInfo& input,
+ const TensorInfo& output,
+ const DepthwiseConvolution2dDescriptor& descriptor,
+ const TensorInfo& weights,
+ const Optional<TensorInfo>& biases,
+ Optional<std::string&> reasonIfUnsupported = EmptyOptional()) const = 0;
+
virtual bool IsDivisionSupported(const TensorInfo& input0,
const TensorInfo& input1,
const TensorInfo& output,
diff --git a/src/armnn/LayerSupport.cpp b/src/armnn/LayerSupport.cpp
index 320d9cef74..831a846092 100644
--- a/src/armnn/LayerSupport.cpp
+++ b/src/armnn/LayerSupport.cpp
@@ -186,7 +186,28 @@ bool IsDepthwiseConvolutionSupported(const BackendId& backend,
char* reasonIfUnsupported,
size_t reasonIfUnsupportedMaxLength)
{
- FORWARD_LAYER_SUPPORT_FUNC(backend, IsDepthwiseConvolutionSupported, input, output, descriptor, weights, biases);
+ if (descriptor.m_DilationX == 1 && descriptor.m_DilationY == 1)
+ {
+ // Pre 19.05 ArmNN did not have the dilation parameters.
+ // This version of IsDepthwiseConvolutionSupported is called for backwards-compatibility
+ FORWARD_LAYER_SUPPORT_FUNC(backend,
+ IsDepthwiseConvolutionSupported,
+ input,
+ output,
+ descriptor,
+ weights,
+ biases);
+ }
+ else
+ {
+ FORWARD_LAYER_SUPPORT_FUNC(backend,
+ IsDilatedDepthwiseConvolutionSupported,
+ input,
+ output,
+ descriptor,
+ weights,
+ biases);
+ }
}
bool IsDequantizeSupported(const BackendId& backend,
diff --git a/src/armnn/layers/DepthwiseConvolution2dLayer.cpp b/src/armnn/layers/DepthwiseConvolution2dLayer.cpp
index a1ffe91792..e49c179eb1 100644
--- a/src/armnn/layers/DepthwiseConvolution2dLayer.cpp
+++ b/src/armnn/layers/DepthwiseConvolution2dLayer.cpp
@@ -74,15 +74,16 @@ DepthwiseConvolution2dLayer::InferOutputShapes(const std::vector<TensorShape>& i
// Expected filter shape: [ M, I, H, W ] - This shape does NOT depend on the data layout
// Namely: [ depth multiplier, input channels, filter height, filter width ]
// Output channels = input channels * depthMultiplier
-
unsigned int depthMultiplier = filterShape[0];
unsigned int filterHeight = filterShape[2];
- unsigned int readHeight = (inputHeight + m_Param.m_PadTop + m_Param.m_PadBottom) - filterHeight;
+ unsigned int dilatedFilterHeight = filterHeight + (m_Param.m_DilationY - 1) * (filterHeight - 1);
+ unsigned int readHeight = (inputHeight + m_Param.m_PadTop + m_Param.m_PadBottom) - dilatedFilterHeight;
unsigned int outputHeight = 1 + (readHeight / m_Param.m_StrideY);
unsigned int filterWidth = filterShape[3];
- unsigned int readWidth = (inputWidth + m_Param.m_PadLeft + m_Param.m_PadRight) - filterWidth;
+ unsigned int dilatedFilterWidth = filterWidth + (m_Param.m_DilationX - 1) * (filterWidth - 1);
+ unsigned int readWidth = (inputWidth + m_Param.m_PadLeft + m_Param.m_PadRight) - dilatedFilterWidth;
unsigned int outputWidth = 1 + (readWidth / m_Param.m_StrideX);
unsigned int outputChannels = inputChannels * depthMultiplier;
diff --git a/src/armnnTfLiteParser/TfLiteParser.cpp b/src/armnnTfLiteParser/TfLiteParser.cpp
index 0cc6f93f3a..fdb38122c2 100644
--- a/src/armnnTfLiteParser/TfLiteParser.cpp
+++ b/src/armnnTfLiteParser/TfLiteParser.cpp
@@ -228,24 +228,6 @@ void CheckBufferSize(TfLiteParser::BufferRawPtr bufferPtr,
#define CHECK_BUFFER_SIZE(BUFFER_PTR, TENSOR_INFO, BUFFER_ID) \
CheckBufferSize(BUFFER_PTR, TENSOR_INFO, BUFFER_ID, CHECK_LOCATION())
-uint32_t CheckDilation(const int32_t dilationFactor,
- size_t operatorIndex,
- const CheckLocation& location)
-{
- if (dilationFactor != 1)
- {
- std::stringstream ss;
- ss << "ArmNN only supports convolution layers with dilations [1,1,1,1] for operator with index "
- << operatorIndex << location.AsString();
- throw ParseException(ss.str());
- }
-
- return static_cast<uint32_t>(dilationFactor);
-}
-
-#define CHECK_DILATION(DILATION_FACTOR, OPERATOR_INDEX) \
- CheckDilation(DILATION_FACTOR, OPERATOR_INDEX, CHECK_LOCATION())
-
bool IsActivationSupported(tflite::ActivationFunctionType activationType)
{
switch(activationType)
@@ -297,6 +279,7 @@ std::vector<unsigned int> AsUnsignedVector(const std::vector<int32_t> & in)
void CalcPadding(uint32_t inputSize,
uint32_t filterSize,
uint32_t stride,
+ uint32_t dilation,
uint32_t& paddingFront,
uint32_t& paddingBack,
tflite::Padding padding)
@@ -306,7 +289,8 @@ void CalcPadding(uint32_t inputSize,
if (padding == tflite::Padding_SAME)
{
uint32_t outputSize = (inputSize + stride - 1) / stride;
- uint32_t temp = (outputSize - 1) * stride + filterSize;
+ uint32_t dilatedSize = filterSize + (dilation - 1) * (filterSize - 1);
+ uint32_t temp = (outputSize - 1) * stride + dilatedSize;
if (temp > inputSize)
{
paddingFront = (temp - inputSize) / 2;
@@ -722,9 +706,8 @@ void TfLiteParser::ParseConv2D(size_t subgraphIndex, size_t operatorIndex)
desc.m_StrideX = CHECKED_NON_NEGATIVE(options->stride_w);
desc.m_StrideY = CHECKED_NON_NEGATIVE(options->stride_h);
desc.m_DataLayout = armnn::DataLayout::NHWC;
-
- CHECK_DILATION(options->dilation_h_factor, operatorIndex);
- CHECK_DILATION(options->dilation_w_factor, operatorIndex);
+ desc.m_DilationX = CHECKED_NON_NEGATIVE(options->dilation_w_factor);
+ desc.m_DilationY = CHECKED_NON_NEGATIVE(options->dilation_h_factor);
auto inputs = GetInputs(m_Model, subgraphIndex, operatorIndex);
CHECK_VALID_SIZE(inputs.size(), 2, 3);
@@ -744,8 +727,10 @@ void TfLiteParser::ParseConv2D(size_t subgraphIndex, size_t operatorIndex)
unsigned int filterHeight = filterTensorInfo.GetShape()[1];
unsigned int filterWidth = filterTensorInfo.GetShape()[2];
- CalcPadding(inputHeight, filterHeight, desc.m_StrideY, desc.m_PadTop, desc.m_PadBottom, options->padding);
- CalcPadding(inputWidth, filterWidth, desc.m_StrideX, desc.m_PadLeft, desc.m_PadRight, options->padding);
+ CalcPadding(inputHeight, filterHeight, desc.m_StrideY,
+ desc.m_DilationY, desc.m_PadTop, desc.m_PadBottom, options->padding);
+ CalcPadding(inputWidth, filterWidth, desc.m_StrideX,
+ desc.m_DilationX, desc.m_PadLeft, desc.m_PadRight, options->padding);
auto filterTensorAndData = CreateConstTensor(inputs[1],
filterTensorInfo,
@@ -810,9 +795,8 @@ void TfLiteParser::ParseDepthwiseConv2D(size_t subgraphIndex, size_t operatorInd
CHECK_VALID_SIZE(inputs.size(), 2, 3);
auto outputs = GetOutputs(m_Model, subgraphIndex, operatorIndex);
CHECK_VALID_SIZE(outputs.size(), 1);
-
- CHECK_DILATION(options->dilation_h_factor, operatorIndex);
- CHECK_DILATION(options->dilation_w_factor, operatorIndex);
+ desc.m_DilationX = CHECKED_NON_NEGATIVE(options->dilation_w_factor);
+ desc.m_DilationY = CHECKED_NON_NEGATIVE(options->dilation_h_factor);
armnn::TensorInfo inputTensorInfo = ToTensorInfo(inputs[0]);
armnn::TensorInfo filterTensorInfo = ToTensorInfo(inputs[1]);
@@ -834,8 +818,10 @@ void TfLiteParser::ParseDepthwiseConv2D(size_t subgraphIndex, size_t operatorInd
// Mappings from TensorflowLite filter tensors to the ArmNN filter tensors (ArmNN weights have to be [M, I, H, W])
PermutationVector permutationVector{ 2, 3, 1, 0 }; // [H, W, I, M] -> [M, I, H, W]
- CalcPadding(inputHeight, filterHeight, desc.m_StrideY, desc.m_PadTop, desc.m_PadBottom, options->padding);
- CalcPadding(inputWidth, filterWidth, desc.m_StrideX, desc.m_PadLeft, desc.m_PadRight, options->padding);
+ CalcPadding(inputHeight, filterHeight, desc.m_StrideY,
+ desc.m_DilationY, desc.m_PadTop, desc.m_PadBottom, options->padding);
+ CalcPadding(inputWidth, filterWidth, desc.m_StrideX,
+ desc.m_DilationX, desc.m_PadLeft, desc.m_PadRight, options->padding);
auto filterTensorAndData = CreateConstTensor(inputs[1], filterTensorInfo, permutationVector);
armnn::IConnectableLayer* layer;
@@ -1045,8 +1031,10 @@ void TfLiteParser::ParsePool(size_t subgraphIndex,
unsigned int inputHeight = inputTensorInfo.GetShape()[1];
unsigned int inputWidth = inputTensorInfo.GetShape()[2];
- CalcPadding(inputHeight, desc.m_PoolHeight, desc.m_StrideY, desc.m_PadTop, desc.m_PadBottom, options->padding);
- CalcPadding(inputWidth, desc.m_PoolWidth, desc.m_StrideX, desc.m_PadLeft, desc.m_PadRight, options->padding);
+ CalcPadding(inputHeight, desc.m_PoolHeight, desc.m_StrideY, 1u,
+ desc.m_PadTop, desc.m_PadBottom, options->padding);
+ CalcPadding(inputWidth, desc.m_PoolWidth, desc.m_StrideX, 1u,
+ desc.m_PadLeft, desc.m_PadRight, options->padding);
auto outputs = GetOutputs(m_Model, subgraphIndex, operatorIndex);
CHECK_VALID_SIZE(outputs.size(), 1);
diff --git a/src/backends/cl/ClLayerSupport.cpp b/src/backends/cl/ClLayerSupport.cpp
index a5c5f2bd9d..73c9e49c4f 100644
--- a/src/backends/cl/ClLayerSupport.cpp
+++ b/src/backends/cl/ClLayerSupport.cpp
@@ -246,6 +246,23 @@ bool ClLayerSupport::IsDepthwiseConvolutionSupported(const TensorInfo& input,
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 6393a11e84..e9a9e68005 100644
--- a/src/backends/cl/ClLayerSupport.hpp
+++ b/src/backends/cl/ClLayerSupport.hpp
@@ -61,6 +61,13 @@ public:
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 1ff0978a40..e681e95d90 100644
--- a/src/backends/cl/workloads/ClDepthwiseConvolutionWorkload.cpp
+++ b/src/backends/cl/workloads/ClDepthwiseConvolutionWorkload.cpp
@@ -52,13 +52,19 @@ arm_compute::Status ClDepthwiseConvolutionWorkloadValidate(const TensorInfo& inp
}
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 @@ ClDepthwiseConvolutionWorkload::ClDepthwiseConvolutionWorkload(
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 @@ ClDepthwiseConvolutionWorkload::ClDepthwiseConvolutionWorkload(
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 @@ ClDepthwiseConvolutionWorkload::ClDepthwiseConvolutionWorkload(
// 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 @@ ClDepthwiseConvolutionWorkload::ClDepthwiseConvolutionWorkload(
m_BiasTensor.get(),
&output,
padStrideInfo,
- depthMultiplier);
+ depthMultiplier,
+ arm_compute::ActivationLayerInfo(),
+ aclDilationInfo);
}
else
{
@@ -131,7 +145,10 @@ ClDepthwiseConvolutionWorkload::ClDepthwiseConvolutionWorkload(
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 898660cc91..c257dd373a 100644
--- a/src/backends/neon/NeonLayerSupport.cpp
+++ b/src/backends/neon/NeonLayerSupport.cpp
@@ -203,6 +203,22 @@ bool NeonLayerSupport::IsDepthwiseConvolutionSupported(const TensorInfo& input,
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 27e825afa9..a5aae0bde9 100644
--- a/src/backends/neon/NeonLayerSupport.hpp
+++ b/src/backends/neon/NeonLayerSupport.hpp
@@ -56,6 +56,13 @@ public:
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 c915555dd7..0b917fc530 100644
--- a/src/backends/neon/workloads/NeonDepthwiseConvolutionWorkload.cpp
+++ b/src/backends/neon/workloads/NeonDepthwiseConvolutionWorkload.cpp
@@ -52,14 +52,18 @@ arm_compute::Status NeonDepthwiseConvolutionWorkloadValidate(const TensorInfo& i
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 @@ NeonDepthwiseConvolutionWorkload::NeonDepthwiseConvolutionWorkload(
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 @@ NeonDepthwiseConvolutionWorkload::NeonDepthwiseConvolutionWorkload(
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 @@ NeonDepthwiseConvolutionWorkload::NeonDepthwiseConvolutionWorkload(
m_BiasTensor.get(),
&output,
padStrideInfo,
- depthMultiplier);
+ depthMultiplier,
+ arm_compute::ActivationLayerInfo(),
+ aclDilationInfo);
}
else
{
@@ -134,7 +144,9 @@ NeonDepthwiseConvolutionWorkload::NeonDepthwiseConvolutionWorkload(
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 8eded84e09..a1d8e7de81 100644
--- a/src/backends/reference/RefLayerSupport.cpp
+++ b/src/backends/reference/RefLayerSupport.cpp
@@ -429,7 +429,29 @@ bool RefLayerSupport::IsDetectionPostProcessSupported(const armnn::TensorInfo& i
&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 53a1abf150..9b1a95cdcd 100644
--- a/src/backends/reference/RefLayerSupport.hpp
+++ b/src/backends/reference/RefLayerSupport.hpp
@@ -74,6 +74,14 @@ public:
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,