From e73686ac797be2d19cd9bed26d690e1431e3d848 Mon Sep 17 00:00:00 2001 From: Usama Arif Date: Mon, 8 Apr 2019 17:30:48 +0100 Subject: COMPMID-2047: Add support for dilation in CLDepthwiseConvolution. Change-Id: I3106aa34bd168985a56791613d95072756be6e9b Signed-off-by: Usama Arif Reviewed-on: https://review.mlplatform.org/c/958 Comments-Addressed: Arm Jenkins Reviewed-by: Pablo Marquez Tested-by: Arm Jenkins --- .../fixtures/DepthwiseConvolutionLayerFixture.h | 4 +- tests/datasets/DepthwiseConvolutionLayerDataset.h | 23 +- .../DilatedDepthwiseConvolutionLayerDataset.h | 139 +++++++++++ tests/validation/CL/DepthwiseConvolutionLayer.cpp | 260 ++++++++++++++++++--- .../fixtures/DepthwiseConvolutionLayerFixture.h | 29 +-- .../reference/DepthwiseConvolutionLayer.cpp | 53 +++-- 6 files changed, 437 insertions(+), 71 deletions(-) create mode 100644 tests/datasets/DilatedDepthwiseConvolutionLayerDataset.h (limited to 'tests') diff --git a/tests/benchmark/fixtures/DepthwiseConvolutionLayerFixture.h b/tests/benchmark/fixtures/DepthwiseConvolutionLayerFixture.h index 48ea03810f..33753bcd07 100644 --- a/tests/benchmark/fixtures/DepthwiseConvolutionLayerFixture.h +++ b/tests/benchmark/fixtures/DepthwiseConvolutionLayerFixture.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2018 ARM Limited. + * Copyright (c) 2017-2019 ARM Limited. * * SPDX-License-Identifier: MIT * @@ -45,7 +45,7 @@ class DepthwiseConvolutionLayerFixture : public framework::Fixture { public: template - void setup(TensorShape src_shape, Size2D kernel_size, PadStrideInfo info, DataType data_type, int batches) + void setup(TensorShape src_shape, Size2D kernel_size, PadStrideInfo info, Size2D Dilation, DataType data_type, int batches) { // Get shapes TensorShape weights_shape(kernel_size.width, kernel_size.height); diff --git a/tests/datasets/DepthwiseConvolutionLayerDataset.h b/tests/datasets/DepthwiseConvolutionLayerDataset.h index 8a1f3b6f39..4c78eb87ea 100644 --- a/tests/datasets/DepthwiseConvolutionLayerDataset.h +++ b/tests/datasets/DepthwiseConvolutionLayerDataset.h @@ -38,16 +38,18 @@ namespace datasets class DepthwiseConvolutionLayerDataset { public: - using type = std::tuple; + using type = std::tuple; struct iterator { iterator(std::vector::const_iterator src_it, std::vector::const_iterator weights_it, - std::vector::const_iterator infos_it) + std::vector::const_iterator infos_it, + std::vector::const_iterator dilation_it) : _src_it{ std::move(src_it) }, _weights_it{ std::move(weights_it) }, - _infos_it{ std::move(infos_it) } + _infos_it{ std::move(infos_it) }, + _dilation_it{ std::move(dilation_it) } { } @@ -56,13 +58,14 @@ public: std::stringstream description; description << "In=" << *_src_it << ":"; description << "Weights=" << *_weights_it << ":"; - description << "Info=" << *_infos_it; + description << "Info=" << *_infos_it << ":"; + description << "Dilation=" << *_dilation_it; return description.str(); } DepthwiseConvolutionLayerDataset::type operator*() const { - return std::make_tuple(*_src_it, *_weights_it, *_infos_it); + return std::make_tuple(*_src_it, *_weights_it, *_infos_it, *_dilation_it); } iterator &operator++() @@ -70,6 +73,7 @@ public: ++_src_it; ++_weights_it; ++_infos_it; + ++_dilation_it; return *this; } @@ -78,23 +82,25 @@ public: std::vector::const_iterator _src_it; std::vector::const_iterator _weights_it; std::vector::const_iterator _infos_it; + std::vector::const_iterator _dilation_it; }; iterator begin() const { - return iterator(_src_shapes.begin(), _weight_shapes.begin(), _infos.begin()); + return iterator(_src_shapes.begin(), _weight_shapes.begin(), _infos.begin(), _dilations.begin()); } int size() const { - return std::min(_src_shapes.size(), std::min(_weight_shapes.size(), _infos.size())); + return std::min(_src_shapes.size(), std::min(_weight_shapes.size(), std::min(_infos.size(), _dilations.size()))); } - void add_config(TensorShape src, Size2D weights, PadStrideInfo info) + void add_config(TensorShape src, Size2D weights, PadStrideInfo info, Size2D dilation = Size2D(1U, 1U)) { _src_shapes.emplace_back(std::move(src)); _weight_shapes.emplace_back(std::move(weights)); _infos.emplace_back(std::move(info)); + _dilations.emplace_back(std::move(dilation)); } protected: @@ -105,6 +111,7 @@ private: std::vector _src_shapes{}; std::vector _weight_shapes{}; std::vector _infos{}; + std::vector _dilations{}; }; /** Dataset containing small, generic depthwise convolution shapes. */ diff --git a/tests/datasets/DilatedDepthwiseConvolutionLayerDataset.h b/tests/datasets/DilatedDepthwiseConvolutionLayerDataset.h new file mode 100644 index 0000000000..df054de501 --- /dev/null +++ b/tests/datasets/DilatedDepthwiseConvolutionLayerDataset.h @@ -0,0 +1,139 @@ +/* + * Copyright (c) 2019 ARM Limited. + * + * SPDX-License-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef ARM_COMPUTE_TEST_DILATED_CONVOLUTION_LAYER_DATASET +#define ARM_COMPUTE_TEST_DILATED_CONVOLUTION_LAYER_DATASET + +#include "utils/TypePrinter.h" + +#include "arm_compute/core/TensorShape.h" +#include "arm_compute/core/Types.h" +#include "tests/datasets/DepthwiseConvolutionLayerDataset.h" + +namespace arm_compute +{ +namespace test +{ +namespace datasets +{ +/** Dataset containing small, generic depthwise convolution shapes with dilation. */ +class SmallDepthwiseDilatedConvolutionLayerDataset final : public DepthwiseConvolutionLayerDataset +{ +public: + SmallDepthwiseDilatedConvolutionLayerDataset() + { + // Different strides and dilations + add_config(TensorShape(7U, 7U, 1U), Size2D(3U, 2U), PadStrideInfo(1, 1, 0, 0), Size2D(2U, 2U)); + add_config(TensorShape(7U, 7U, 1U), Size2D(3U, 2U), PadStrideInfo(1, 2, 0, 0), Size2D(2U, 1U)); + add_config(TensorShape(7U, 7U, 1U), Size2D(3U, 2U), PadStrideInfo(1, 1, 0, 0), Size2D(2U, 1U)); + add_config(TensorShape(7U, 7U, 1U), Size2D(3U, 2U), PadStrideInfo(2, 1, 0, 0), Size2D(2U, 2U)); + add_config(TensorShape(7U, 7U, 1U), Size2D(3U, 2U), PadStrideInfo(2, 2, 0, 0), Size2D(1U, 2U)); + + add_config(TensorShape(7U, 8U, 1U), Size2D(2U, 3U), PadStrideInfo(1, 2, 0, 0), Size2D(2U, 2U)); + add_config(TensorShape(23U, 27U, 5U), Size2D(3U, 5U), PadStrideInfo(2, 1, 0, 0), Size2D(2U, 1U)); + add_config(TensorShape(33U, 27U, 7U), Size2D(7U, 3U), PadStrideInfo(3, 2, 1, 0), Size2D(1U, 2U)); + // Asymmetric padding + add_config(TensorShape(33U, 27U, 7U), Size2D(5U, 7U), PadStrideInfo(3, 2, 1, 1, 2, 0, DimensionRoundingType::FLOOR), Size2D(2U, 2U)); + add_config(TensorShape(33U, 27U, 7U), Size2D(5U, 7U), PadStrideInfo(3, 2, 1, 1, 0, 2, DimensionRoundingType::FLOOR), Size2D(2U, 2U)); + } +}; + +/** Dataset containing small, 3x3 depthwise convolution shapes with dilation. */ +class SmallDepthwiseDilatedConvolutionLayerDataset3x3 final : public DepthwiseConvolutionLayerDataset +{ +public: + SmallDepthwiseDilatedConvolutionLayerDataset3x3() + { + add_config(TensorShape(7U, 7U, 1U), Size2D(3U, 3U), PadStrideInfo(1, 1, 1, 0), Size2D(2U, 2U)); + add_config(TensorShape(7U, 7U, 1U), Size2D(3U, 3U), PadStrideInfo(1, 1, 2, 0), Size2D(2U, 2U)); + add_config(TensorShape(7U, 7U, 1U), Size2D(3U, 3U), PadStrideInfo(1, 1, 3, 0), Size2D(2U, 2U)); + + // Different strides and dilations + add_config(TensorShape(7U, 7U, 1U), Size2D(3U, 3U), PadStrideInfo(1, 1, 0, 0), Size2D(2U, 2U)); + add_config(TensorShape(7U, 7U, 1U), Size2D(3U, 3U), PadStrideInfo(1, 2, 0, 0), Size2D(2U, 1U)); + add_config(TensorShape(7U, 7U, 1U), Size2D(3U, 3U), PadStrideInfo(2, 1, 0, 0), Size2D(2U, 2U)); + add_config(TensorShape(7U, 7U, 1U), Size2D(3U, 3U), PadStrideInfo(2, 2, 0, 0), Size2D(1U, 2U)); + + add_config(TensorShape(11U, 11U, 1U), Size2D(3U, 3U), PadStrideInfo(3, 3, 0, 0), Size2D(2U, 2U)); + add_config(TensorShape(7U, 7U, 3U, 2U), Size2D(3U, 3U), PadStrideInfo(1, 1, 0, 0), Size2D(2U, 2U)); + + add_config(TensorShape(21U, 31U, 9U, 4U), Size2D(3U, 3U), PadStrideInfo(1, 1, 1, 0), Size2D(1U, 1U)); + + add_config(TensorShape(21U, 31U, 9U, 4U), Size2D(3U, 3U), PadStrideInfo(1, 1, 1, 0), Size2D(2U, 2U)); + // Asymmetric padding + add_config(TensorShape(33U, 27U, 11U), Size2D(3U, 3U), PadStrideInfo(2, 2, 0, 1, 0, 1, DimensionRoundingType::FLOOR), Size2D(2U, 2U)); + } +}; + +/** Dataset containing large, generic depthwise convolution shapes with dilation. */ +class LargeDepthwiseDilatedConvolutionLayerDataset final : public DepthwiseConvolutionLayerDataset +{ +public: + LargeDepthwiseDilatedConvolutionLayerDataset() + { + add_config(TensorShape(33U, 27U, 11U), Size2D(3U, 3U), PadStrideInfo(1, 2, 0, 1), Size2D(2U, 1U)); + add_config(TensorShape(17U, 31U, 2U), Size2D(5U, 9U), PadStrideInfo(1, 2, 1, 1), Size2D(1U, 2U)); + add_config(TensorShape(23U, 27U, 5U), Size2D(11U, 3U), PadStrideInfo(1, 2, 0, 0), Size2D(3U, 3U)); + add_config(TensorShape(17U, 31U, 2U, 3U), Size2D(5U, 9U), PadStrideInfo(1, 2, 1, 1), Size2D(2U, 2U)); + add_config(TensorShape(233U, 277U, 55U), Size2D(3U, 3U), PadStrideInfo(2, 1, 0, 0), Size2D(2U, 2U)); + add_config(TensorShape(333U, 277U, 77U), Size2D(3U, 3U), PadStrideInfo(3, 2, 1, 0), Size2D(3U, 2U)); + add_config(TensorShape(177U, 311U, 22U), Size2D(3U, 3U), PadStrideInfo(1, 2, 1, 1), Size2D(2U, 2U)); + add_config(TensorShape(233U, 277U, 55U), Size2D(3U, 3U), PadStrideInfo(1, 2, 0, 0), Size2D(5U, 2U)); + add_config(TensorShape(333U, 277U, 77U), Size2D(3U, 3U), PadStrideInfo(2, 3, 0, 1), Size2D(2U, 2U)); + add_config(TensorShape(177U, 311U, 22U), Size2D(3U, 3U), PadStrideInfo(2, 1, 1, 1), Size2D(2U, 5U)); + // Asymmetric padding + add_config(TensorShape(33U, 27U, 7U), Size2D(5U, 7U), PadStrideInfo(3, 2, 2, 1, 2, 0, DimensionRoundingType::FLOOR), Size2D(3U, 2U)); + add_config(TensorShape(33U, 27U, 7U), Size2D(5U, 7U), PadStrideInfo(3, 2, 1, 3, 0, 2, DimensionRoundingType::FLOOR), Size2D(4U, 4U)); + add_config(TensorShape(33U, 27U, 7U), Size2D(5U, 7U), PadStrideInfo(3, 2, 1, 0, 1, 0, DimensionRoundingType::FLOOR), Size2D(2U, 2U)); + add_config(TensorShape(33U, 27U, 7U), Size2D(5U, 7U), PadStrideInfo(3, 2, 0, 1, 0, 1, DimensionRoundingType::FLOOR), Size2D(3U, 3U)); + } +}; + +/** Dataset containing large, 3x3 depthwise convolution shapes with dilation. */ +class LargeDepthwiseDilatedConvolutionLayerDataset3x3 final : public DepthwiseConvolutionLayerDataset +{ +public: + LargeDepthwiseDilatedConvolutionLayerDataset3x3() + { + add_config(TensorShape(33U, 27U, 11U, 3U), Size2D(3U, 3U), PadStrideInfo(1, 1, 0, 1), Size2D(2U, 1U)); + add_config(TensorShape(33U, 27U, 11U, 3U), Size2D(3U, 3U), PadStrideInfo(1, 1, 1, 1), Size2D(2U, 2U)); + add_config(TensorShape(21U, 31U, 9U, 4U), Size2D(3U, 3U), PadStrideInfo(1, 2, 1, 0), Size2D(2U, 2U)); + add_config(TensorShape(33U, 27U, 11U, 3U), Size2D(3U, 3U), PadStrideInfo(1, 2, 0, 1), Size2D(2U, 1U)); + add_config(TensorShape(33U, 27U, 11U, 3U), Size2D(3U, 3U), PadStrideInfo(1, 2, 1, 1), Size2D(2U, 3U)); + add_config(TensorShape(21U, 31U, 9U, 4U), Size2D(3U, 3U), PadStrideInfo(2, 1, 1, 0), Size2D(2U, 1U)); + add_config(TensorShape(33U, 27U, 11U, 3U), Size2D(3U, 3U), PadStrideInfo(2, 1, 0, 1), Size2D(3U, 3U)); + add_config(TensorShape(33U, 27U, 11U, 3U), Size2D(3U, 3U), PadStrideInfo(2, 1, 1, 1), Size2D(2U, 2U)); + add_config(TensorShape(21U, 31U, 9U, 4U), Size2D(3U, 3U), PadStrideInfo(2, 2, 1, 0), Size2D(2U, 2U)); + add_config(TensorShape(33U, 27U, 11U, 3U), Size2D(3U, 3U), PadStrideInfo(2, 2, 0, 1), Size2D(4U, 4U)); + add_config(TensorShape(33U, 27U, 11U, 3U), Size2D(3U, 3U), PadStrideInfo(2, 2, 1, 1), Size2D(2U, 5U)); + add_config(TensorShape(233U, 277U, 55U, 3U), Size2D(3U, 3U), PadStrideInfo(2, 1, 0, 0), Size2D(3U, 3U)); + add_config(TensorShape(177U, 311U, 22U), Size2D(3U, 3U), PadStrideInfo(1, 2, 1, 1), Size2D(4U, 4U)); + add_config(TensorShape(233U, 277U, 55U), Size2D(3U, 3U), PadStrideInfo(1, 2, 0, 0), Size2D(5U, 5U)); + add_config(TensorShape(333U, 277U, 77U, 5U), Size2D(3U, 3U), PadStrideInfo(2, 3, 0, 1), Size2D(4U, 4U)); + add_config(TensorShape(177U, 311U, 22U), Size2D(3U, 3U), PadStrideInfo(2, 1, 1, 1), Size2D(3U, 3U)); + } +}; +} // namespace datasets +} // namespace test +} // namespace arm_compute +#endif /* ARM_COMPUTE_TEST_DILATED_CONVOLUTION_LAYER_DATASET */ diff --git a/tests/validation/CL/DepthwiseConvolutionLayer.cpp b/tests/validation/CL/DepthwiseConvolutionLayer.cpp index dd2d9f344a..94f64e19b4 100644 --- a/tests/validation/CL/DepthwiseConvolutionLayer.cpp +++ b/tests/validation/CL/DepthwiseConvolutionLayer.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2018 ARM Limited. + * Copyright (c) 2017-2019 ARM Limited. * * SPDX-License-Identifier: MIT * @@ -18,7 +18,7 @@ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONCLCTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ #include "arm_compute/core/Types.h" @@ -28,6 +28,7 @@ #include "tests/CL/CLAccessor.h" #include "tests/PaddingCalculator.h" #include "tests/datasets/DepthwiseConvolutionLayerDataset.h" +#include "tests/datasets/DilatedDepthwiseConvolutionLayerDataset.h" #include "tests/framework/Asserts.h" #include "tests/framework/Macros.h" #include "tests/framework/datasets/Datasets.h" @@ -55,7 +56,7 @@ TEST_SUITE(DepthwiseConvolutionLayer) // *INDENT-OFF* // clang-format off -DATA_TEST_CASE(Validate3x3, framework::DatasetMode::ALL, zip(zip(zip(zip(zip(zip(zip( +DATA_TEST_CASE(Validate3x3, framework::DatasetMode::ALL, zip(zip(zip(zip(zip(zip(zip(zip( framework::dataset::make("InputInfo", { TensorInfo(TensorShape(32U, 18U, 2U), 1, DataType::F32), // Mismatching data type input/weights TensorInfo(TensorShape(32U, 18U, 3U), 1, DataType::F32), // Mismatching input feature maps TensorInfo(TensorShape(32U, 18U, 2U), 1, DataType::F32), // Unsupported weights dimensions @@ -66,6 +67,8 @@ DATA_TEST_CASE(Validate3x3, framework::DatasetMode::ALL, zip(zip(zip(zip(zip(zip TensorInfo(TensorShape(32U, 18U, 2U), 1, DataType::F32), // Invalid biases dimensions TensorInfo(TensorShape(32U, 18U, 2U), 1, DataType::F32), // Invalid output size TensorInfo(TensorShape(27U, 13U, 2U), 1, DataType::F32), // Window shrink + TensorInfo(TensorShape(32U, 18U, 8U), 1, DataType::F32), // patch size bigger than input width + TensorInfo(TensorShape(32U, 18U, 8U), 1, DataType::F32), // dilation < 1 TensorInfo(TensorShape(32U, 18U, 8U), 1, DataType::F32), TensorInfo(TensorShape(50U, 32U, 8U), 1, DataType::QASYMM8), }), @@ -80,6 +83,8 @@ DATA_TEST_CASE(Validate3x3, framework::DatasetMode::ALL, zip(zip(zip(zip(zip(zip TensorInfo(TensorShape(3U, 3U, 2U), 1, DataType::F32), TensorInfo(TensorShape(3U, 3U, 2U), 1, DataType::F32), TensorInfo(TensorShape(3U, 3U, 16U), 1, DataType::F32), + TensorInfo(TensorShape(3U, 3U, 16U), 1, DataType::F32), + TensorInfo(TensorShape(3U, 3U, 16U), 1, DataType::F32), TensorInfo(TensorShape(3U, 3U, 24U), 1, DataType::QASYMM8), })), framework::dataset::make("BiasesInfo", { TensorInfo(TensorShape(2U), 1, DataType::F32), @@ -93,6 +98,8 @@ DATA_TEST_CASE(Validate3x3, framework::DatasetMode::ALL, zip(zip(zip(zip(zip(zip TensorInfo(TensorShape(2U), 1, DataType::F32), TensorInfo(TensorShape(2U), 1, DataType::F32), TensorInfo(TensorShape(16U), 1, DataType::F32), + TensorInfo(TensorShape(16U), 1, DataType::F32), + TensorInfo(TensorShape(16U), 1, DataType::F32), TensorInfo(TensorShape(24U), 1, DataType::S32), })), framework::dataset::make("OutputInfo", { TensorInfo(TensorShape(30U, 16U, 2U), 1, DataType::F32), @@ -106,6 +113,8 @@ DATA_TEST_CASE(Validate3x3, framework::DatasetMode::ALL, zip(zip(zip(zip(zip(zip TensorInfo(TensorShape(32U, 18U, 2U), 1, DataType::F32), TensorInfo(TensorShape(25U, 11U, 2U), 1, DataType::F32), TensorInfo(TensorShape(30U, 16U, 16U), 1, DataType::F32), + TensorInfo(TensorShape(30U, 16U, 16U), 1, DataType::F32), + TensorInfo(TensorShape(30U, 16U, 16U), 1, DataType::F32), TensorInfo(TensorShape(48U, 30U, 24U), 1, DataType::QASYMM8), })), framework::dataset::make("ConvInfo", { PadStrideInfo(1, 1, 0, 0), @@ -120,6 +129,8 @@ DATA_TEST_CASE(Validate3x3, framework::DatasetMode::ALL, zip(zip(zip(zip(zip(zip PadStrideInfo(1, 1, 0, 0), PadStrideInfo(1, 1, 0, 0), PadStrideInfo(1, 1, 0, 0), + PadStrideInfo(1, 1, 0, 0), + PadStrideInfo(1, 1, 0, 0), })), framework::dataset::make("DepthMultiplier", { 1, 1, @@ -132,6 +143,8 @@ DATA_TEST_CASE(Validate3x3, framework::DatasetMode::ALL, zip(zip(zip(zip(zip(zip 1, 1, 2, + 2, + 2, 3, })), framework::dataset::make("ActivationInfo", { ActivationLayerInfo(), @@ -145,22 +158,41 @@ DATA_TEST_CASE(Validate3x3, framework::DatasetMode::ALL, zip(zip(zip(zip(zip(zip ActivationLayerInfo(), ActivationLayerInfo(), ActivationLayerInfo(), + ActivationLayerInfo(), + ActivationLayerInfo(), ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU), })), - framework::dataset::make("Expected", { false, false, false, false, false, false, false, false, false, false, true, true })), - input_info, weights_info, biases_info, output_info, conv_info, depth_multiplier, act_info, expected) + framework::dataset::make("Dilation", { Size2D(1U, 1U), + Size2D(1U, 1U), + Size2D(1U, 1U), + Size2D(1U, 1U), + Size2D(1U, 1U), + Size2D(1U, 1U), + Size2D(1U, 1U), + Size2D(1U, 1U), + Size2D(1U, 1U), + Size2D(1U, 1U), + Size2D(20U, 1U), + Size2D(0U, 1U), + Size2D(1U, 1U), + Size2D(1U, 1U), + })), + framework::dataset::make("Expected", { false, false, false, false, false, false, false, false, false, false, false, false, true, true })), + input_info, weights_info, biases_info, output_info, conv_info, depth_multiplier, act_info, dilation, expected) { - bool is_valid = bool(CLDepthwiseConvolutionLayer3x3::validate(&input_info.clone()->set_is_resizable(false), &weights_info.clone()->set_is_resizable(false), &biases_info.clone()->set_is_resizable(false), &output_info.clone()->set_is_resizable(false), conv_info, depth_multiplier, act_info)); + bool is_valid = bool(CLDepthwiseConvolutionLayer3x3::validate(&input_info.clone()->set_is_resizable(false), &weights_info.clone()->set_is_resizable(false), &biases_info.clone()->set_is_resizable(false), &output_info.clone()->set_is_resizable(false), conv_info, depth_multiplier, act_info,GPUTarget::MIDGARD, dilation)); ARM_COMPUTE_EXPECT(is_valid == expected, framework::LogLevel::ERRORS); } -DATA_TEST_CASE(ValidateGeneric, framework::DatasetMode::ALL, zip(zip(zip(zip(zip(zip( +DATA_TEST_CASE(ValidateGeneric, framework::DatasetMode::ALL, zip(zip(zip(zip(zip(zip(zip( framework::dataset::make("InputInfo", { TensorInfo(TensorShape(27U, 13U, 2U), 1, DataType::F32), // Mismatching data type input/weights TensorInfo(TensorShape(27U, 13U, 3U), 1, DataType::F32), // Mismatching input feature maps TensorInfo(TensorShape(27U, 13U, 2U), 1, DataType::F32), // Mismatching depth multiplier TensorInfo(TensorShape(27U, 13U, 2U), 1, DataType::F32), // Invalid biases size TensorInfo(TensorShape(27U, 13U, 2U), 1, DataType::F32), // Invalid biases dimensions TensorInfo(TensorShape(27U, 13U, 2U), 1, DataType::F32), // Invalid output size + TensorInfo(TensorShape(27U, 13U, 8U), 1, DataType::F32), // patch size bigger than input width + TensorInfo(TensorShape(27U, 13U, 8U), 1, DataType::F32), // dilation < 1 TensorInfo(TensorShape(27U, 13U, 8U), 1, DataType::F32), TensorInfo(TensorShape(32U, 13U, 8U), 1, DataType::QASYMM8), }), @@ -171,6 +203,8 @@ DATA_TEST_CASE(ValidateGeneric, framework::DatasetMode::ALL, zip(zip(zip(zip(zip TensorInfo(TensorShape(3U, 3U, 2U), 1, DataType::F32), TensorInfo(TensorShape(3U, 3U, 2U), 1, DataType::F32), TensorInfo(TensorShape(3U, 3U, 16U), 1, DataType::F32), + TensorInfo(TensorShape(3U, 3U, 16U), 1, DataType::F32), + TensorInfo(TensorShape(3U, 3U, 16U), 1, DataType::F32), TensorInfo(TensorShape(3U, 3U, 24U), 1, DataType::QASYMM8), })), framework::dataset::make("BiasesInfo", { TensorInfo(TensorShape(2U), 1, DataType::F32), @@ -180,6 +214,8 @@ DATA_TEST_CASE(ValidateGeneric, framework::DatasetMode::ALL, zip(zip(zip(zip(zip TensorInfo(TensorShape(2U, 2U), 1, DataType::F32), TensorInfo(TensorShape(2U), 1, DataType::F32), TensorInfo(TensorShape(16U), 1, DataType::F32), + TensorInfo(TensorShape(16U), 1, DataType::F32), + TensorInfo(TensorShape(16U), 1, DataType::F32), TensorInfo(TensorShape(24U), 1, DataType::S32), })), framework::dataset::make("OutputInfo", { TensorInfo(TensorShape(25U, 11U, 2U), 1, DataType::F32), @@ -189,6 +225,8 @@ DATA_TEST_CASE(ValidateGeneric, framework::DatasetMode::ALL, zip(zip(zip(zip(zip TensorInfo(TensorShape(25U, 11U, 2U), 1, DataType::F32), TensorInfo(TensorShape(27U, 13U, 2U), 1, DataType::F32), TensorInfo(TensorShape(25U, 11U, 16U), 1, DataType::F32), + TensorInfo(TensorShape(25U, 11U, 16U), 1, DataType::F32), + TensorInfo(TensorShape(25U, 11U, 16U), 1, DataType::F32), TensorInfo(TensorShape(32U, 11U, 24U), 1, DataType::QASYMM8), })), framework::dataset::make("ConvInfo", { PadStrideInfo(1, 1, 0, 0), @@ -198,6 +236,8 @@ DATA_TEST_CASE(ValidateGeneric, framework::DatasetMode::ALL, zip(zip(zip(zip(zip PadStrideInfo(1, 1, 0, 0), PadStrideInfo(1, 1, 0, 0), PadStrideInfo(1, 1, 0, 0), + PadStrideInfo(1, 1, 0, 0), + PadStrideInfo(1, 1, 0, 0), PadStrideInfo(1, 1, 1, 0), })), framework::dataset::make("DepthMultiplier", { 1, @@ -207,12 +247,25 @@ DATA_TEST_CASE(ValidateGeneric, framework::DatasetMode::ALL, zip(zip(zip(zip(zip 1, 1, 2, + 2, + 2, 3, })), - framework::dataset::make("Expected", { false, false, false, false, false, false, true, true })), - input_info, weights_info, biases_info, output_info, conv_info, depth_multiplier, expected) + framework::dataset::make("Dilation", { Size2D(1U, 1U), + Size2D(1U, 1U), + Size2D(1U, 1U), + Size2D(1U, 1U), + Size2D(1U, 1U), + Size2D(1U, 1U), + Size2D(20U, 1U), + Size2D(0U, 1U), + Size2D(1U, 1U), + Size2D(1U, 1U), + })), + framework::dataset::make("Expected", { false, false, false, false, false, false, false, false, true, true })), + input_info, weights_info, biases_info, output_info, conv_info, depth_multiplier, dilation, expected) { - bool is_valid = bool(CLDepthwiseConvolutionLayer::validate(&input_info.clone()->set_is_resizable(false), &weights_info.clone()->set_is_resizable(false), &biases_info.clone()->set_is_resizable(false), &output_info.clone()->set_is_resizable(false), conv_info, depth_multiplier)); + bool is_valid = bool(CLDepthwiseConvolutionLayer::validate(&input_info.clone()->set_is_resizable(false), &weights_info.clone()->set_is_resizable(false), &biases_info.clone()->set_is_resizable(false), &output_info.clone()->set_is_resizable(false), conv_info, depth_multiplier,ActivationLayerInfo(), dilation)); ARM_COMPUTE_EXPECT(is_valid == expected, framework::LogLevel::ERRORS); } // clang-format on @@ -243,7 +296,25 @@ FIXTURE_DATA_TEST_CASE(RunLarge, CLDepthwiseConvolutionLayerFixture, frame { validate(CLAccessor(_target), _reference, tolerance_f16); } -TEST_SUITE_END() +TEST_SUITE(Dilation) +FIXTURE_DATA_TEST_CASE(RunSmall, CLDepthwiseConvolutionLayerFixture, framework::DatasetMode::ALL, combine(combine(combine(datasets::SmallDepthwiseDilatedConvolutionLayerDataset3x3(), + depth_multipliers), + framework::dataset::make("DataType", + DataType::F16)), + framework::dataset::make("DataLayout", { DataLayout::NCHW }))) +{ + validate(CLAccessor(_target), _reference, tolerance_f16); +} +FIXTURE_DATA_TEST_CASE(RunLarge, CLDepthwiseConvolutionLayerFixture, framework::DatasetMode::NIGHTLY, combine(combine(combine(datasets::LargeDepthwiseDilatedConvolutionLayerDataset3x3(), + depth_multipliers), + framework::dataset::make("DataType", + DataType::F16)), + framework::dataset::make("DataLayout", { DataLayout::NCHW }))) +{ + validate(CLAccessor(_target), _reference, tolerance_f16); +} +TEST_SUITE_END() // Dilation +TEST_SUITE_END() // NCHW TEST_SUITE(NHWC) FIXTURE_DATA_TEST_CASE(RunSmall, CLDepthwiseConvolutionLayerFixture, framework::DatasetMode::ALL, @@ -263,8 +334,26 @@ FIXTURE_DATA_TEST_CASE(RunLarge, CLDepthwiseConvolutionLayerFixture, frame { validate(CLAccessor(_target), _reference, tolerance_f16); } -TEST_SUITE_END() -TEST_SUITE_END() +TEST_SUITE(Dilation) +FIXTURE_DATA_TEST_CASE(RunSmall, CLDepthwiseConvolutionLayerFixture, framework::DatasetMode::ALL, combine(combine(combine(datasets::SmallDepthwiseDilatedConvolutionLayerDataset3x3(), + depth_multipliers), + framework::dataset::make("DataType", + DataType::F16)), + framework::dataset::make("DataLayout", { DataLayout::NHWC }))) +{ + validate(CLAccessor(_target), _reference, tolerance_f16); +} +FIXTURE_DATA_TEST_CASE(RunLarge, CLDepthwiseConvolutionLayerFixture, framework::DatasetMode::NIGHTLY, combine(combine(combine(datasets::LargeDepthwiseDilatedConvolutionLayerDataset3x3(), + depth_multipliers), + framework::dataset::make("DataType", + DataType::F16)), + framework::dataset::make("DataLayout", { DataLayout::NHWC }))) +{ + validate(CLAccessor(_target), _reference, tolerance_f16); +} +TEST_SUITE_END() // Dilation +TEST_SUITE_END() // NHWC +TEST_SUITE_END() // W3x3 TEST_SUITE(Generic) FIXTURE_DATA_TEST_CASE(RunSmall, CLDepthwiseConvolutionLayerFixture, framework::DatasetMode::ALL, combine(combine(combine(datasets::SmallDepthwiseConvolutionLayerDataset(), depth_multipliers), @@ -282,8 +371,27 @@ FIXTURE_DATA_TEST_CASE(RunLarge, CLDepthwiseConvolutionLayerFixture, frame { validate(CLAccessor(_target), _reference, tolerance_f16, tolerance_num); } -TEST_SUITE_END() -TEST_SUITE_END() + +TEST_SUITE(Dilation) +FIXTURE_DATA_TEST_CASE(RunSmall, CLDepthwiseConvolutionLayerFixture, framework::DatasetMode::ALL, combine(combine(combine(datasets::SmallDepthwiseDilatedConvolutionLayerDataset(), + depth_multipliers), + framework::dataset::make("DataType", + DataType::F16)), + framework::dataset::make("DataLayout", { DataLayout::NCHW, DataLayout::NHWC }))) +{ + validate(CLAccessor(_target), _reference, tolerance_f16, tolerance_num); +} +FIXTURE_DATA_TEST_CASE(RunLarge, CLDepthwiseConvolutionLayerFixture, framework::DatasetMode::NIGHTLY, combine(combine(combine(datasets::LargeDepthwiseDilatedConvolutionLayerDataset(), + depth_multipliers), + framework::dataset::make("DataType", + DataType::F16)), + framework::dataset::make("DataLayout", { DataLayout::NCHW, DataLayout::NHWC }))) +{ + validate(CLAccessor(_target), _reference, tolerance_f16, tolerance_num); +} +TEST_SUITE_END() // Dilation +TEST_SUITE_END() // Generic +TEST_SUITE_END() // FP16 TEST_SUITE(FP32) TEST_SUITE(W3x3) @@ -306,7 +414,26 @@ FIXTURE_DATA_TEST_CASE(RunLarge, CLDepthwiseConvolutionLayerFixture, fram { validate(CLAccessor(_target), _reference, tolerance_f32); } -TEST_SUITE_END() +TEST_SUITE(Dilation) +FIXTURE_DATA_TEST_CASE(RunSmall, CLDepthwiseConvolutionLayerFixture, framework::DatasetMode::ALL, + combine(combine(combine(datasets::SmallDepthwiseDilatedConvolutionLayerDataset3x3(), depth_multipliers), + framework::dataset::make("DataType", + DataType::F32)), + framework::dataset::make("DataLayout", DataLayout::NCHW))) +{ + validate(CLAccessor(_target), _reference, tolerance_f32); +} +FIXTURE_DATA_TEST_CASE(RunLarge, CLDepthwiseConvolutionLayerFixture, framework::DatasetMode::NIGHTLY, combine(combine(combine(datasets::LargeDepthwiseDilatedConvolutionLayerDataset3x3(), + depth_multipliers), + framework::dataset::make("DataType", + DataType::F32)), + framework::dataset::make("DataLayout", DataLayout::NCHW))) +{ + validate(CLAccessor(_target), _reference, tolerance_f32); +} + +TEST_SUITE_END() // Dilation +TEST_SUITE_END() // NCHW TEST_SUITE(NHWC) FIXTURE_DATA_TEST_CASE(RunSmall, CLDepthwiseConvolutionLayerFixture, framework::DatasetMode::ALL, combine(combine(combine(datasets::SmallDepthwiseConvolutionLayerDataset3x3(), @@ -325,8 +452,28 @@ FIXTURE_DATA_TEST_CASE(RunLarge, CLDepthwiseConvolutionLayerFixture, fram { validate(CLAccessor(_target), _reference, tolerance_f32); } -TEST_SUITE_END() -TEST_SUITE_END() +TEST_SUITE(Dilation) + +FIXTURE_DATA_TEST_CASE(RunSmall, CLDepthwiseConvolutionLayerFixture, framework::DatasetMode::ALL, + combine(combine(combine(datasets::SmallDepthwiseDilatedConvolutionLayerDataset3x3(), + depth_multipliers), + framework::dataset::make("DataType", + DataType::F32)), + framework::dataset::make("DataLayout", DataLayout::NHWC))) +{ + validate(CLAccessor(_target), _reference, tolerance_f32); +} +FIXTURE_DATA_TEST_CASE(RunLarge, CLDepthwiseConvolutionLayerFixture, framework::DatasetMode::NIGHTLY, combine(combine(combine(datasets::LargeDepthwiseDilatedConvolutionLayerDataset3x3(), + depth_multipliers), + framework::dataset::make("DataType", + DataType::F32)), + framework::dataset::make("DataLayout", DataLayout::NHWC))) +{ + validate(CLAccessor(_target), _reference, tolerance_f32); +} +TEST_SUITE_END() // Dilation +TEST_SUITE_END() // NHWC +TEST_SUITE_END() // W3x3 TEST_SUITE(Generic) FIXTURE_DATA_TEST_CASE(RunSmall, CLDepthwiseConvolutionLayerFixture, framework::DatasetMode::ALL, combine(combine(combine(datasets::SmallDepthwiseConvolutionLayerDataset(), depth_multipliers), @@ -344,9 +491,28 @@ FIXTURE_DATA_TEST_CASE(RunLarge, CLDepthwiseConvolutionLayerFixture, fram { validate(CLAccessor(_target), _reference, tolerance_f32); } -TEST_SUITE_END() -TEST_SUITE_END() -TEST_SUITE_END() + +TEST_SUITE(Dilation) +FIXTURE_DATA_TEST_CASE(RunSmall, CLDepthwiseConvolutionLayerFixture, framework::DatasetMode::ALL, combine(combine(combine(datasets::SmallDepthwiseDilatedConvolutionLayerDataset(), + depth_multipliers), + framework::dataset::make("DataType", + DataType::F32)), + framework::dataset::make("DataLayout", { DataLayout::NCHW, DataLayout::NHWC }))) +{ + validate(CLAccessor(_target), _reference, tolerance_f32); +} +FIXTURE_DATA_TEST_CASE(RunLarge, CLDepthwiseConvolutionLayerFixture, framework::DatasetMode::NIGHTLY, combine(combine(combine(datasets::LargeDepthwiseDilatedConvolutionLayerDataset3x3(), + depth_multipliers), + framework::dataset::make("DataType", + DataType::F32)), + framework::dataset::make("DataLayout", { DataLayout::NCHW, DataLayout::NHWC }))) +{ + validate(CLAccessor(_target), _reference, tolerance_f32); +} +TEST_SUITE_END() // Dilation +TEST_SUITE_END() // Generic +TEST_SUITE_END() // FP32 +TEST_SUITE_END() // Float template using CLDepthwiseConvolutionLayerQuantizedFixture = DepthwiseConvolutionLayerValidationQuantizedFixture; @@ -372,7 +538,27 @@ FIXTURE_DATA_TEST_CASE(RunLarge, CLDepthwiseConvolutionLayerQuantizedFixture, framework::DatasetMode::PRECOMMIT, + combine(combine(combine(combine(datasets::SmallDepthwiseDilatedConvolutionLayerDataset(), + depth_multipliers), + framework::dataset::make("DataType", DataType::QASYMM8)), + framework::dataset::make("QuantizationInfo", { QuantizationInfo(0.5f, 10) })), + framework::dataset::make("DataLayout", { DataLayout::NCHW, DataLayout::NHWC }))) +{ + validate(CLAccessor(_target), _reference, tolerance_qasymm8); +} +FIXTURE_DATA_TEST_CASE(RunLarge, CLDepthwiseConvolutionLayerQuantizedFixture, framework::DatasetMode::NIGHTLY, + combine(combine(combine(combine(datasets::LargeDepthwiseDilatedConvolutionLayerDataset(), + depth_multipliers), + framework::dataset::make("DataType", DataType::QASYMM8)), + framework::dataset::make("QuantizationInfo", { QuantizationInfo(0.5f, 10) })), + framework::dataset::make("DataLayout", { DataLayout::NCHW, DataLayout::NHWC }))) +{ + validate(CLAccessor(_target), _reference, tolerance_qasymm8); +} +TEST_SUITE_END() // Dilation +TEST_SUITE_END() // Generic TEST_SUITE(W3x3) FIXTURE_DATA_TEST_CASE(RunSmall, CLDepthwiseConvolutionLayerQuantizedFixture, framework::DatasetMode::PRECOMMIT, combine(combine(combine(combine(datasets::SmallDepthwiseConvolutionLayerDataset3x3(), @@ -392,12 +578,32 @@ FIXTURE_DATA_TEST_CASE(RunLarge, CLDepthwiseConvolutionLayerQuantizedFixture, framework::DatasetMode::PRECOMMIT, + combine(combine(combine(combine(datasets::SmallDepthwiseDilatedConvolutionLayerDataset3x3(), + depth_multipliers), + framework::dataset::make("DataType", DataType::QASYMM8)), + framework::dataset::make("QuantizationInfo", { QuantizationInfo(0.5f, 10) })), + framework::dataset::make("DataLayout", { DataLayout::NCHW, DataLayout::NHWC }))) +{ + validate(CLAccessor(_target), _reference, tolerance_qasymm8); +} +FIXTURE_DATA_TEST_CASE(RunLarge, CLDepthwiseConvolutionLayerQuantizedFixture, framework::DatasetMode::NIGHTLY, + combine(combine(combine(combine(datasets::LargeDepthwiseDilatedConvolutionLayerDataset3x3(), + depth_multipliers), + framework::dataset::make("DataType", DataType::QASYMM8)), + framework::dataset::make("QuantizationInfo", { QuantizationInfo(0.5f, 10) })), + framework::dataset::make("DataLayout", { DataLayout::NCHW, DataLayout::NHWC }))) +{ + validate(CLAccessor(_target), _reference, tolerance_qasymm8); +} +TEST_SUITE_END() // Dilation +TEST_SUITE_END() // W3x3 +TEST_SUITE_END() // QASYMM8 +TEST_SUITE_END() // Quantized -TEST_SUITE_END() -TEST_SUITE_END() +TEST_SUITE_END() // DepthwiseConvolutionLayer +TEST_SUITE_END() // CL } // namespace validation } // namespace test } // namespace arm_compute diff --git a/tests/validation/fixtures/DepthwiseConvolutionLayerFixture.h b/tests/validation/fixtures/DepthwiseConvolutionLayerFixture.h index 5428154a2b..dd8bf232be 100644 --- a/tests/validation/fixtures/DepthwiseConvolutionLayerFixture.h +++ b/tests/validation/fixtures/DepthwiseConvolutionLayerFixture.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2018 ARM Limited. + * Copyright (c) 2017-2019 ARM Limited. * * SPDX-License-Identifier: MIT * @@ -55,7 +55,8 @@ public: public: template - void setup(TensorShape in_shape, Size2D kernel_size, PadStrideInfo pad_stride_info, unsigned int depth_multiplier, DataType data_type, QuantizationInfo quantization_info, DataLayout data_layout) + void setup(TensorShape in_shape, Size2D kernel_size, PadStrideInfo pad_stride_info, Size2D dilation, unsigned int depth_multiplier, DataType data_type, QuantizationInfo quantization_info, + DataLayout data_layout) { _quantization_info = quantization_info; _data_type = data_type; @@ -65,13 +66,13 @@ public: const TensorInfo in_info(in_shape, 1, data_type); const TensorInfo we_info(weights_shape, 1, data_type); - TensorShape out_shape = compute_depthwise_convolution_shape(in_info, we_info, pad_stride_info, depth_multiplier); + const TensorShape out_shape = compute_depthwise_convolution_shape(in_info, we_info, pad_stride_info, depth_multiplier, dilation); weights_shape.set(2, out_shape.z()); const TensorShape biases_shape(weights_shape[2]); - _target = compute_target(in_shape, weights_shape, biases_shape, out_shape, pad_stride_info, depth_multiplier, data_type, bias_data_type, quantization_info, data_layout); - _reference = compute_reference(in_shape, weights_shape, biases_shape, out_shape, pad_stride_info, depth_multiplier, data_type, bias_data_type, quantization_info); + _target = compute_target(in_shape, weights_shape, biases_shape, out_shape, pad_stride_info, dilation, depth_multiplier, data_type, bias_data_type, quantization_info, data_layout); + _reference = compute_reference(in_shape, weights_shape, biases_shape, out_shape, pad_stride_info, dilation, depth_multiplier, data_type, bias_data_type, quantization_info); } protected: @@ -104,7 +105,8 @@ protected: } } - TensorType compute_target(TensorShape input_shape, TensorShape weights_shape, TensorShape biases_shape, TensorShape output_shape, PadStrideInfo &pad_stride_info, unsigned int depth_multiplier, + TensorType compute_target(TensorShape input_shape, TensorShape weights_shape, TensorShape biases_shape, TensorShape output_shape, PadStrideInfo &pad_stride_info, Size2D dilation, + unsigned int depth_multiplier, const DataType data_type, const DataType bias_data_type, const QuantizationInfo quantization_info, const DataLayout data_layout) { if(data_layout == DataLayout::NHWC) @@ -122,7 +124,7 @@ protected: // Create Depthwise Convolution configure function FunctionType dwc; - dwc.configure(&src, &weights, &biases, &dst, pad_stride_info, depth_multiplier); + dwc.configure(&src, &weights, &biases, &dst, pad_stride_info, depth_multiplier, ActivationLayerInfo(), dilation); ARM_COMPUTE_EXPECT(src.info()->is_resizable(), framework::LogLevel::ERRORS); ARM_COMPUTE_EXPECT(weights.info()->is_resizable(), framework::LogLevel::ERRORS); @@ -152,7 +154,7 @@ protected: } SimpleTensor compute_reference(const TensorShape &in_shape, const TensorShape &weights_shape, const TensorShape &biases_shape, const TensorShape &out_shape, const PadStrideInfo &pad_stride_info, - unsigned int depth_multiplier, + const Size2D &dilation, unsigned int depth_multiplier, const DataType data_type, const DataType bias_data_type, const QuantizationInfo quantization_info) { SimpleTensor src{ in_shape, data_type, 1, quantization_info }; @@ -163,7 +165,7 @@ protected: fill(weights, 1); fill(biases, 2); - return reference::depthwise_convolution(src, weights, biases, out_shape, pad_stride_info, depth_multiplier); + return reference::depthwise_convolution(src, weights, biases, out_shape, pad_stride_info, depth_multiplier, dilation); } TensorType _target{}; @@ -177,9 +179,9 @@ class DepthwiseConvolutionLayerValidationFixture : public DepthwiseConvolutionLa { public: template - void setup(TensorShape in_shape, Size2D kernel_size, PadStrideInfo pad_stride_info, unsigned int depth_multiplier, DataType data_type, DataLayout data_layout) + void setup(TensorShape in_shape, Size2D kernel_size, PadStrideInfo pad_stride_info, Size2D dilation, unsigned int depth_multiplier, DataType data_type, DataLayout data_layout) { - DepthwiseConvolutionLayerValidationGenericFixture::setup(in_shape, kernel_size, pad_stride_info, depth_multiplier, + DepthwiseConvolutionLayerValidationGenericFixture::setup(in_shape, kernel_size, pad_stride_info, dilation, depth_multiplier, data_type, QuantizationInfo(), data_layout); } }; @@ -189,9 +191,10 @@ class DepthwiseConvolutionLayerValidationQuantizedFixture : public DepthwiseConv { public: template - void setup(TensorShape in_shape, Size2D kernel_size, PadStrideInfo pad_stride_info, unsigned int depth_multiplier, DataType data_type, QuantizationInfo quantization_info, DataLayout data_layout) + void setup(TensorShape in_shape, Size2D kernel_size, PadStrideInfo pad_stride_info, Size2D dilation, unsigned int depth_multiplier, DataType data_type, QuantizationInfo quantization_info, + DataLayout data_layout) { - DepthwiseConvolutionLayerValidationGenericFixture::setup(in_shape, kernel_size, pad_stride_info, depth_multiplier, + DepthwiseConvolutionLayerValidationGenericFixture::setup(in_shape, kernel_size, pad_stride_info, dilation, depth_multiplier, data_type, quantization_info, data_layout); } }; diff --git a/tests/validation/reference/DepthwiseConvolutionLayer.cpp b/tests/validation/reference/DepthwiseConvolutionLayer.cpp index 122dbd4d98..90ecffbbca 100644 --- a/tests/validation/reference/DepthwiseConvolutionLayer.cpp +++ b/tests/validation/reference/DepthwiseConvolutionLayer.cpp @@ -70,13 +70,19 @@ SimpleTensor depthwise_convolution(const SimpleTensor &src, const SimpleTe const int pad_right = conv_info.pad_right(); const int pad_bottom = conv_info.pad_bottom(); - const int patch_half_width = (filter_width + (dilation.x() - 1) * (filter_width - 1)) / 2; - const int patch_half_height = (filter_height + (dilation.y() - 1) * (filter_height - 1)) / 2; + const float patch_width = (filter_width + (dilation.x() - 1) * (filter_width - 1)); + const float patch_height = (filter_height + (dilation.y() - 1) * (filter_height - 1)); - const int minimum_x = -pad_left + patch_half_width; - const int minimum_y = -pad_top + patch_half_height; - const int maximum_x = input_width + pad_left + pad_right - patch_half_width * 2; - const int maximum_y = input_height + pad_top + pad_bottom - patch_half_height * 2; + const int patch_half_width_floor = patch_width / 2; + const int patch_half_height_floor = patch_height / 2; + + const auto patch_half_width_ceil = static_cast(std::ceil(patch_width / 2)); + const auto patch_half_height_ceil = static_cast(std::ceil(patch_height / 2)); + + const int minimum_x = -pad_left + patch_half_width_floor; + const int minimum_y = -pad_top + patch_half_height_floor; + const int maximum_x = input_width + pad_left + pad_right - static_cast(patch_width); + const int maximum_y = input_height + pad_top + pad_bottom - static_cast(patch_height); const T border_value(0); @@ -89,21 +95,20 @@ SimpleTensor depthwise_convolution(const SimpleTensor &src, const SimpleTe { const int out_z = z * depth_multiplier + m; - for(int y = minimum_y; y < minimum_y + maximum_y; y += conv_info.stride().second) + for(int y = minimum_y; y <= minimum_y + maximum_y; y += conv_info.stride().second) { - for(int x = minimum_x; x < minimum_x + maximum_x; x += conv_info.stride().first) + for(int x = minimum_x; x <= minimum_x + maximum_x; x += conv_info.stride().first) { Coordinates coords(static_cast(x), static_cast(y), static_cast(z), static_cast(r)); size_t filter_offset = filter_plane * out_z; T val(0); - for(int j = y - patch_half_height; j <= y + patch_half_height; j += dilation.y()) + for(int j = y - patch_half_height_floor; j < y + patch_half_height_ceil; j += dilation.y()) { - for(int i = x - patch_half_width; i <= x + patch_half_width; i += dilation.x()) + for(int i = x - patch_half_width_floor; i < x + patch_half_width_ceil; i += dilation.x()) { coords.set(0, i); coords.set(1, j); - val += *(weights.data() + filter_offset) * tensor_elem_at(src, coords, BorderMode::CONSTANT, border_value); ++filter_offset; } @@ -157,13 +162,19 @@ SimpleTensor depthwise_convolution(const SimpleTensor &src, co const int pad_right = conv_info.pad_right(); const int pad_bottom = conv_info.pad_bottom(); - const int patch_half_width = (filter_width + (dilation.x() - 1) * (filter_width - 1)) / 2; - const int patch_half_height = (filter_height + (dilation.y() - 1) * (filter_height - 1)) / 2; + const float patch_width = (filter_width + (dilation.x() - 1) * (filter_width - 1)); + const float patch_height = (filter_height + (dilation.y() - 1) * (filter_height - 1)); + + const int patch_half_width_floor = patch_width / 2; + const int patch_half_height_floor = patch_height / 2; + + const auto patch_half_width_ceil = static_cast(std::ceil(patch_width / 2)); + const auto patch_half_height_ceil = static_cast(std::ceil(patch_height / 2)); - const int minimum_x = -pad_left + patch_half_width; - const int minimum_y = -pad_top + patch_half_height; - const int maximum_x = input_width + pad_left + pad_right - patch_half_width * 2; - const int maximum_y = input_height + pad_top + pad_bottom - patch_half_height * 2; + const int minimum_x = -pad_left + patch_half_width_floor; + const int minimum_y = -pad_top + patch_half_height_floor; + const int maximum_x = input_width + pad_left + pad_right - static_cast(patch_width); + const int maximum_y = input_height + pad_top + pad_bottom - static_cast(patch_height); int out_pos = 0; for(int r = 0; r < num_batches; ++r) @@ -175,17 +186,17 @@ SimpleTensor depthwise_convolution(const SimpleTensor &src, co const int out_z = z * depth_multiplier + m; const int32_t bias_val = *static_cast(biases(Coordinates(out_z))); - for(int y = minimum_y; y < minimum_y + maximum_y; y += conv_info.stride().second) + for(int y = minimum_y; y <= minimum_y + maximum_y; y += conv_info.stride().second) { - for(int x = minimum_x; x < minimum_x + maximum_x; x += conv_info.stride().first) + for(int x = minimum_x; x <= minimum_x + maximum_x; x += conv_info.stride().first) { Coordinates coords(x, y, z, r); int filter_offset = filter_plane * out_z; int32_t val = 0; - for(int j = y - patch_half_height; j <= y + patch_half_height; j += dilation.y()) + for(int j = y - patch_half_height_floor; j < y + patch_half_height_ceil; j += dilation.y()) { - for(int i = x - patch_half_width; i <= x + patch_half_width; i += dilation.x()) + for(int i = x - patch_half_width_floor; i < x + patch_half_width_ceil; i += dilation.x()) { coords.set(0, i); coords.set(1, j); -- cgit v1.2.1