diff options
author | giuros01 <giuseppe.rossini@arm.com> | 2019-01-31 16:29:19 +0000 |
---|---|---|
committer | Giuseppe Rossini <giuseppe.rossini@arm.com> | 2019-02-06 17:27:09 +0000 |
commit | a69a88b0b69c4c4018562afcfd560ae94412ec99 (patch) | |
tree | 18b0b80e7de07846790c533697794a95b96ca034 /tests | |
parent | 99089cecf88d5e5f334c220183ae0cd25c92a2d4 (diff) | |
download | ComputeLibrary-a69a88b0b69c4c4018562afcfd560ae94412ec99.tar.gz |
COMPMID-1915: Deconvolution doesn't work when inner_dimension_top != 0 or inner_dimension_right != 0
Change-Id: Ia0533cfb34878fc81e929eb405c49e46609d26b8
Signed-off-by: giuros01 <giuseppe.rossini@arm.com>
Reviewed-on: https://review.mlplatform.org/616
Reviewed-by: Georgios Pinitas <georgios.pinitas@arm.com>
Tested-by: Arm Jenkins <bsgcomp@arm.com>
Diffstat (limited to 'tests')
-rw-r--r-- | tests/validation/CL/DeconvolutionLayer.cpp | 28 | ||||
-rw-r--r-- | tests/validation/NEON/DeconvolutionLayer.cpp | 8 | ||||
-rw-r--r-- | tests/validation/fixtures/DeconvolutionLayerFixture.h | 42 | ||||
-rw-r--r-- | tests/validation/reference/DeconvolutionLayer.cpp | 23 | ||||
-rw-r--r-- | tests/validation/reference/DeconvolutionLayer.h | 5 |
5 files changed, 52 insertions, 54 deletions
diff --git a/tests/validation/CL/DeconvolutionLayer.cpp b/tests/validation/CL/DeconvolutionLayer.cpp index 46a229bb39..31852c8eb6 100644 --- a/tests/validation/CL/DeconvolutionLayer.cpp +++ b/tests/validation/CL/DeconvolutionLayer.cpp @@ -50,16 +50,16 @@ constexpr AbsoluteTolerance<float> tolerance_qasymm8(0.0); /**< T constexpr float tolerance_num = 0.07f; /**< Tolerance number */ const auto data4x4 = datasets::SmallDeconvolutionShapes() * framework::dataset::make("StrideX", 1, 4) * framework::dataset::make("StrideY", 1, 4) * framework::dataset::make("PadX", 0, 3) - * framework::dataset::make("PadY", 0, 3) * framework::dataset::make("ax", 0) * framework::dataset::make("ay", 0) * framework::dataset::make("NumKernels", { 3 }); + * framework::dataset::make("PadY", 0, 3) * framework::dataset::make("NumKernels", { 3 }); const auto data3x3 = datasets::SmallDeconvolutionShapes() * framework::dataset::make("StrideX", 1, 4) * framework::dataset::make("StrideY", 1, 4) * framework::dataset::make("PadX", 0, 2) - * framework::dataset::make("PadY", 0, 2) * framework::dataset::make("ax", 0) * framework::dataset::make("ay", 0) * framework::dataset::make("NumKernels", { 3 }); + * framework::dataset::make("PadY", 0, 2) * framework::dataset::make("NumKernels", { 3 }); const auto data3x3_precommit = datasets::SmallDeconvolutionShapes() * framework::dataset::make("StrideX", 1, 2) * framework::dataset::make("StrideY", 1, 2) * framework::dataset::make("PadX", 0, 2) - * framework::dataset::make("PadY", 0, 2) * framework::dataset::make("ax", 0) * framework::dataset::make("ay", 0) * framework::dataset::make("NumKernels", { 3 }); + * framework::dataset::make("PadY", 0, 2) * framework::dataset::make("NumKernels", { 3 }); const auto data1x1 = datasets::SmallDeconvolutionShapes() * framework::dataset::make("StrideX", 1, 4) * framework::dataset::make("StrideY", 1, 4) * framework::dataset::make("PadX", 0, 1) - * framework::dataset::make("PadY", 0, 1) * framework::dataset::make("ax", 0) * framework::dataset::make("ay", 0) * framework::dataset::make("NumKernels", { 3 }); + * framework::dataset::make("PadY", 0, 1) * framework::dataset::make("NumKernels", { 3 }); const auto data_layouts_dataset = framework::dataset::make("DataLayout", { DataLayout::NCHW }); } // namespace @@ -74,12 +74,14 @@ DATA_TEST_CASE(Validate, framework::DatasetMode::ALL, zip(zip(zip(zip(zip(zip(zi TensorInfo(TensorShape(27U, 13U, 2U), 1, DataType::F32), // Invalid weights shape TensorInfo(TensorShape(27U, 13U, 2U), 1, DataType::F32), // Invalid bias shape TensorInfo(TensorShape(13U, 11U, 4U, 3U), 1, DataType::F32), // Window shrink + TensorInfo(TensorShape(32U, 16U, 2U), 1, DataType::F32), // Inner border different from 0 TensorInfo(TensorShape(32U, 16U, 2U), 1, DataType::F32), }), framework::dataset::make("WeightsInfo", { TensorInfo(TensorShape(3U, 3U, 2U, 2U), 1, DataType::F16), TensorInfo(TensorShape(3U, 3U, 2U, 4U), 1, DataType::F32), TensorInfo(TensorShape(3U, 2U, 2U, 2U), 1, DataType::F32), TensorInfo(TensorShape(3U, 3U, 4U), 1, DataType::F32), + TensorInfo(TensorShape(1U, 1U, 2U, 4U), 1, DataType::F32), TensorInfo(TensorShape(1U, 1U, 2U, 4U), 1, DataType::F32), })), framework::dataset::make("BiasInfo", { TensorInfo(TensorShape(1U), 1, DataType::F16), @@ -88,32 +90,36 @@ DATA_TEST_CASE(Validate, framework::DatasetMode::ALL, zip(zip(zip(zip(zip(zip(zi TensorInfo(TensorShape(1U), 1, DataType::F32), TensorInfo(TensorShape(4U), 1, DataType::F32), TensorInfo(TensorShape(4U), 1, DataType::S32), + TensorInfo(TensorShape(4U), 1, DataType::S32), })), framework::dataset::make("OutputInfo",{ TensorInfo(TensorShape(25U, 11U, 2U), 1, DataType::F16), TensorInfo(TensorShape(25U, 10U, 2U), 1, DataType::F32), TensorInfo(TensorShape(13U, 13U, 2U), 1, DataType::F32), TensorInfo(TensorShape(11U, 9U, 1U, 3U), 1, DataType::F32), TensorInfo(TensorShape(32U, 16U, 4U), 1, DataType::F32), + TensorInfo(TensorShape(32U, 16U, 4U), 1, DataType::F32), })), framework::dataset::make("PadStrideInfo", { PadStrideInfo(1, 1, 0, 0), PadStrideInfo(1, 1, 0, 0), PadStrideInfo(1, 1, 0, 0), PadStrideInfo(1, 1, 1, 1), PadStrideInfo(1, 1, 0, 0), + PadStrideInfo(1, 1, 0, 0), })), - framework::dataset::make("ax", { 1U, - 1U, - 1U, + framework::dataset::make("ax", { 0U, + 0U, + 0U, 0U, 0U, })), - framework::dataset::make("ay", { 1U, - 1U, - 1U, + framework::dataset::make("ay", { 0U, 0U, 0U, + 0U, + 1U, + 0U, })), - framework::dataset::make("Expected", { false, false, false, false, true })), + framework::dataset::make("Expected", { false, false, false, false, false, true })), input_info, weights_info, bias_info, output_info, pad_info, ax, ay, expected) { bool is_valid = bool(CLDeconvolutionLayer::validate(&input_info.clone()->set_is_resizable(false), &weights_info.clone()->set_is_resizable(false), &bias_info.clone()->set_is_resizable(false), &output_info.clone()->set_is_resizable(false), pad_info, ax, ay)); diff --git a/tests/validation/NEON/DeconvolutionLayer.cpp b/tests/validation/NEON/DeconvolutionLayer.cpp index 9a3ed30241..4a05535e09 100644 --- a/tests/validation/NEON/DeconvolutionLayer.cpp +++ b/tests/validation/NEON/DeconvolutionLayer.cpp @@ -46,16 +46,16 @@ namespace constexpr AbsoluteTolerance<float> tolerance_fp32(0.001f); /**< Tolerance for floating point tests */ const auto data4x4 = datasets::SmallDeconvolutionShapes() * framework::dataset::make("StrideX", 1, 4) * framework::dataset::make("StrideY", 1, 4) * framework::dataset::make("PadX", 0, 3) - * framework::dataset::make("PadY", 0, 3) * framework::dataset::make("ax", 0) * framework::dataset::make("ay", 0) * framework::dataset::make("NumKernels", { 3 }); + * framework::dataset::make("PadY", 0, 3) * framework::dataset::make("NumKernels", { 3 }); const auto data3x3 = datasets::SmallDeconvolutionShapes() * framework::dataset::make("StrideX", 1, 4) * framework::dataset::make("StrideY", 1, 4) * framework::dataset::make("PadX", 0, 2) - * framework::dataset::make("PadY", 0, 2) * framework::dataset::make("ax", 0) * framework::dataset::make("ay", 0) * framework::dataset::make("NumKernels", { 3 }); + * framework::dataset::make("PadY", 0, 2) * framework::dataset::make("NumKernels", { 3 }); const auto data3x3_precommit = datasets::SmallDeconvolutionShapes() * framework::dataset::make("StrideX", 1, 2) * framework::dataset::make("StrideY", 1, 2) * framework::dataset::make("PadX", 0, 2) - * framework::dataset::make("PadY", 0, 2) * framework::dataset::make("ax", 0) * framework::dataset::make("ay", 0) * framework::dataset::make("NumKernels", { 3 }); + * framework::dataset::make("PadY", 0, 2) * framework::dataset::make("NumKernels", { 3 }); const auto data1x1 = datasets::SmallDeconvolutionShapes() * framework::dataset::make("StrideX", 1, 4) * framework::dataset::make("StrideY", 1, 4) * framework::dataset::make("PadX", 0, 1) - * framework::dataset::make("PadY", 0, 1) * framework::dataset::make("ax", 0) * framework::dataset::make("ay", 0) * framework::dataset::make("NumKernels", { 3 }); + * framework::dataset::make("PadY", 0, 1) * framework::dataset::make("NumKernels", { 3 }); const auto data_layouts_dataset = framework::dataset::make("DataLayout", { DataLayout::NCHW }); } // namespace diff --git a/tests/validation/fixtures/DeconvolutionLayerFixture.h b/tests/validation/fixtures/DeconvolutionLayerFixture.h index 85c7ed5604..8f15f04f0e 100644 --- a/tests/validation/fixtures/DeconvolutionLayerFixture.h +++ b/tests/validation/fixtures/DeconvolutionLayerFixture.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2018 ARM Limited. + * Copyright (c) 2017-2019 ARM Limited. * * SPDX-License-Identifier: MIT * @@ -51,15 +51,15 @@ public: public: template <typename...> void setup(TensorShape input_shape, TensorShape weights_shape, TensorShape bias_shape, TensorShape output_shape, PadStrideInfo info, - const std::pair<unsigned int, unsigned int> &inner_border, DataType data_type, DataLayout data_layout, QuantizationInfo quantization_info) + DataType data_type, DataLayout data_layout, QuantizationInfo quantization_info) { _data_type = data_type; _bias_data_type = is_data_type_quantized_asymmetric(data_type) ? DataType::S32 : data_type; _data_layout = data_layout; _quantization_info = quantization_info; - _target = compute_target(input_shape, weights_shape, bias_shape, output_shape, info, inner_border); - _reference = compute_reference(input_shape, weights_shape, bias_shape, output_shape, info, inner_border); + _target = compute_target(input_shape, weights_shape, bias_shape, output_shape, info); + _reference = compute_reference(input_shape, weights_shape, bias_shape, output_shape, info); } protected: @@ -94,7 +94,7 @@ protected: } TensorType compute_target(TensorShape input_shape, TensorShape weights_shape, const TensorShape bias_shape, TensorShape output_shape, - const PadStrideInfo &info, const std::pair<unsigned int, unsigned int> &inner_border) + const PadStrideInfo &info) { if(_data_layout == DataLayout::NHWC) { @@ -111,7 +111,7 @@ protected: // Create and configure function FunctionType conv; - conv.configure(&src, &weights, &bias, &dst, info, inner_border.first, inner_border.second); + conv.configure(&src, &weights, &bias, &dst, info); ARM_COMPUTE_EXPECT(src.info()->is_resizable(), framework::LogLevel::ERRORS); ARM_COMPUTE_EXPECT(weights.info()->is_resizable(), framework::LogLevel::ERRORS); @@ -141,7 +141,7 @@ protected: } SimpleTensor<T> compute_reference(const TensorShape &input_shape, const TensorShape &weights_shape, const TensorShape &bias_shape, const TensorShape &output_shape, - const PadStrideInfo &info, const std::pair<unsigned int, unsigned int> inner_border) + const PadStrideInfo &info) { // Create reference SimpleTensor<T> src{ input_shape, _data_type, 1, _quantization_info }; @@ -153,7 +153,7 @@ protected: fill(weights, 1); fill(bias, 2); - return reference::deconvolution_layer<T>(src, weights, bias, output_shape, info, inner_border); + return reference::deconvolution_layer<T>(src, weights, bias, output_shape, info); } TensorType _target{}; @@ -170,18 +170,17 @@ class DeconvolutionValidationFixture : public DeconvolutionLayerFixtureBase<Tens public: template <typename...> void setup(TensorShape input_shape, unsigned int sx, unsigned int sy, unsigned int padx, unsigned int pady, - unsigned int inner_border_right, unsigned int inner_border_top, unsigned int num_kernels, DataType data_type, DataLayout data_layout) + unsigned int num_kernels, DataType data_type, DataLayout data_layout) { ARM_COMPUTE_ERROR_ON_MSG(kernel_size_x != kernel_size_y, "Only square kernels supported"); const TensorShape weights_shape(kernel_size_x, kernel_size_y, input_shape.z(), num_kernels); const TensorShape bias_shape(num_kernels); const PadStrideInfo info(sx, sy, padx, pady, DimensionRoundingType::CEIL); - const std::pair<unsigned int, unsigned int> inner_border(inner_border_right, inner_border_top); - auto out_dim = deconvolution_output_dimensions(input_shape.x(), input_shape.y(), kernel_size_x, kernel_size_y, padx, pady, sx, sy); - TensorInfo input_info(input_shape, 1, data_type); - TensorInfo weights_info(weights_shape, 1, data_type); - TensorShape output_shape = compute_deconvolution_output_shape(out_dim, input_info, weights_info); - DeconvolutionLayerFixtureBase<TensorType, AccessorType, FunctionType, T>::setup(input_shape, weights_shape, bias_shape, output_shape, info, inner_border, data_type, data_layout, QuantizationInfo()); + auto out_dim = deconvolution_output_dimensions(input_shape.x(), input_shape.y(), kernel_size_x, kernel_size_y, padx, pady, sx, sy); + TensorInfo input_info(input_shape, 1, data_type); + TensorInfo weights_info(weights_shape, 1, data_type); + TensorShape output_shape = compute_deconvolution_output_shape(out_dim, input_info, weights_info); + DeconvolutionLayerFixtureBase<TensorType, AccessorType, FunctionType, T>::setup(input_shape, weights_shape, bias_shape, output_shape, info, data_type, data_layout, QuantizationInfo()); } }; @@ -191,18 +190,17 @@ class DeconvolutionValidationQuantizedFixture : public DeconvolutionLayerFixture public: template <typename...> void setup(TensorShape input_shape, unsigned int sx, unsigned int sy, unsigned int padx, unsigned int pady, - unsigned int inner_border_right, unsigned int inner_border_top, unsigned int num_kernels, DataType data_type, DataLayout data_layout, QuantizationInfo quantization_info) + unsigned int num_kernels, DataType data_type, DataLayout data_layout, QuantizationInfo quantization_info) { ARM_COMPUTE_ERROR_ON_MSG(kernel_size_x != kernel_size_y, "Only square kernels supported"); const TensorShape weights_shape(kernel_size_x, kernel_size_y, input_shape.z(), num_kernels); const TensorShape bias_shape(num_kernels); const PadStrideInfo info(sx, sy, padx, pady, DimensionRoundingType::CEIL); - const std::pair<unsigned int, unsigned int> inner_border(inner_border_right, inner_border_top); - auto out_dim = deconvolution_output_dimensions(input_shape.x(), input_shape.y(), kernel_size_x, kernel_size_y, padx, pady, sx, sy); - TensorInfo input_info(input_shape, 1, data_type, quantization_info); - TensorInfo weights_info(weights_shape, 1, data_type, quantization_info); - TensorShape output_shape = compute_deconvolution_output_shape(out_dim, input_info, weights_info); - DeconvolutionLayerFixtureBase<TensorType, AccessorType, FunctionType, T>::setup(input_shape, weights_shape, bias_shape, output_shape, info, inner_border, data_type, data_layout, quantization_info); + auto out_dim = deconvolution_output_dimensions(input_shape.x(), input_shape.y(), kernel_size_x, kernel_size_y, padx, pady, sx, sy); + TensorInfo input_info(input_shape, 1, data_type, quantization_info); + TensorInfo weights_info(weights_shape, 1, data_type, quantization_info); + TensorShape output_shape = compute_deconvolution_output_shape(out_dim, input_info, weights_info); + DeconvolutionLayerFixtureBase<TensorType, AccessorType, FunctionType, T>::setup(input_shape, weights_shape, bias_shape, output_shape, info, data_type, data_layout, quantization_info); } }; diff --git a/tests/validation/reference/DeconvolutionLayer.cpp b/tests/validation/reference/DeconvolutionLayer.cpp index 5ca3b44baa..916792479f 100644 --- a/tests/validation/reference/DeconvolutionLayer.cpp +++ b/tests/validation/reference/DeconvolutionLayer.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2018 ARM Limited. + * Copyright (c) 2017-2019 ARM Limited. * * SPDX-License-Identifier: MIT * @@ -35,7 +35,7 @@ namespace reference { template <typename T, typename TB> SimpleTensor<T> deconvolution_layer(const SimpleTensor<T> &src, const SimpleTensor<T> &weights, const SimpleTensor<TB> &bias, const TensorShape &output_shape, - const PadStrideInfo &info, const std::pair<unsigned int, unsigned int> &a) + const PadStrideInfo &info) { // Create reference const int stride_x = info.stride().first; @@ -45,8 +45,8 @@ SimpleTensor<T> deconvolution_layer(const SimpleTensor<T> &src, const SimpleTens const int weights_upper_dims = weights.shape().total_size() / (weights_width * weights_height); // Find the upsampled dimensions - unsigned int out_x = (src.shape().x() - 1) * stride_x + a.first + 1; - unsigned int out_y = (src.shape().y() - 1) * stride_y + a.second + 1; + unsigned int out_x = (src.shape().x() - 1) * stride_x + 1; + unsigned int out_y = (src.shape().y() - 1) * stride_y + 1; // Find the padding needed for the convolution with stride 1 in order to match output shape unsigned int padx = output_shape.x() - (out_x - weights_width + 1); @@ -64,13 +64,8 @@ SimpleTensor<T> deconvolution_layer(const SimpleTensor<T> &src, const SimpleTens const int width_scaled = scaled.shape().x(); const int height_scaled = scaled.shape().y(); const int num_2d_slices = src.shape().total_size() / (width_in * height_in); - const int ax = a.first; // The number of zeros added to right edge of the input. - const int ay = a.second; // The number of zeros added to top edge of the input. ARM_COMPUTE_ERROR_ON(info.pad().first > (weights.shape().x() - 1)); - ARM_COMPUTE_ERROR_ON_MSG(ax > stride_x - 1, "ax must be smaller than stride_x"); - ARM_COMPUTE_ERROR_ON_MSG(ay > stride_y - 1, "ay must be smaller than stride_y"); - if(src.data_type() == DataType::QASYMM8) { const uint8_t quantized_zero = src.quantization_info().offset; @@ -100,9 +95,9 @@ SimpleTensor<T> deconvolution_layer(const SimpleTensor<T> &src, const SimpleTens const int offset_slice_in = slice * width_in * height_in; const int offset_slice_out = slice * width_scaled * height_scaled; const int start_x = padx / 2; - const int start_y = ay + pady / 2; + const int start_y = pady / 2; const int end_y = height_scaled - pady / 2; - const int end_x = width_scaled - ax - padx / 2; + const int end_x = width_scaled - padx / 2; for(int yi = start_y, in_y = 0; yi < end_y; yi += stride_y, in_y++) { @@ -120,11 +115,11 @@ SimpleTensor<T> deconvolution_layer(const SimpleTensor<T> &src, const SimpleTens } template SimpleTensor<uint8_t> deconvolution_layer(const SimpleTensor<uint8_t> &src, const SimpleTensor<uint8_t> &weights, const SimpleTensor<int32_t> &bias, const TensorShape &output_shape, - const PadStrideInfo &info, const std::pair<unsigned int, unsigned int> &a); + const PadStrideInfo &info); template SimpleTensor<float> deconvolution_layer(const SimpleTensor<float> &src, const SimpleTensor<float> &weights, const SimpleTensor<float> &bias, const TensorShape &output_shape, - const PadStrideInfo &info, const std::pair<unsigned int, unsigned int> &a); + const PadStrideInfo &info); template SimpleTensor<half> deconvolution_layer(const SimpleTensor<half> &src, const SimpleTensor<half> &weights, const SimpleTensor<half> &bias, const TensorShape &output_shape, - const PadStrideInfo &info, const std::pair<unsigned int, unsigned int> &a); + const PadStrideInfo &info); } // namespace reference } // namespace validation } // namespace test diff --git a/tests/validation/reference/DeconvolutionLayer.h b/tests/validation/reference/DeconvolutionLayer.h index 95fb416b30..21583e3b12 100644 --- a/tests/validation/reference/DeconvolutionLayer.h +++ b/tests/validation/reference/DeconvolutionLayer.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2018 ARM Limited. + * Copyright (c) 2017-2019 ARM Limited. * * SPDX-License-Identifier: MIT * @@ -46,8 +46,7 @@ namespace reference * */ template <typename T, typename TB> -SimpleTensor<T> deconvolution_layer(const SimpleTensor<T> &src, const SimpleTensor<T> &weights, const SimpleTensor<TB> &bias, const TensorShape &output_shape, const PadStrideInfo &info, - const std::pair<unsigned int, unsigned int> &a); +SimpleTensor<T> deconvolution_layer(const SimpleTensor<T> &src, const SimpleTensor<T> &weights, const SimpleTensor<TB> &bias, const TensorShape &output_shape, const PadStrideInfo &info); } // namespace reference } // namespace validation } // namespace test |