aboutsummaryrefslogtreecommitdiff
path: root/src/core
diff options
context:
space:
mode:
authorMatthew Jackson <matthew.jackson@arm.com>2019-08-22 16:13:27 +0100
committerMatthew Jackson <matthew.jackson@arm.com>2019-08-28 09:22:18 +0000
commitb9070a42a44ec1a0102e2f0b04523d2e96392903 (patch)
tree476ae6897e26380a00e4ccfdcd315d6b6f884622 /src/core
parent275f99cb09606191c5589952d57175be655de74a (diff)
downloadComputeLibrary-b9070a42a44ec1a0102e2f0b04523d2e96392903.tar.gz
COMPMID-2605: Add asymmetric padding support for Deconvolution layer
Change-Id: I63b773bdce25f1342ccd3a08ded623a1508f70fe Signed-off-by: Matthew Jackson <matthew.jackson@arm.com> Reviewed-on: https://review.mlplatform.org/c/1797 Comments-Addressed: Arm Jenkins <bsgcomp@arm.com> Tested-by: Arm Jenkins <bsgcomp@arm.com> Reviewed-by: Michele Di Giorgio <michele.digiorgio@arm.com> Reviewed-by: Giuseppe Rossini <giuseppe.rossini@arm.com>
Diffstat (limited to 'src/core')
-rw-r--r--src/core/CL/kernels/CLDeconvolutionLayerUpsampleKernel.cpp9
-rw-r--r--src/core/CL/kernels/CLDeconvolutionReshapeOutputKernel.cpp17
-rw-r--r--src/core/CPP/kernels/CPPUpsampleKernel.cpp8
-rw-r--r--src/core/Utils.cpp21
4 files changed, 28 insertions, 27 deletions
diff --git a/src/core/CL/kernels/CLDeconvolutionLayerUpsampleKernel.cpp b/src/core/CL/kernels/CLDeconvolutionLayerUpsampleKernel.cpp
index 50f654680c..4ae9cabd1f 100644
--- a/src/core/CL/kernels/CLDeconvolutionLayerUpsampleKernel.cpp
+++ b/src/core/CL/kernels/CLDeconvolutionLayerUpsampleKernel.cpp
@@ -56,7 +56,6 @@ Status CLDeconvolutionLayerUpsampleKernel::validate(const ITensorInfo *input, co
ARM_COMPUTE_RETURN_ERROR_ON(output->dimension(idx_w) == 0);
ARM_COMPUTE_RETURN_ERROR_ON(output->dimension(idx_h) == 0);
- ARM_COMPUTE_RETURN_ERROR_ON(!info.padding_is_symmetric());
ARM_COMPUTE_RETURN_ERROR_ON(input->dimension(idx_c) != output->dimension(idx_c));
for(size_t i = 3; i < Coordinates::num_max_dimensions; ++i)
@@ -104,12 +103,12 @@ void CLDeconvolutionLayerUpsampleKernel::run(const Window &window, cl::CommandQu
const size_t idx_w = get_data_layout_dimension_index(data_layout, DataLayoutDimension::WIDTH);
const size_t idx_h = get_data_layout_dimension_index(data_layout, DataLayoutDimension::HEIGHT);
- const int out_start_x = _info.pad().first;
- const int out_end_x = _output->info()->dimension(idx_w) - _info.pad().first + _info.stride().first - 1;
+ const int out_start_x = _info.pad_left();
+ const int out_end_x = _output->info()->dimension(idx_w) - _info.pad_right() + _info.stride().first - 1;
const int out_step_x = _info.stride().first;
- const int out_start_y = _info.pad().second;
- const int out_end_y = _output->info()->dimension(idx_h) - _info.pad().second + _info.stride().second - 1;
+ const int out_start_y = _info.pad_top();
+ const int out_end_y = _output->info()->dimension(idx_h) - _info.pad_bottom() + _info.stride().second - 1;
const int out_step_y = _info.stride().second;
switch(data_layout)
diff --git a/src/core/CL/kernels/CLDeconvolutionReshapeOutputKernel.cpp b/src/core/CL/kernels/CLDeconvolutionReshapeOutputKernel.cpp
index 71218f5b52..69e5eff213 100644
--- a/src/core/CL/kernels/CLDeconvolutionReshapeOutputKernel.cpp
+++ b/src/core/CL/kernels/CLDeconvolutionReshapeOutputKernel.cpp
@@ -40,8 +40,6 @@ Status validate_arguments(const ITensorInfo *input, const ITensorInfo *bias, con
{
ARM_COMPUTE_RETURN_ERROR_ON_NULLPTR(input, output, input_info, weights_info);
const DataLayout data_layout = input_info->data_layout();
- const unsigned int stride_x = deconv_info.stride().first;
- const unsigned int stride_y = deconv_info.stride().second;
const size_t idx_w = get_data_layout_dimension_index(data_layout, DataLayoutDimension::WIDTH);
const size_t idx_h = get_data_layout_dimension_index(data_layout, DataLayoutDimension::HEIGHT);
@@ -77,8 +75,8 @@ Status validate_arguments(const ITensorInfo *input, const ITensorInfo *bias, con
if(output->total_size() != 0)
{
- auto out_dims = deconvolution_output_dimensions(input_info->dimension(idx_w), input_info->dimension(idx_h), weights_info->dimension(idx_w), weights_info->dimension(idx_h),
- 0, 0, stride_x, stride_y);
+ const PadStrideInfo stride_info(deconv_info.stride().first, deconv_info.stride().second);
+ auto out_dims = deconvolution_output_dimensions(input_info->dimension(idx_w), input_info->dimension(idx_h), weights_info->dimension(idx_w), weights_info->dimension(idx_h), stride_info);
const TensorShape output_shape = misc::shape_calculator::compute_deconvolution_output_shape(out_dims, *input_info, *weights_info);
@@ -92,14 +90,11 @@ std::pair<Status, Window> validate_and_configure_window(const ITensorInfo *input
ARM_COMPUTE_ERROR_ON_NULLPTR(input, output);
const DataLayout data_layout = input_info->data_layout();
+ const size_t idx_w = get_data_layout_dimension_index(data_layout, DataLayoutDimension::WIDTH);
+ const size_t idx_h = get_data_layout_dimension_index(data_layout, DataLayoutDimension::HEIGHT);
+ const PadStrideInfo stride_info(deconv_info.stride().first, deconv_info.stride().second);
- const unsigned int stride_x = deconv_info.stride().first;
- const unsigned int stride_y = deconv_info.stride().second;
- const size_t idx_w = get_data_layout_dimension_index(data_layout, DataLayoutDimension::WIDTH);
- const size_t idx_h = get_data_layout_dimension_index(data_layout, DataLayoutDimension::HEIGHT);
-
- auto out_dims = deconvolution_output_dimensions(input_info->dimension(idx_w), input_info->dimension(idx_h), weights_info->dimension(idx_w), weights_info->dimension(idx_h),
- 0, 0, stride_x, stride_y);
+ auto out_dims = deconvolution_output_dimensions(input_info->dimension(idx_w), input_info->dimension(idx_h), weights_info->dimension(idx_w), weights_info->dimension(idx_h), stride_info);
const TensorShape output_shape = misc::shape_calculator::compute_deconvolution_output_shape(out_dims, *input_info, *weights_info);
diff --git a/src/core/CPP/kernels/CPPUpsampleKernel.cpp b/src/core/CPP/kernels/CPPUpsampleKernel.cpp
index ad2d54a0f8..e63808f80e 100644
--- a/src/core/CPP/kernels/CPPUpsampleKernel.cpp
+++ b/src/core/CPP/kernels/CPPUpsampleKernel.cpp
@@ -76,10 +76,10 @@ void CPPUpsampleKernel::run(const Window &window, const ThreadInfo &info)
const int height_scaled = _output->info()->dimension(1);
const int stride_x = _info.stride().first;
const int stride_y = _info.stride().second;
- const int start_x = _info.pad().first;
- const int start_y = _info.pad().second;
- const int end_y = height_scaled - _info.pad().second;
- const int end_x = width_scaled - _info.pad().first;
+ const int start_x = _info.pad_left();
+ const int start_y = _info.pad_top();
+ const int end_x = width_scaled - _info.pad_right();
+ const int end_y = height_scaled - _info.pad_bottom();
const size_t element_size = _input->info()->element_size();
//The fill value is normally 0, but for QASYMM8 the '0' corresponds to the offset
diff --git a/src/core/Utils.cpp b/src/core/Utils.cpp
index 122373f5c6..d11788acd3 100644
--- a/src/core/Utils.cpp
+++ b/src/core/Utils.cpp
@@ -374,15 +374,22 @@ PadStrideInfo arm_compute::calculate_same_pad(TensorShape input_shape, TensorSha
return same_info;
}
-std::pair<unsigned int, unsigned int> arm_compute::deconvolution_output_dimensions(
- unsigned int in_width, unsigned int in_height, unsigned int kernel_width, unsigned int kernel_height, unsigned int padx, unsigned int pady,
- unsigned int stride_x, unsigned int stride_y)
+std::pair<unsigned int, unsigned int> arm_compute::deconvolution_output_dimensions(unsigned int in_width, unsigned int in_height,
+ unsigned int kernel_width, unsigned int kernel_height,
+ const PadStrideInfo &pad_stride_info)
{
+ const unsigned int pad_left = pad_stride_info.pad_left();
+ const unsigned int pad_top = pad_stride_info.pad_top();
+ const unsigned int pad_right = pad_stride_info.pad_right();
+ const unsigned int pad_bottom = pad_stride_info.pad_bottom();
+ const unsigned int stride_x = pad_stride_info.stride().first;
+ const unsigned int stride_y = pad_stride_info.stride().second;
+
ARM_COMPUTE_ERROR_ON(in_width < 1 || in_height < 1);
- ARM_COMPUTE_ERROR_ON(((in_width - 1) * stride_x + kernel_width) < 2 * padx);
- ARM_COMPUTE_ERROR_ON(((in_height - 1) * stride_y + kernel_height) < 2 * pady);
- const int w = stride_x * (in_width - 1) + kernel_width - 2 * padx;
- const int h = stride_y * (in_height - 1) + kernel_height - 2 * pady;
+ ARM_COMPUTE_ERROR_ON(((in_width - 1) * stride_x + kernel_width) < (pad_left + pad_right));
+ ARM_COMPUTE_ERROR_ON(((in_height - 1) * stride_y + kernel_height) < (pad_top + pad_bottom));
+ const int w = stride_x * (in_width - 1) + kernel_width - (pad_left + pad_right);
+ const int h = stride_y * (in_height - 1) + kernel_height - (pad_top + pad_bottom);
return std::make_pair<unsigned int, unsigned int>(w, h);
}