diff options
Diffstat (limited to 'tests/validation')
-rw-r--r-- | tests/validation/NEON/PoolingLayer.cpp | 19 | ||||
-rw-r--r-- | tests/validation/fixtures/PoolingLayerFixture.h | 42 | ||||
-rw-r--r-- | tests/validation/reference/PoolingLayer.cpp | 42 | ||||
-rw-r--r-- | tests/validation/reference/PoolingLayer.h | 4 |
4 files changed, 76 insertions, 31 deletions
diff --git a/tests/validation/NEON/PoolingLayer.cpp b/tests/validation/NEON/PoolingLayer.cpp index 1012320b0d..a5876dcd0a 100644 --- a/tests/validation/NEON/PoolingLayer.cpp +++ b/tests/validation/NEON/PoolingLayer.cpp @@ -112,13 +112,32 @@ DATA_TEST_CASE(Validate, framework::DatasetMode::ALL, zip(zip(zip( // *INDENT-ON* template <typename T> +using NEPoolingLayerIndicesFixture = PoolingLayerIndicesValidationFixture<Tensor, Accessor, NEPoolingLayer, T>; + +template <typename T> using NEPoolingLayerFixture = PoolingLayerValidationFixture<Tensor, Accessor, NEPoolingLayer, T>; template <typename T> using NESpecialPoolingLayerFixture = SpecialPoolingLayerValidationFixture<Tensor, Accessor, NEPoolingLayer, T>; +const auto PoolingLayerIndicesDatasetFPSmall = combine(combine(combine(framework::dataset::make("PoolType", { PoolingType::MAX }), framework::dataset::make("PoolingSize", { Size2D(2, 2) })), + framework::dataset::make("PadStride", { PadStrideInfo(1, 1, 0, 0), PadStrideInfo(2, 1, 0, 0) })), + framework::dataset::make("ExcludePadding", { true, false })); + TEST_SUITE(Float) TEST_SUITE(FP32) +FIXTURE_DATA_TEST_CASE(RunIndices, NEPoolingLayerIndicesFixture<float>, framework::DatasetMode::PRECOMMIT, combine(combine(datasets::SmallShapes(), combine(PoolingLayerIndicesDatasetFPSmall, + framework::dataset::make("DataType", + DataType::F32))), + framework::dataset::make("DataLayout", { DataLayout::NCHW }) + + )) +{ + // Validate output + validate(Accessor(_target), _reference, tolerance_f32); + validate(Accessor(_target_indices), _ref_indices); +} + FIXTURE_DATA_TEST_CASE(RunSpecial, NESpecialPoolingLayerFixture<float>, framework::DatasetMode::ALL, datasets::PoolingLayerDatasetSpecial() * framework::dataset::make("DataType", DataType::F32)) { // Validate output diff --git a/tests/validation/fixtures/PoolingLayerFixture.h b/tests/validation/fixtures/PoolingLayerFixture.h index ec186564b7..7f2d7ac225 100644 --- a/tests/validation/fixtures/PoolingLayerFixture.h +++ b/tests/validation/fixtures/PoolingLayerFixture.h @@ -34,7 +34,6 @@ #include "tests/framework/Asserts.h" #include "tests/framework/Fixture.h" #include "tests/validation/reference/PoolingLayer.h" - #include <random> namespace arm_compute @@ -48,7 +47,7 @@ class PoolingLayerValidationGenericFixture : public framework::Fixture { public: template <typename...> - void setup(TensorShape shape, PoolingLayerInfo pool_info, DataType data_type, DataLayout data_layout) + void setup(TensorShape shape, PoolingLayerInfo pool_info, DataType data_type, DataLayout data_layout, bool indices = false) { std::mt19937 gen(library->seed()); std::uniform_int_distribution<> offset_dis(0, 20); @@ -59,8 +58,8 @@ public: const QuantizationInfo output_qinfo(scale, scale_out); _pool_info = pool_info; - _target = compute_target(shape, pool_info, data_type, data_layout, input_qinfo, output_qinfo); - _reference = compute_reference(shape, pool_info, data_type, input_qinfo, output_qinfo); + _target = compute_target(shape, pool_info, data_type, data_layout, input_qinfo, output_qinfo, indices); + _reference = compute_reference(shape, pool_info, data_type, input_qinfo, output_qinfo, indices); } protected: @@ -79,7 +78,9 @@ protected: } TensorType compute_target(TensorShape shape, PoolingLayerInfo info, - DataType data_type, DataLayout data_layout, QuantizationInfo input_qinfo, QuantizationInfo output_qinfo) + DataType data_type, DataLayout data_layout, + QuantizationInfo input_qinfo, QuantizationInfo output_qinfo, + bool indices) { // Change shape in case of NHWC. if(data_layout == DataLayout::NHWC) @@ -91,20 +92,24 @@ protected: TensorType src = create_tensor<TensorType>(shape, data_type, 1, input_qinfo, data_layout); const TensorShape dst_shape = misc::shape_calculator::compute_pool_shape(*(src.info()), info); TensorType dst = create_tensor<TensorType>(dst_shape, data_type, 1, output_qinfo, data_layout); + _target_indices = create_tensor<TensorType>(dst_shape, DataType::U32, 1); // Create and configure function FunctionType pool_layer; - pool_layer.configure(&src, &dst, info); + pool_layer.configure(&src, &dst, info, (indices) ? &_target_indices : nullptr); ARM_COMPUTE_EXPECT(src.info()->is_resizable(), framework::LogLevel::ERRORS); ARM_COMPUTE_EXPECT(dst.info()->is_resizable(), framework::LogLevel::ERRORS); + ARM_COMPUTE_EXPECT(_target_indices.info()->is_resizable(), framework::LogLevel::ERRORS); // Allocate tensors src.allocator()->allocate(); dst.allocator()->allocate(); + _target_indices.allocator()->allocate(); ARM_COMPUTE_EXPECT(!src.info()->is_resizable(), framework::LogLevel::ERRORS); ARM_COMPUTE_EXPECT(!dst.info()->is_resizable(), framework::LogLevel::ERRORS); + ARM_COMPUTE_EXPECT(!_target_indices.info()->is_resizable(), framework::LogLevel::ERRORS); // Fill tensors fill(AccessorType(src)); @@ -115,20 +120,33 @@ protected: return dst; } - SimpleTensor<T> compute_reference(const TensorShape &shape, PoolingLayerInfo info, DataType data_type, QuantizationInfo input_qinfo, QuantizationInfo output_qinfo) + SimpleTensor<T> compute_reference(const TensorShape &shape, PoolingLayerInfo info, DataType data_type, + QuantizationInfo input_qinfo, QuantizationInfo output_qinfo, bool indices) { // Create reference SimpleTensor<T> src{ shape, data_type, 1, input_qinfo }; - // Fill reference fill(src); - return reference::pooling_layer<T>(src, info, output_qinfo); + return reference::pooling_layer<T>(src, info, output_qinfo, indices ? &_ref_indices : nullptr); } - TensorType _target{}; - SimpleTensor<T> _reference{}; - PoolingLayerInfo _pool_info{}; + TensorType _target{}; + SimpleTensor<T> _reference{}; + PoolingLayerInfo _pool_info{}; + TensorType _target_indices{}; + SimpleTensor<uint32_t> _ref_indices{}; +}; +template <typename TensorType, typename AccessorType, typename FunctionType, typename T> +class PoolingLayerIndicesValidationFixture : public PoolingLayerValidationGenericFixture<TensorType, AccessorType, FunctionType, T> +{ +public: + template <typename...> + void setup(TensorShape shape, PoolingType pool_type, Size2D pool_size, PadStrideInfo pad_stride_info, bool exclude_padding, DataType data_type, DataLayout data_layout) + { + PoolingLayerValidationGenericFixture<TensorType, AccessorType, FunctionType, T>::setup(shape, PoolingLayerInfo(pool_type, pool_size, data_layout, pad_stride_info, exclude_padding), + data_type, data_layout, true); + } }; template <typename TensorType, typename AccessorType, typename FunctionType, typename T> diff --git a/tests/validation/reference/PoolingLayer.cpp b/tests/validation/reference/PoolingLayer.cpp index ed2eb2c7ec..1a1aebd1b4 100644 --- a/tests/validation/reference/PoolingLayer.cpp +++ b/tests/validation/reference/PoolingLayer.cpp @@ -38,13 +38,15 @@ namespace reference using namespace arm_compute::misc::shape_calculator; template <typename T, typename ACC_T, typename std::enable_if<is_floating_point<T>::value, int>::type> -SimpleTensor<T> pooling_layer_internal(const SimpleTensor<T> &src, const PoolingLayerInfo &info) +SimpleTensor<T> pooling_layer_internal(const SimpleTensor<T> &src, const PoolingLayerInfo &info, SimpleTensor<uint32_t> *indices) { ARM_COMPUTE_ERROR_ON(info.is_global_pooling && (src.shape().x() != src.shape().y())); - // Create reference SimpleTensor<T> dst{ compute_pool_shape(TensorInfo(src.shape(), 1, src.data_type()), info), src.data_type(), 1 }; - + if(indices) + { + *indices = SimpleTensor<uint32_t> { compute_pool_shape(TensorInfo(src.shape(), 1, src.data_type()), info), DataType::U32, 1 }; + } 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; @@ -79,6 +81,7 @@ SimpleTensor<T> pooling_layer_internal(const SimpleTensor<T> &src, const Pooling hstart = std::max(hstart, 0); auto max_val = std::numeric_limits<ACC_T>::lowest(); + int max_index{ 0 }; for(int y = hstart; y < hend; ++y) { for(int x = wstart; x < wend; ++x) @@ -86,12 +89,17 @@ SimpleTensor<T> pooling_layer_internal(const SimpleTensor<T> &src, const Pooling const auto val = static_cast<ACC_T>(src[r * h_src * w_src + y * w_src + x]); if(val > max_val) { - max_val = val; + max_val = val; + max_index = coord2index(src.shape(), Coordinates(x, y, r)); } } } dst[r * h_dst * w_dst + h * w_dst + w] = static_cast<T>(max_val); + if(indices) + { + (*indices)[r * h_dst * w_dst + h * w_dst + w] = max_index; + } } } } @@ -151,48 +159,48 @@ SimpleTensor<T> pooling_layer_internal(const SimpleTensor<T> &src, const Pooling return dst; } -template SimpleTensor<float> pooling_layer_internal<float>(const SimpleTensor<float> &src, const PoolingLayerInfo &info); -template SimpleTensor<half> pooling_layer_internal<half>(const SimpleTensor<half> &src, const PoolingLayerInfo &info); -template SimpleTensor<half> pooling_layer_internal<half, float>(const SimpleTensor<half> &src, const PoolingLayerInfo &info); +template SimpleTensor<float> pooling_layer_internal<float>(const SimpleTensor<float> &src, const PoolingLayerInfo &info, SimpleTensor<uint32_t> *indices); +template SimpleTensor<half> pooling_layer_internal<half>(const SimpleTensor<half> &src, const PoolingLayerInfo &info, SimpleTensor<uint32_t> *indices); +template SimpleTensor<half> pooling_layer_internal<half, float>(const SimpleTensor<half> &src, const PoolingLayerInfo &info, SimpleTensor<uint32_t> *indices); template <typename T> -SimpleTensor<T> pooling_layer(const SimpleTensor<T> &src, const PoolingLayerInfo &info, const QuantizationInfo &output_qinfo) +SimpleTensor<T> pooling_layer(const SimpleTensor<T> &src, const PoolingLayerInfo &info, const QuantizationInfo &output_qinfo, SimpleTensor<uint32_t> *indices) { ARM_COMPUTE_UNUSED(output_qinfo); - return pooling_layer_internal<T, T>(src, info); + return pooling_layer_internal<T, T>(src, info, indices); } template <> -SimpleTensor<uint8_t> pooling_layer<uint8_t>(const SimpleTensor<uint8_t> &src, const PoolingLayerInfo &info, const QuantizationInfo &output_qinfo) +SimpleTensor<uint8_t> pooling_layer<uint8_t>(const SimpleTensor<uint8_t> &src, const PoolingLayerInfo &info, const QuantizationInfo &output_qinfo, SimpleTensor<uint32_t> *indices) { SimpleTensor<float> src_tmp = convert_from_asymmetric(src); - SimpleTensor<float> dst_tmp = pooling_layer_internal<float>(src_tmp, info); + SimpleTensor<float> dst_tmp = pooling_layer_internal<float>(src_tmp, info, indices); SimpleTensor<uint8_t> dst = convert_to_asymmetric<uint8_t>(dst_tmp, output_qinfo); return dst; } template <> -SimpleTensor<int8_t> pooling_layer<int8_t>(const SimpleTensor<int8_t> &src, const PoolingLayerInfo &info, const QuantizationInfo &output_qinfo) +SimpleTensor<int8_t> pooling_layer<int8_t>(const SimpleTensor<int8_t> &src, const PoolingLayerInfo &info, const QuantizationInfo &output_qinfo, SimpleTensor<uint32_t> *indices) { SimpleTensor<float> src_tmp = convert_from_asymmetric(src); - SimpleTensor<float> dst_tmp = pooling_layer_internal<float>(src_tmp, info); + SimpleTensor<float> dst_tmp = pooling_layer_internal<float>(src_tmp, info, indices); SimpleTensor<int8_t> dst = convert_to_asymmetric<int8_t>(dst_tmp, output_qinfo); return dst; } template <> -SimpleTensor<half> pooling_layer(const SimpleTensor<half> &src, const PoolingLayerInfo &info, const QuantizationInfo &output_qinfo) +SimpleTensor<half> pooling_layer(const SimpleTensor<half> &src, const PoolingLayerInfo &info, const QuantizationInfo &output_qinfo, SimpleTensor<uint32_t> *indices) { ARM_COMPUTE_UNUSED(output_qinfo); if(src.data_type() == DataType::F16 && info.fp_mixed_precision) { - return pooling_layer_internal<half, float>(src, info); + return pooling_layer_internal<half, float>(src, info, indices); } - return pooling_layer_internal<half>(src, info); + return pooling_layer_internal<half>(src, info, indices); } -template SimpleTensor<float> pooling_layer(const SimpleTensor<float> &src, const PoolingLayerInfo &info, const QuantizationInfo &output_qinfo); +template SimpleTensor<float> pooling_layer(const SimpleTensor<float> &src, const PoolingLayerInfo &info, const QuantizationInfo &output_qinfo, SimpleTensor<uint32_t> *indices); } // namespace reference } // namespace validation } // namespace test diff --git a/tests/validation/reference/PoolingLayer.h b/tests/validation/reference/PoolingLayer.h index 92d97d548e..3ca7f28d5a 100644 --- a/tests/validation/reference/PoolingLayer.h +++ b/tests/validation/reference/PoolingLayer.h @@ -36,9 +36,9 @@ namespace validation namespace reference { template <typename T, typename ACC_T = T, typename std::enable_if<is_floating_point<T>::value, int>::type = 0> -SimpleTensor<T> pooling_layer_internal(const SimpleTensor<T> &src, const PoolingLayerInfo &info); +SimpleTensor<T> pooling_layer_internal(const SimpleTensor<T> &src, const PoolingLayerInfo &info, SimpleTensor<uint32_t> *indices); template <typename T> -SimpleTensor<T> pooling_layer(const SimpleTensor<T> &src, const PoolingLayerInfo &info, const QuantizationInfo &output_qinfo); +SimpleTensor<T> pooling_layer(const SimpleTensor<T> &src, const PoolingLayerInfo &info, const QuantizationInfo &output_qinfo, SimpleTensor<uint32_t> *indices); } // namespace reference } // namespace validation } // namespace test |