From 6e464c37b5335e362ac3f988cc4b0beed5205ff4 Mon Sep 17 00:00:00 2001 From: Isabella Gottardi Date: Fri, 26 Jan 2018 12:32:45 +0000 Subject: COMPMID-828 - Add support for non square pool size - Part1 Change-Id: Ib8100e7c659c49694c746fa3f36ce20f44f6929f Reviewed-on: https://eu-gerrit-1.euhpc.arm.com/117804 Reviewed-by: Michele DiGiorgio Reviewed-by: Georgios Pinitas Tested-by: Jenkins --- arm_compute/core/Size2D.h | 32 +++------------ arm_compute/core/Types.h | 25 ++++++++++-- src/core/CL/kernels/CLPoolingLayerKernel.cpp | 7 ++-- .../GLES_COMPUTE/kernels/GCPoolingLayerKernel.cpp | 9 +++-- src/core/NEON/kernels/NEPoolingLayerKernel.cpp | 19 ++++----- src/runtime/NEON/functions/NEPoolingLayer.cpp | 2 +- tests/validation/CL/PoolingLayer.cpp | 8 ++-- tests/validation/GLES_COMPUTE/PoolingLayer.cpp | 4 +- tests/validation/NEON/PoolingLayer.cpp | 6 +-- tests/validation/fixtures/PoolingLayerFixture.h | 8 ++-- tests/validation/reference/PoolingLayer.cpp | 47 ++++++++++++---------- tests/validation/reference/PoolingLayer.h | 6 +-- utils/TypePrinter.h | 2 +- 13 files changed, 88 insertions(+), 87 deletions(-) diff --git a/arm_compute/core/Size2D.h b/arm_compute/core/Size2D.h index cb053ea2c4..3840771cd1 100644 --- a/arm_compute/core/Size2D.h +++ b/arm_compute/core/Size2D.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2017 ARM Limited. + * Copyright (c) 2016-2018 ARM Limited. * * SPDX-License-Identifier: MIT * @@ -25,6 +25,7 @@ #define __ARM_COMPUTE_SIZE2D_H__ #include +#include namespace arm_compute { @@ -33,10 +34,7 @@ class Size2D { public: /** Default constructor */ - Size2D() - : width(0), height(0) - { - } + Size2D() = default; /** Constructor. Initializes "width" and "height" respectively with "w" and "h" * * @param[in] w Width of the image or rectangle @@ -46,26 +44,6 @@ public: : width(w), height(h) { } - /** Constructor. Initializes "width" and "height" with the dimensions of "size" - * - * @param[in] size Size data object - */ - Size2D(const Size2D &size) - : width(size.width), height(size.height) - { - } - /** Copy assignment - * - * @param[in] size Constant reference input "Size2D" data object to copy - * - * @return Reference to the newly altered left hand side "Size2D" data object - */ - Size2D &operator=(const Size2D &size) - { - width = size.width; - height = size.height; - return *this; - } /** The area of the image or rectangle calculated as (width * height) * * @return Area (width * height) @@ -77,8 +55,8 @@ public: } public: - size_t width; /**< Width of the image region or rectangle */ - size_t height; /**< Height of the image region or rectangle */ + size_t width = {}; /**< Width of the image region or rectangle */ + size_t height = {}; /**< Height of the image region or rectangle */ }; } #endif /*__ARM_COMPUTE_SIZE2D_H__ */ diff --git a/arm_compute/core/Types.h b/arm_compute/core/Types.h index aa415acebe..72be5cba2b 100644 --- a/arm_compute/core/Types.h +++ b/arm_compute/core/Types.h @@ -27,6 +27,7 @@ #include "arm_compute/core/Coordinates.h" #include "arm_compute/core/QAsymm8.h" #include "arm_compute/core/Rounding.h" +#include "arm_compute/core/Size2D.h" #include "arm_compute/core/Strides.h" #include "arm_compute/core/TensorShape.h" #include "support/Half.h" @@ -578,7 +579,7 @@ class PoolingLayerInfo public: /** Default Constructor */ PoolingLayerInfo() - : _pool_type(PoolingType::MAX), _pool_size(0), _pad_stride_info(PadStrideInfo()), _exclude_padding(false), _is_global_pooling(false) + : _pool_type(PoolingType::MAX), _pool_size(Size2D()), _pad_stride_info(PadStrideInfo()), _exclude_padding(false), _is_global_pooling(false) { } /** Default Constructor @@ -594,6 +595,22 @@ public: unsigned int pool_size, PadStrideInfo pad_stride_info = PadStrideInfo(), bool exclude_padding = false) + : _pool_type(pool_type), _pool_size(Size2D(pool_size, pool_size)), _pad_stride_info(pad_stride_info), _exclude_padding(exclude_padding), _is_global_pooling(false) + { + } + /** Default Constructor + * + * @param[in] pool_type Pooling type @ref PoolingType. + * @param[in] pool_size Pooling size, in elements, across x and y. + * @param[in] pad_stride_info (Optional) Padding and stride information @ref PadStrideInfo + * @param[in] exclude_padding (Optional) Strategy when accounting padding in calculations. + * True will exclude padding while false will not (Used in AVG/L2 pooling to determine the pooling area). + * Defaults to false; + */ + explicit PoolingLayerInfo(PoolingType pool_type, + Size2D pool_size, + PadStrideInfo pad_stride_info = PadStrideInfo(), + bool exclude_padding = false) : _pool_type(pool_type), _pool_size(pool_size), _pad_stride_info(pad_stride_info), _exclude_padding(exclude_padding), _is_global_pooling(false) { } @@ -604,14 +621,14 @@ public: * @param[in] pool_type Pooling type @ref PoolingType. */ explicit PoolingLayerInfo(PoolingType pool_type) - : _pool_type(pool_type), _pool_size(0), _pad_stride_info(PadStrideInfo(1, 1, 0, 0)), _exclude_padding(false), _is_global_pooling(true) + : _pool_type(pool_type), _pool_size(Size2D()), _pad_stride_info(PadStrideInfo(1, 1, 0, 0)), _exclude_padding(false), _is_global_pooling(true) { } PoolingType pool_type() const { return _pool_type; } - unsigned int pool_size() const + const Size2D &pool_size() const { return _pool_size; } @@ -630,7 +647,7 @@ public: private: PoolingType _pool_type; - unsigned int _pool_size; + Size2D _pool_size; PadStrideInfo _pad_stride_info; bool _exclude_padding; bool _is_global_pooling; diff --git a/src/core/CL/kernels/CLPoolingLayerKernel.cpp b/src/core/CL/kernels/CLPoolingLayerKernel.cpp index 860cc92266..043a4bde04 100644 --- a/src/core/CL/kernels/CLPoolingLayerKernel.cpp +++ b/src/core/CL/kernels/CLPoolingLayerKernel.cpp @@ -63,12 +63,13 @@ Status validate_arguments(const ITensorInfo *input, const ITensorInfo *output, c "Unsupported combination of parameters!"); const bool is_global_pooling = pool_info.is_global_pooling(); - const unsigned int pool_size = is_global_pooling ? input->tensor_shape().x() : pool_info.pool_size(); + const unsigned int pool_size = is_global_pooling ? input->tensor_shape().x() : pool_info.pool_size().width; ARM_COMPUTE_RETURN_ERROR_ON_MSG(is_global_pooling && (input->tensor_shape().x() != input->tensor_shape().y()), "Global pooling is supported only with rectangular inputs!"); ARM_COMPUTE_RETURN_ERROR_ON_MSG(!is_global_pooling && ((pool_info.pad_stride_info().pad().first >= pool_size) || (pool_info.pad_stride_info().pad().second >= pool_size)), "Invalid pool size and pool pad combination!"); + ARM_COMPUTE_RETURN_ERROR_ON_MSG(pool_info.pool_size().width != pool_info.pool_size().height, "Invalid Pool size, width not equal to height!"); // Checks performed when output is configured if(output->total_size() != 0) @@ -98,7 +99,7 @@ std::tuple validate_and_configure_window(ITenso int pool_stride_y = 0; unsigned int pooled_w = 0; unsigned int pooled_h = 0; - int pool_size = pool_info.pool_size(); + int pool_size = pool_info.pool_size().width; const PadStrideInfo pad_stride_info = pool_info.pad_stride_info(); std::tie(pool_pad_x, pool_pad_y) = pad_stride_info.pad(); std::tie(pool_stride_x, pool_stride_y) = pad_stride_info.stride(); @@ -171,7 +172,7 @@ void CLPoolingLayerKernel::configure(const ICLTensor *input, ICLTensor *output, unsigned int pooled_w = 0; unsigned int pooled_h = 0; const PoolingType pool_type = pool_info.pool_type(); - int pool_size = pool_info.pool_size(); + int pool_size = pool_info.pool_size().width; const PadStrideInfo pad_stride_info = pool_info.pad_stride_info(); const bool exclude_padding = pool_info.exclude_padding(); std::tie(pool_pad_x, pool_pad_y) = pad_stride_info.pad(); diff --git a/src/core/GLES_COMPUTE/kernels/GCPoolingLayerKernel.cpp b/src/core/GLES_COMPUTE/kernels/GCPoolingLayerKernel.cpp index 6451db741d..64b94c0334 100644 --- a/src/core/GLES_COMPUTE/kernels/GCPoolingLayerKernel.cpp +++ b/src/core/GLES_COMPUTE/kernels/GCPoolingLayerKernel.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017 ARM Limited. + * Copyright (c) 2017-2018 ARM Limited. * * SPDX-License-Identifier: MIT * @@ -62,12 +62,13 @@ Status validate_arguments(const ITensorInfo *input, const ITensorInfo *output, c "Unsupported combination of parameters!"); const bool is_global_pooling = pool_info.is_global_pooling(); - const unsigned int pool_size = is_global_pooling ? input->tensor_shape().x() : pool_info.pool_size(); + const unsigned int pool_size = is_global_pooling ? input->tensor_shape().x() : pool_info.pool_size().width; ARM_COMPUTE_RETURN_ERROR_ON_MSG(is_global_pooling && (input->tensor_shape().x() != input->tensor_shape().y()), "Global pooling is supported only with rectangular inputs!"); ARM_COMPUTE_RETURN_ERROR_ON_MSG(!is_global_pooling && ((pool_info.pad_stride_info().pad().first >= pool_size) || (pool_info.pad_stride_info().pad().second >= pool_size)), "Invalid pool size and pool pad combination!"); + ARM_COMPUTE_RETURN_ERROR_ON_MSG(pool_info.pool_size().width != pool_info.pool_size().height, "Invalid Pool size, width not equal to height!"); // Checks performed when output is configured if(output->total_size() != 0) @@ -97,7 +98,7 @@ std::tuple validate_and_configure_window(ITenso int pool_stride_y = 0; unsigned int pooled_w = 0; unsigned int pooled_h = 0; - int pool_size = pool_info.pool_size(); + int pool_size = pool_info.pool_size().width; const PadStrideInfo pad_stride_info = pool_info.pad_stride_info(); std::tie(pool_pad_x, pool_pad_y) = pad_stride_info.pad(); std::tie(pool_stride_x, pool_stride_y) = pad_stride_info.stride(); @@ -229,7 +230,7 @@ void GCPoolingLayerKernel::configure(const IGCTensor *input, IGCTensor *output, unsigned int pooled_w = 0; unsigned int pooled_h = 0; const PoolingType pool_type = pool_info.pool_type(); - int pool_size = pool_info.pool_size(); + int pool_size = pool_info.pool_size().width; const PadStrideInfo pad_stride_info = pool_info.pad_stride_info(); const bool exclude_padding = pool_info.exclude_padding(); std::tie(pool_pad_x, pool_pad_y) = pad_stride_info.pad(); diff --git a/src/core/NEON/kernels/NEPoolingLayerKernel.cpp b/src/core/NEON/kernels/NEPoolingLayerKernel.cpp index be5fa4cc4c..a3ab8a361f 100644 --- a/src/core/NEON/kernels/NEPoolingLayerKernel.cpp +++ b/src/core/NEON/kernels/NEPoolingLayerKernel.cpp @@ -151,7 +151,7 @@ inline void scale_vector_s16x8(uint16x8_t &v, const Coordinates &id, int id_offs v = vsetq_lane_u16(elems[7], v, 7); } -Status validate_arguments(const ITensorInfo *input, const ITensorInfo *output, const PoolingLayerInfo &pool_info, unsigned int &pooled_w, unsigned int pooled_h, int pool_size) +Status validate_arguments(const ITensorInfo *input, const ITensorInfo *output, const PoolingLayerInfo &pool_info, unsigned int &pooled_w, unsigned int pooled_h, int pool_size_x, int pool_size_y) { ARM_COMPUTE_RETURN_ERROR_ON_NULLPTR(input, output); @@ -166,10 +166,11 @@ Status validate_arguments(const ITensorInfo *input, const ITensorInfo *output, c ARM_COMPUTE_RETURN_ERROR_ON_DATA_TYPE_CHANNEL_NOT_IN(input, 1, DataType::QS8, DataType::QASYMM8, DataType::QS16, DataType::F16, DataType::F32); ARM_COMPUTE_RETURN_ERROR_ON(pool_type == PoolingType::L2 && is_data_type_quantized(input->data_type())); - ARM_COMPUTE_RETURN_ERROR_ON((supported_pool_sizes.find(pool_size) == supported_pool_sizes.end()) && ((input->data_type() != DataType::F32) && (input->data_type() != DataType::QASYMM8))); + ARM_COMPUTE_RETURN_ERROR_ON((supported_pool_sizes.find(pool_size_x) == supported_pool_sizes.end()) && ((input->data_type() != DataType::F32) && (input->data_type() != DataType::QASYMM8))); ARM_COMPUTE_RETURN_ERROR_ON(is_global_pooling && (input->tensor_shape().x() != input->tensor_shape().y())); ARM_COMPUTE_RETURN_ERROR_ON(is_data_type_fixed_point(input->data_type()) && pool_stride_x > 2); ARM_COMPUTE_RETURN_ERROR_ON(exclude_padding && is_data_type_fixed_point(input->data_type())); + ARM_COMPUTE_RETURN_ERROR_ON(pool_size_x != pool_size_y); if(output->total_size() != 0) { @@ -370,7 +371,7 @@ void NEPoolingLayerKernel::configure(const ITensor *input, ITensor *output, cons const int pool_stride_x = pad_stride_info.stride().first; // Update pool size in case of global pooling - const int pool_size = is_global_pooling ? input->info()->dimension(0) : pool_info.pool_size(); + const int pool_size = is_global_pooling ? input->info()->dimension(0) : pool_info.pool_size().width; // Validate pool info before calling scaled_dimensions ARM_COMPUTE_ERROR_THROW_ON(validate_arguments_pool_info(input->info(), pool_info, pool_size)); @@ -387,7 +388,7 @@ void NEPoolingLayerKernel::configure(const ITensor *input, ITensor *output, cons auto_init(input->info(), output->info(), pooled_w, pooled_h); // Perform validation step - ARM_COMPUTE_ERROR_THROW_ON(validate_arguments(input->info(), output->info(), pool_info, pooled_w, pooled_h, pool_size)); + ARM_COMPUTE_ERROR_THROW_ON(validate_arguments(input->info(), output->info(), pool_info, pooled_w, pooled_h, pool_size, pool_size)); // Set instance variables _input = input; @@ -1491,7 +1492,7 @@ void NEPoolingLayerKernel::poolingN_f32(const Window &window_input, const Window Iterator input(_input, window_input); Iterator output(_output, window); - const int pool_size = _pool_info.is_global_pooling() ? _input->info()->tensor_shape().x() : _pool_info.pool_size(); + const int pool_size = _pool_info.is_global_pooling() ? _input->info()->tensor_shape().x() : _pool_info.pool_size().width; const int pool_pad_right = _pool_info.pad_stride_info().pad_right(); const int pool_pad_top = _pool_info.pad_stride_info().pad_top(); const int pool_pad_left = _pool_info.pad_stride_info().pad_left(); @@ -1613,7 +1614,7 @@ void NEPoolingLayerKernel::poolingN_qasymm8(const Window &window_input, const Wi Iterator input(_input, window_input); Iterator output(_output, window); - const int pool_size = _pool_info.is_global_pooling() ? _input->info()->tensor_shape().x() : _pool_info.pool_size(); + const int pool_size = _pool_info.is_global_pooling() ? _input->info()->tensor_shape().x() : _pool_info.pool_size().width; const int pool_pad_right = _pool_info.pad_stride_info().pad_right(); const int pool_pad_top = _pool_info.pad_stride_info().pad_top(); const int pool_pad_left = _pool_info.pad_stride_info().pad_left(); @@ -1712,7 +1713,7 @@ Status NEPoolingLayerKernel::validate(const ITensorInfo *input, const ITensorInf BorderSize border_size(0); const bool is_global_pooling = pool_info.is_global_pooling(); - const unsigned int pool_size = is_global_pooling ? input->tensor_shape().x() : pool_info.pool_size(); + const unsigned int pool_size = is_global_pooling ? input->tensor_shape().x() : pool_info.pool_size().width; // Validate pool info befor calling scaled_dimensions ARM_COMPUTE_RETURN_ON_ERROR(validate_arguments_pool_info(input, pool_info, pool_size)); @@ -1724,7 +1725,7 @@ Status NEPoolingLayerKernel::validate(const ITensorInfo *input, const ITensorInf pool_size, pool_info.pad_stride_info()); - ARM_COMPUTE_RETURN_ON_ERROR(validate_arguments(input, output, pool_info, pooled_w, pooled_h, pool_size)); + ARM_COMPUTE_RETURN_ON_ERROR(validate_arguments(input, output, pool_info, pooled_w, pooled_h, pool_size, pool_size)); ARM_COMPUTE_RETURN_ON_ERROR(validate_and_configure_window(input->clone().get(), output->clone().get(), pool_info, num_elems_processed_per_iteration, border_size, pooled_w, pooled_h, pool_size).first); return Status{}; @@ -1739,7 +1740,7 @@ void NEPoolingLayerKernel::run(const Window &window, const ThreadInfo &info) const unsigned int pool_stride_x = _pool_info.pad_stride_info().stride().first; const unsigned int pool_stride_y = _pool_info.pad_stride_info().stride().second; - const unsigned int pool_size = _pool_info.pool_size(); + const unsigned int pool_size = _pool_info.pool_size().width; // Set step for input in x and y direction for the input Window window_input(window); diff --git a/src/runtime/NEON/functions/NEPoolingLayer.cpp b/src/runtime/NEON/functions/NEPoolingLayer.cpp index 8a32507a73..bc0b6f86d3 100644 --- a/src/runtime/NEON/functions/NEPoolingLayer.cpp +++ b/src/runtime/NEON/functions/NEPoolingLayer.cpp @@ -38,7 +38,7 @@ NEPoolingLayer::NEPoolingLayer() void NEPoolingLayer::configure(ITensor *input, ITensor *output, const PoolingLayerInfo &pool_info) { // Check if we have Global Pooling Layer - _is_global_pooling_layer = (input->info()->dimension(0) == pool_info.pool_size()) && (input->info()->dimension(1) == pool_info.pool_size()); + _is_global_pooling_layer = (input->info()->dimension(0) == pool_info.pool_size().width) && (input->info()->dimension(1) == pool_info.pool_size().height); // Configure pooling kernel _pooling_layer_kernel.configure(input, output, pool_info); diff --git a/tests/validation/CL/PoolingLayer.cpp b/tests/validation/CL/PoolingLayer.cpp index fdb2a8dd20..a830e0841f 100644 --- a/tests/validation/CL/PoolingLayer.cpp +++ b/tests/validation/CL/PoolingLayer.cpp @@ -46,21 +46,21 @@ namespace /** Failing data set */ const auto PoolingLayerDatasetSpecial = ((((framework::dataset::make("Shape", TensorShape{ 60U, 52U, 3U, 5U }) * framework::dataset::make("PoolType", PoolingType::AVG)) - * framework::dataset::make("PoolingSize", 100)) + * framework::dataset::make("PoolingSize", Size2D(100, 100))) * framework::dataset::make("PadStride", PadStrideInfo(5, 5, 50, 50))) * framework::dataset::make("ExcludePadding", true)); /** Input data set for floating-point data types */ -const auto PoolingLayerDatasetFP = combine(combine(combine(datasets::PoolingTypes(), framework::dataset::make("PoolingSize", { 2, 3, 4, 7, 9 })), +const auto PoolingLayerDatasetFP = combine(combine(combine(datasets::PoolingTypes(), framework::dataset::make("PoolingSize", { Size2D(2, 2), Size2D(3, 3), Size2D(7, 7), Size2D(9, 9) })), framework::dataset::make("PadStride", { PadStrideInfo(1, 1, 0, 0), PadStrideInfo(2, 1, 0, 0), PadStrideInfo(1, 2, 1, 1), PadStrideInfo(2, 2, 1, 0) })), framework::dataset::make("ExcludePadding", { true, false })); /** Input data set for fixed-point data types */ -const auto PoolingLayerDatasetQS = combine(combine(combine(framework::dataset::make("PoolingType", { PoolingType::MAX, PoolingType::AVG }), framework::dataset::make("PoolingSize", { 2, 3 })), +const auto PoolingLayerDatasetQS = combine(combine(combine(framework::dataset::make("PoolingType", { PoolingType::MAX, PoolingType::AVG }), framework::dataset::make("PoolingSize", { Size2D(2, 2), Size2D(3, 3) })), framework::dataset::make("PadStride", { PadStrideInfo(1, 1, 0, 0), PadStrideInfo(2, 1, 0, 0), PadStrideInfo(1, 2, 1, 1), PadStrideInfo(2, 2, 1, 0) })), framework::dataset::make("ExcludePadding", { true, false })); /** Input data set for asymmetric data type */ -const auto PoolingLayerDatasetQASYMM8 = combine(combine(combine(framework::dataset::make("PoolingType", { PoolingType::MAX, PoolingType::AVG }), framework::dataset::make("PoolingSize", { 2, 3 })), +const auto PoolingLayerDatasetQASYMM8 = combine(combine(combine(framework::dataset::make("PoolingType", { PoolingType::MAX, PoolingType::AVG }), framework::dataset::make("PoolingSize", { Size2D(2, 2), Size2D(3, 3) })), framework::dataset::make("PadStride", { PadStrideInfo(1, 1, 0, 0), PadStrideInfo(2, 1, 0, 0), PadStrideInfo(1, 2, 1, 1), PadStrideInfo(2, 2, 1, 0) })), framework::dataset::make("ExcludePadding", { true, false })); diff --git a/tests/validation/GLES_COMPUTE/PoolingLayer.cpp b/tests/validation/GLES_COMPUTE/PoolingLayer.cpp index e789dbab07..1496ceec1c 100644 --- a/tests/validation/GLES_COMPUTE/PoolingLayer.cpp +++ b/tests/validation/GLES_COMPUTE/PoolingLayer.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017 ARM Limited. + * Copyright (c) 2017-2018 ARM Limited. * * SPDX-License-Identifier: MIT * @@ -44,7 +44,7 @@ namespace validation namespace { /** Input data set for floating-point data types */ -const auto PoolingLayerDatasetFP = combine(combine(combine(datasets::PoolingTypes(), framework::dataset::make("PoolingSize", { 2, 3, 4, 7, 9 })), +const auto PoolingLayerDatasetFP = combine(combine(combine(datasets::PoolingTypes(), framework::dataset::make("PoolingSize", { Size2D(2, 2), Size2D(3, 3), Size2D(4, 4), Size2D(7, 7), Size2D(9, 9) })), framework::dataset::make("PadStride", { PadStrideInfo(1, 1, 0, 0), PadStrideInfo(2, 1, 0, 0), PadStrideInfo(1, 2, 1, 1), PadStrideInfo(2, 2, 1, 0) })), framework::dataset::make("ExcludePadding", { true, false })); diff --git a/tests/validation/NEON/PoolingLayer.cpp b/tests/validation/NEON/PoolingLayer.cpp index e526613bdd..eace8d7148 100644 --- a/tests/validation/NEON/PoolingLayer.cpp +++ b/tests/validation/NEON/PoolingLayer.cpp @@ -44,17 +44,17 @@ namespace validation namespace { /** Input data set for float data types */ -const auto PoolingLayerDatasetFP = combine(combine(combine(datasets::PoolingTypes(), framework::dataset::make("PoolingSize", { 2, 3, 7, 9 })), +const auto PoolingLayerDatasetFP = combine(combine(combine(datasets::PoolingTypes(), framework::dataset::make("PoolingSize", { Size2D(2, 2), Size2D(3, 3), Size2D(7, 7), Size2D(9, 9) })), framework::dataset::make("PadStride", { PadStrideInfo(1, 1, 0, 0), PadStrideInfo(2, 1, 0, 0), PadStrideInfo(1, 2, 1, 1), PadStrideInfo(2, 2, 1, 0) })), framework::dataset::make("ExcludePadding", { true, false })); /** Input data set for quantized data types */ -const auto PoolingLayerDatasetQS = combine(combine(combine(framework::dataset::make("PoolingType", { PoolingType::MAX, PoolingType::AVG }), framework::dataset::make("PoolingSize", { 2, 3 })), +const auto PoolingLayerDatasetQS = combine(combine(combine(framework::dataset::make("PoolingType", { PoolingType::MAX, PoolingType::AVG }), framework::dataset::make("PoolingSize", { Size2D(2, 2), Size2D(3, 3) })), framework::dataset::make("PadStride", { PadStrideInfo(1, 1, 0, 0), PadStrideInfo(2, 1, 0, 0), PadStrideInfo(1, 2, 1, 1), PadStrideInfo(2, 2, 1, 0) })), framework::dataset::make("ExcludePadding", { false })); /** Input data set for asymmetric data type */ -const auto PoolingLayerDatasetQASYMM8 = combine(combine(combine(framework::dataset::make("PoolingType", { PoolingType::MAX, PoolingType::AVG }), framework::dataset::make("PoolingSize", { 2, 3, 9 })), +const auto PoolingLayerDatasetQASYMM8 = combine(combine(combine(framework::dataset::make("PoolingType", { PoolingType::MAX, PoolingType::AVG }), framework::dataset::make("PoolingSize", { Size2D(2, 2), Size2D(3, 3), Size2D(9, 9) })), framework::dataset::make("PadStride", { PadStrideInfo(1, 1, 0, 0), PadStrideInfo(2, 1, 0, 0), PadStrideInfo(1, 2, 1, 1), PadStrideInfo(2, 2, 1, 0) })), framework::dataset::make("ExcludePadding", { true, false })); diff --git a/tests/validation/fixtures/PoolingLayerFixture.h b/tests/validation/fixtures/PoolingLayerFixture.h index 890eef2d4b..f101199365 100644 --- a/tests/validation/fixtures/PoolingLayerFixture.h +++ b/tests/validation/fixtures/PoolingLayerFixture.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017 ARM Limited. + * Copyright (c) 2017-2018 ARM Limited. * * SPDX-License-Identifier: MIT * @@ -132,7 +132,7 @@ class PoolingLayerValidationFixture : public PoolingLayerValidationGenericFixtur { public: template - void setup(TensorShape shape, PoolingType pool_type, int pool_size, PadStrideInfo pad_stride_info, bool exclude_padding, DataType data_type) + void setup(TensorShape shape, PoolingType pool_type, Size2D pool_size, PadStrideInfo pad_stride_info, bool exclude_padding, DataType data_type) { PoolingLayerValidationGenericFixture::setup(shape, PoolingLayerInfo(pool_type, pool_size, pad_stride_info, exclude_padding), data_type, 0, QuantizationInfo()); @@ -144,7 +144,7 @@ class PoolingLayerValidationFixedPointFixture : public PoolingLayerValidationGen { public: template - void setup(TensorShape shape, PoolingType pool_type, int pool_size, PadStrideInfo pad_stride_info, bool exclude_padding, DataType data_type, int fractional_bits) + void setup(TensorShape shape, PoolingType pool_type, Size2D pool_size, PadStrideInfo pad_stride_info, bool exclude_padding, DataType data_type, int fractional_bits) { PoolingLayerValidationGenericFixture::setup(shape, PoolingLayerInfo(pool_type, pool_size, pad_stride_info, exclude_padding), data_type, fractional_bits, QuantizationInfo()); @@ -156,7 +156,7 @@ class PoolingLayerValidationQuantizedFixture : public PoolingLayerValidationGene { public: template - void setup(TensorShape shape, PoolingType pool_type, int pool_size, PadStrideInfo pad_stride_info, bool exclude_padding, DataType data_type, QuantizationInfo quantization_info) + void setup(TensorShape shape, PoolingType pool_type, Size2D pool_size, PadStrideInfo pad_stride_info, bool exclude_padding, DataType data_type, QuantizationInfo quantization_info) { PoolingLayerValidationGenericFixture::setup(shape, PoolingLayerInfo(pool_type, pool_size, pad_stride_info, exclude_padding), data_type, 0, quantization_info); diff --git a/tests/validation/reference/PoolingLayer.cpp b/tests/validation/reference/PoolingLayer.cpp index d05c0403ff..c14ab98c28 100644 --- a/tests/validation/reference/PoolingLayer.cpp +++ b/tests/validation/reference/PoolingLayer.cpp @@ -37,14 +37,15 @@ namespace reference { namespace { -TensorShape calculate_output_shape(TensorShape shape, PoolingLayerInfo info) +TensorShape calculate_output_shape(TensorShape shape, const PoolingLayerInfo &info) { - TensorShape dst_shape = shape; - const int pool_size = info.is_global_pooling() ? shape.x() : info.pool_size(); + TensorShape dst_shape = shape; + const int pool_size_x = info.is_global_pooling() ? shape.x() : info.pool_size().width; + const int pool_size_y = info.is_global_pooling() ? shape.y() : info.pool_size().height; const std::pair scaled_dims = arm_compute::scaled_dimensions(shape.x(), shape.y(), - pool_size, - pool_size, + pool_size_x, + pool_size_y, info.pad_stride_info()); dst_shape.set(0, scaled_dims.first); dst_shape.set(1, scaled_dims.second); @@ -54,11 +55,12 @@ TensorShape calculate_output_shape(TensorShape shape, PoolingLayerInfo info) } // namespace template ::value, int>::type> -SimpleTensor pooling_layer(const SimpleTensor &src, PoolingLayerInfo info) +SimpleTensor pooling_layer(const SimpleTensor &src, const PoolingLayerInfo &info) { ARM_COMPUTE_ERROR_ON(info.is_global_pooling() && (src.shape().x() != src.shape().y())); - const int pool_size = info.is_global_pooling() ? src.shape().x() : info.pool_size(); + const int pool_size_x = info.is_global_pooling() ? src.shape().x() : info.pool_size().width; + const int pool_size_y = info.is_global_pooling() ? src.shape().y() : info.pool_size().height; PoolingType type = info.pool_type(); int pool_stride_x = info.pad_stride_info().stride().first; int pool_stride_y = info.pad_stride_info().stride().second; @@ -88,8 +90,8 @@ SimpleTensor pooling_layer(const SimpleTensor &src, PoolingLayerInfo info) { int wstart = w * pool_stride_x - pad_left; int hstart = h * pool_stride_y - pad_top; - int wend = std::min(wstart + pool_size, w_src); - int hend = std::min(hstart + pool_size, h_src); + int wend = std::min(wstart + pool_size_x, w_src); + int hend = std::min(hstart + pool_size_y, h_src); wstart = std::max(wstart, 0); hstart = std::max(hstart, 0); @@ -122,8 +124,8 @@ SimpleTensor pooling_layer(const SimpleTensor &src, PoolingLayerInfo info) T avg_val(0); int wstart = w * pool_stride_x - pad_left; int hstart = h * pool_stride_y - pad_top; - int wend = std::min(wstart + pool_size, w_src + pad_right); - int hend = std::min(hstart + pool_size, h_src + pad_bottom); + int wend = std::min(wstart + pool_size_x, w_src + pad_right); + int hend = std::min(hstart + pool_size_y, h_src + pad_bottom); int pool = (hend - hstart) * (wend - wstart); wstart = std::max(wstart, 0); hstart = std::max(hstart, 0); @@ -167,11 +169,12 @@ SimpleTensor pooling_layer(const SimpleTensor &src, PoolingLayerInfo info) } template ::value, int>::type> -SimpleTensor pooling_layer(const SimpleTensor &src, PoolingLayerInfo info) +SimpleTensor pooling_layer(const SimpleTensor &src, const PoolingLayerInfo &info) { ARM_COMPUTE_ERROR_ON(info.is_global_pooling() && (src.shape().x() != src.shape().y())); - const int pool_size = info.is_global_pooling() ? src.shape().x() : info.pool_size(); + const int pool_size_x = info.is_global_pooling() ? src.shape().x() : info.pool_size().width; + const int pool_size_y = info.is_global_pooling() ? src.shape().y() : info.pool_size().height; PoolingType type = info.pool_type(); int pool_stride_x = info.pad_stride_info().stride().first; int pool_stride_y = info.pad_stride_info().stride().second; @@ -201,8 +204,8 @@ SimpleTensor pooling_layer(const SimpleTensor &src, PoolingLayerInfo info) { int wstart = w * pool_stride_x - pad_left; int hstart = h * pool_stride_y - pad_top; - int wend = std::min(wstart + pool_size, w_src); - int hend = std::min(hstart + pool_size, h_src); + int wend = std::min(wstart + pool_size_x, w_src); + int hend = std::min(hstart + pool_size_y, h_src); wstart = std::max(wstart, 0); hstart = std::max(hstart, 0); @@ -234,8 +237,8 @@ SimpleTensor pooling_layer(const SimpleTensor &src, PoolingLayerInfo info) { int wstart = w * pool_stride_x - pad_left; int hstart = h * pool_stride_y - pad_top; - int wend = std::min(wstart + pool_size, w_src + pad_right); - int hend = std::min(hstart + pool_size, h_src + pad_bottom); + int wend = std::min(wstart + pool_size_x, w_src + pad_right); + int hend = std::min(hstart + pool_size_y, h_src + pad_bottom); int pool = (hend - hstart) * (wend - wstart); wstart = std::max(wstart, 0); hstart = std::max(hstart, 0); @@ -288,7 +291,7 @@ SimpleTensor pooling_layer(const SimpleTensor &src, PoolingLayerInfo info) } template <> -SimpleTensor pooling_layer(const SimpleTensor &src, PoolingLayerInfo info) +SimpleTensor pooling_layer(const SimpleTensor &src, const PoolingLayerInfo &info) { SimpleTensor src_tmp = convert_from_asymmetric(src); SimpleTensor dst_tmp = pooling_layer(src_tmp, info); @@ -296,10 +299,10 @@ SimpleTensor pooling_layer(const SimpleTensor &src, P return dst; } -template SimpleTensor pooling_layer(const SimpleTensor &src, PoolingLayerInfo info); -template SimpleTensor pooling_layer(const SimpleTensor &src, PoolingLayerInfo info); -template SimpleTensor pooling_layer(const SimpleTensor &src, PoolingLayerInfo info); -template SimpleTensor pooling_layer(const SimpleTensor &src, PoolingLayerInfo info); +template SimpleTensor pooling_layer(const SimpleTensor &src, const PoolingLayerInfo &info); +template SimpleTensor pooling_layer(const SimpleTensor &src, const PoolingLayerInfo &info); +template SimpleTensor pooling_layer(const SimpleTensor &src, const PoolingLayerInfo &info); +template SimpleTensor pooling_layer(const SimpleTensor &src, const PoolingLayerInfo &info); } // namespace reference } // namespace validation } // namespace test diff --git a/tests/validation/reference/PoolingLayer.h b/tests/validation/reference/PoolingLayer.h index 334054a0eb..b0d30af32a 100644 --- a/tests/validation/reference/PoolingLayer.h +++ b/tests/validation/reference/PoolingLayer.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017 ARM Limited. + * Copyright (c) 2017-2018 ARM Limited. * * SPDX-License-Identifier: MIT * @@ -36,10 +36,10 @@ namespace validation namespace reference { template ::value, int>::type = 0> -SimpleTensor pooling_layer(const SimpleTensor &src, PoolingLayerInfo info); +SimpleTensor pooling_layer(const SimpleTensor &src, const PoolingLayerInfo &info); template ::value, int>::type = 0> -SimpleTensor pooling_layer(const SimpleTensor &src, PoolingLayerInfo info); +SimpleTensor pooling_layer(const SimpleTensor &src, const PoolingLayerInfo &info); } // namespace reference } // namespace validation } // namespace test diff --git a/utils/TypePrinter.h b/utils/TypePrinter.h index cab8029199..048df4358b 100644 --- a/utils/TypePrinter.h +++ b/utils/TypePrinter.h @@ -760,7 +760,7 @@ inline std::string to_string(const PoolingLayerInfo &info) if(!info.is_global_pooling()) { str << "," - << "PoolSize=" << info.pool_size() << "," + << "PoolSize=" << info.pool_size().width << "," << info.pool_size().height << "," << "PadStride=" << info.pad_stride_info(); } str << "}"; -- cgit v1.2.1