From 02bf80d4554cfc824a76008905921cb564bee999 Mon Sep 17 00:00:00 2001 From: Daniil Efremov Date: Wed, 22 Nov 2017 00:26:51 +0700 Subject: COMPMID-661: Fix scale border issue (#38) Change-Id: If1dcca724e5e5f5ab363ffc16b0ef8c943e0b657 Reviewed-on: https://eu-gerrit-1.euhpc.arm.com/110105 Tested-by: BSG Visual Compute Jenkins server to access repositories on http://mpd-gerrit.cambridge.arm.com Reviewed-by: Gian Marco Iodice Reviewed-by: Anthony Barbier --- arm_compute/core/CL/kernels/CLScaleKernel.h | 3 +- arm_compute/core/NEON/kernels/NEScaleKernel.h | 4 +- arm_compute/core/Types.h | 41 +++++++++------ arm_compute/runtime/CL/functions/CLScale.h | 4 +- arm_compute/runtime/NEON/functions/NEScale.h | 4 +- src/core/CL/cl_kernels/scale.cl | 16 +++++- src/core/CL/kernels/CLScaleKernel.cpp | 3 +- src/core/NEON/kernels/NEScaleKernel.cpp | 5 +- src/runtime/CL/functions/CLGaussianPyramid.cpp | 2 +- src/runtime/CL/functions/CLScale.cpp | 4 +- src/runtime/NEON/functions/NEScale.cpp | 14 ++--- tests/datasets/SamplingPolicyDataset.h | 50 ++++++++++++++++++ tests/validation/CL/Scale.cpp | 71 +++++++++++++++----------- tests/validation/CPP/GaussianPyramidHalf.cpp | 3 +- tests/validation/CPP/Scale.cpp | 32 +++++++++--- tests/validation/CPP/Scale.h | 3 +- tests/validation/NEON/Scale.cpp | 60 ++++++++++++---------- tests/validation/fixtures/ScaleFixture.h | 24 +++++---- utils/TypePrinter.h | 25 +++++++++ 19 files changed, 258 insertions(+), 110 deletions(-) create mode 100644 tests/datasets/SamplingPolicyDataset.h diff --git a/arm_compute/core/CL/kernels/CLScaleKernel.h b/arm_compute/core/CL/kernels/CLScaleKernel.h index db0587d6ac..3bca6efd0a 100644 --- a/arm_compute/core/CL/kernels/CLScaleKernel.h +++ b/arm_compute/core/CL/kernels/CLScaleKernel.h @@ -42,8 +42,9 @@ public: * All but the lowest two dimensions must be the same size as in the input tensor, i.e. scaling is only performed within the XY-plane. * @param[in] policy Interpolation type to use * @param[in] border_undefined True if the border mode is undefined. False if it's replicate or constant. + * @param[in] sampling_policy (Optional) Sampling policy used by the interpolation. Defaults to @ref SamplingPolicy::CENTER */ - void configure(const ICLTensor *input, ICLTensor *output, InterpolationPolicy policy, bool border_undefined); + void configure(const ICLTensor *input, ICLTensor *output, InterpolationPolicy policy, bool border_undefined, SamplingPolicy sampling_policy = SamplingPolicy::CENTER); // Inherited methods overridden: BorderSize border_size() const override; diff --git a/arm_compute/core/NEON/kernels/NEScaleKernel.h b/arm_compute/core/NEON/kernels/NEScaleKernel.h index 5ec5854841..ac154d4455 100644 --- a/arm_compute/core/NEON/kernels/NEScaleKernel.h +++ b/arm_compute/core/NEON/kernels/NEScaleKernel.h @@ -59,8 +59,10 @@ public: * @param[out] output Destination tensor. Data types supported: Same as @p input. All but the lowest two dimensions must be the same size as in the input tensor, i.e. scaling is only performed within the XY-plane. * @param[in] policy Interpolation type to use * @param[in] border_undefined True if the border mode is undefined. False if it's replicate or constant. + * @param[in] sampling_policy (Optional) Sampling policy used by the interpolation. Defaults to @ref SamplingPolicy::CENTER */ - void configure(const ITensor *input, const ITensor *dx, const ITensor *dy, const ITensor *offsets, ITensor *output, InterpolationPolicy policy, bool border_undefined); + void configure(const ITensor *input, const ITensor *dx, const ITensor *dy, const ITensor *offsets, ITensor *output, InterpolationPolicy policy, bool border_undefined, + SamplingPolicy sampling_policy = SamplingPolicy::CENTER); // Inherited methods overridden: void run(const Window &window, const ThreadInfo &info) override; diff --git a/arm_compute/core/Types.h b/arm_compute/core/Types.h index 37f8508674..4ecaec1eb9 100644 --- a/arm_compute/core/Types.h +++ b/arm_compute/core/Types.h @@ -41,23 +41,23 @@ using half = half_float::half; /** Image colour formats */ enum class Format { - UNKNOWN, /** Unknown image format */ - U8, /** 1 channel, 1 U8 per channel */ - S16, /** 1 channel, 1 S16 per channel */ - U16, /** 1 channel, 1 U16 per channel */ - S32, /** 1 channel, 1 S32 per channel */ - U32, /** 1 channel, 1 U32 per channel */ - F16, /** 1 channel, 1 F16 per channel */ - F32, /** 1 channel, 1 F32 per channel */ - UV88, /** 2 channel, 1 U8 per channel */ - RGB888, /** 3 channels, 1 U8 per channel */ - RGBA8888, /** 4 channels, 1 U8 per channel */ - YUV444, /** A 3 plane of 8 bit 4:4:4 sampled Y, U, V planes */ - YUYV422, /** A single plane of 32-bit macro pixel of Y0, U0, Y1, V0 bytes */ - NV12, /** A 2 plane YUV format of Luma (Y) and interleaved UV data at 4:2:0 sampling */ - NV21, /** A 2 plane YUV format of Luma (Y) and interleaved VU data at 4:2:0 sampling */ - IYUV, /** A 3 plane of 8-bit 4:2:0 sampled Y, U, V planes */ - UYVY422 /** A single plane of 32-bit macro pixel of U0, Y0, V0, Y1 byte */ + UNKNOWN, /**< Unknown image format */ + U8, /**< 1 channel, 1 U8 per channel */ + S16, /**< 1 channel, 1 S16 per channel */ + U16, /**< 1 channel, 1 U16 per channel */ + S32, /**< 1 channel, 1 S32 per channel */ + U32, /**< 1 channel, 1 U32 per channel */ + F16, /**< 1 channel, 1 F16 per channel */ + F32, /**< 1 channel, 1 F32 per channel */ + UV88, /**< 2 channel, 1 U8 per channel */ + RGB888, /**< 3 channels, 1 U8 per channel */ + RGBA8888, /**< 4 channels, 1 U8 per channel */ + YUV444, /**< A 3 plane of 8 bit 4:4:4 sampled Y, U, V planes */ + YUYV422, /**< A single plane of 32-bit macro pixel of Y0, U0, Y1, V0 bytes */ + NV12, /**< A 2 plane YUV format of Luma (Y) and interleaved UV data at 4:2:0 sampling */ + NV21, /**< A 2 plane YUV format of Luma (Y) and interleaved VU data at 4:2:0 sampling */ + IYUV, /**< A 3 plane of 8-bit 4:2:0 sampled Y, U, V planes */ + UYVY422 /**< A single plane of 32-bit macro pixel of U0, Y0, V0, Y1 byte */ }; /** Available data types */ @@ -82,6 +82,13 @@ enum class DataType SIZET }; +/** Available Sampling Policies */ +enum class SamplingPolicy +{ + CENTER, /**< Samples are taken at pixel center */ + TOP_LEFT /**< Samples are taken at pixel top left corner */ +}; + /** Constant value of the border pixels when using BorderMode::CONSTANT */ constexpr uint8_t CONSTANT_BORDER_VALUE = 199; diff --git a/arm_compute/runtime/CL/functions/CLScale.h b/arm_compute/runtime/CL/functions/CLScale.h index db491c1a44..68d64a9e21 100644 --- a/arm_compute/runtime/CL/functions/CLScale.h +++ b/arm_compute/runtime/CL/functions/CLScale.h @@ -45,8 +45,10 @@ public: * @param[in] policy The interpolation type. * @param[in] border_mode Strategy to use for borders. * @param[in] constant_border_value (Optional) Constant value to use for borders if border_mode is set to CONSTANT. + * @param[in] sampling_policy (Optional) Sampling policy used by the interpolation. Defaults to @ref SamplingPolicy::CENTER */ - void configure(ICLTensor *input, ICLTensor *output, InterpolationPolicy policy, BorderMode border_mode, PixelValue constant_border_value = PixelValue()); + void configure(ICLTensor *input, ICLTensor *output, InterpolationPolicy policy, BorderMode border_mode, PixelValue constant_border_value = PixelValue(), + SamplingPolicy sampling_policy = SamplingPolicy::CENTER); }; } #endif /*__ARM_COMPUTE_CLSCALE_H__ */ diff --git a/arm_compute/runtime/NEON/functions/NEScale.h b/arm_compute/runtime/NEON/functions/NEScale.h index 7297880a7a..1d96db3ffc 100644 --- a/arm_compute/runtime/NEON/functions/NEScale.h +++ b/arm_compute/runtime/NEON/functions/NEScale.h @@ -52,8 +52,10 @@ public: * @param[in] policy The interpolation type. * @param[in] border_mode Strategy to use for borders. * @param[in] constant_border_value (Optional) Constant value to use for borders if border_mode is set to CONSTANT. + * @param[in] sampling_policy (Optional) Sampling policy used by the interpolation. Defaults to @ref SamplingPolicy::CENTER */ - void configure(ITensor *input, ITensor *output, InterpolationPolicy policy, BorderMode border_mode, PixelValue constant_border_value = PixelValue()); + void configure(ITensor *input, ITensor *output, InterpolationPolicy policy, BorderMode border_mode, PixelValue constant_border_value = PixelValue(), + SamplingPolicy sampling_policy = SamplingPolicy::CENTER); // Inherited methods overridden: void run() override; diff --git a/src/core/CL/cl_kernels/scale.cl b/src/core/CL/cl_kernels/scale.cl index d533d970c7..a2ae8c4dd6 100644 --- a/src/core/CL/cl_kernels/scale.cl +++ b/src/core/CL/cl_kernels/scale.cl @@ -49,12 +49,22 @@ inline const float8 transform_nearest(const float2 coord, const float2 scale) inline const float8 transform_bilinear(const float2 coord, const float2 scale) { const float4 in_x_coords = (float4)(coord.s0, 1 + coord.s0, 2 + coord.s0, 3 + coord.s0); - const float4 new_x = (in_x_coords + ((float4)(0.5f))) * (float4)(scale.s0) - (float4)(0.5f); - const float4 new_y = (float4)((coord.s1 + 0.5f) * scale.s1 - 0.5f); +#ifdef SAMPLING_POLICY_TOP_LEFT + const float4 new_x = in_x_coords * (float4)(scale.s0); + const float4 new_y = (float4)(coord.s1 * scale.s1); return (float8)(new_x.s0, new_y.s0, new_x.s1, new_y.s1, new_x.s2, new_y.s2, new_x.s3, new_y.s3); +#elif SAMPLING_POLICY_CENTER + const float4 new_x = (in_x_coords + ((float4)(0.5f))) * (float4)(scale.s0) - (float4)(0.5f); + const float4 new_y = (float4)((coord.s1 + 0.5f) * scale.s1 - 0.5f); + return (float8)(new_x.s0, new_y.s0, new_x.s1, new_y.s1, new_x.s2, new_y.s2, new_x.s3, new_y.s3); +#else /* SAMPLING_POLICY */ +#error("Unsupported sampling policy"); +#endif /* SAMPLING_POLICY */ } /** Performs an affine transformation on an image interpolating with the NEAREAST NEIGHBOUR method. Input and output are single channel U8 or S16. + * + * @note Sampling policy to used is passed as -DSAMPLING_POLICY_(TYPE) e.g. -DSAMPLING_POLICY_TOP_LEFT * * @param[in] in_ptr Pointer to the source image. Supported data types: U8, S16. * @param[in] in_stride_x Stride of the source image in X dimension (in bytes) @@ -89,6 +99,8 @@ __kernel void scale_nearest_neighbour( } /** Performs an affine transformation on an image interpolating with the BILINEAR method. + * + * @note Sampling policy to used is passed as -DSAMPLING_POLICY_(TYPE) e.g. -DSAMPLING_POLICY_TOP_LEFT * * @param[in] in_ptr Pointer to the source image. Supported data types: U8, S16. * @param[in] in_stride_x Stride of the source image in X dimension (in bytes) diff --git a/src/core/CL/kernels/CLScaleKernel.cpp b/src/core/CL/kernels/CLScaleKernel.cpp index 6a5d24c943..673304a271 100644 --- a/src/core/CL/kernels/CLScaleKernel.cpp +++ b/src/core/CL/kernels/CLScaleKernel.cpp @@ -44,7 +44,7 @@ BorderSize CLScaleKernel::border_size() const return BorderSize(1); } -void CLScaleKernel::configure(const ICLTensor *input, ICLTensor *output, InterpolationPolicy policy, bool border_undefined) +void CLScaleKernel::configure(const ICLTensor *input, ICLTensor *output, InterpolationPolicy policy, bool border_undefined, SamplingPolicy sampling_policy) { ARM_COMPUTE_ERROR_ON_DATA_TYPE_CHANNEL_NOT_IN(input, 1, DataType::U8, DataType::S16, DataType::F16, DataType::F32); ARM_COMPUTE_ERROR_ON_NULLPTR(output); @@ -75,6 +75,7 @@ void CLScaleKernel::configure(const ICLTensor *input, ICLTensor *output, Interpo CLBuildOptions build_opts; build_opts.add_option("-DDATA_TYPE=" + get_cl_type_from_data_type(input->info()->data_type())); build_opts.add_option("-DBORDER_SIZE=" + support::cpp11::to_string(border.right)); + build_opts.add_option_if_else(sampling_policy == SamplingPolicy::CENTER, "-DSAMPLING_POLICY_CENTER", "-DSAMPLING_POLICY_TOP_LEFT"); std::string interpolation_name = string_from_interpolation_policy(policy); std::transform(interpolation_name.begin(), interpolation_name.end(), interpolation_name.begin(), ::tolower); diff --git a/src/core/NEON/kernels/NEScaleKernel.cpp b/src/core/NEON/kernels/NEScaleKernel.cpp index b1ced7e38d..1918a77300 100644 --- a/src/core/NEON/kernels/NEScaleKernel.cpp +++ b/src/core/NEON/kernels/NEScaleKernel.cpp @@ -48,12 +48,15 @@ BorderSize NEScaleKernel::border_size() const return BorderSize(1); } -void NEScaleKernel::configure(const ITensor *input, const ITensor *dx, const ITensor *dy, const ITensor *offsets, ITensor *output, InterpolationPolicy policy, bool border_undefined) +void NEScaleKernel::configure(const ITensor *input, const ITensor *dx, const ITensor *dy, const ITensor *offsets, ITensor *output, InterpolationPolicy policy, bool border_undefined, + SamplingPolicy sampling_policy) { ARM_COMPUTE_ERROR_ON_DATA_TYPE_CHANNEL_NOT_IN(input, 1, DataType::U8, DataType::S16, DataType::F32); ARM_COMPUTE_ERROR_ON_NULLPTR(output); ARM_COMPUTE_ERROR_ON_MISMATCHING_DATA_TYPES(input, output); ARM_COMPUTE_ERROR_ON(output == input); + ARM_COMPUTE_ERROR_ON(sampling_policy != SamplingPolicy::CENTER); + ARM_COMPUTE_UNUSED(sampling_policy); if(policy == InterpolationPolicy::NEAREST_NEIGHBOR) { diff --git a/src/runtime/CL/functions/CLGaussianPyramid.cpp b/src/runtime/CL/functions/CLGaussianPyramid.cpp index 8436dce87b..4b32954d91 100644 --- a/src/runtime/CL/functions/CLGaussianPyramid.cpp +++ b/src/runtime/CL/functions/CLGaussianPyramid.cpp @@ -157,7 +157,7 @@ void CLGaussianPyramidOrb::configure(ICLTensor *input, CLPyramid *pyramid, Borde _gauss5x5[i].configure(_pyramid->get_pyramid_level(i), _tmp.get_pyramid_level(i), border_mode, constant_border_value); /* Configure scale image kernel */ - _scale_nearest[i].configure(_tmp.get_pyramid_level(i), _pyramid->get_pyramid_level(i + 1), InterpolationPolicy::NEAREST_NEIGHBOR, border_mode == BorderMode::UNDEFINED); + _scale_nearest[i].configure(_tmp.get_pyramid_level(i), _pyramid->get_pyramid_level(i + 1), InterpolationPolicy::NEAREST_NEIGHBOR, border_mode == BorderMode::UNDEFINED, SamplingPolicy::CENTER); } _tmp.allocate(); diff --git a/src/runtime/CL/functions/CLScale.cpp b/src/runtime/CL/functions/CLScale.cpp index 49b0275019..cb68481787 100644 --- a/src/runtime/CL/functions/CLScale.cpp +++ b/src/runtime/CL/functions/CLScale.cpp @@ -31,10 +31,10 @@ using namespace arm_compute; -void CLScale::configure(ICLTensor *input, ICLTensor *output, InterpolationPolicy policy, BorderMode border_mode, PixelValue constant_border_value) +void CLScale::configure(ICLTensor *input, ICLTensor *output, InterpolationPolicy policy, BorderMode border_mode, PixelValue constant_border_value, SamplingPolicy sampling_policy) { auto k = arm_compute::support::cpp14::make_unique(); - k->configure(input, output, policy, border_mode == BorderMode::UNDEFINED); + k->configure(input, output, policy, border_mode == BorderMode::UNDEFINED, sampling_policy); _kernel = std::move(k); _border_handler.configure(input, _kernel->border_size(), border_mode, constant_border_value); } diff --git a/src/runtime/NEON/functions/NEScale.cpp b/src/runtime/NEON/functions/NEScale.cpp index bbd3fac63f..bd565c92ff 100644 --- a/src/runtime/NEON/functions/NEScale.cpp +++ b/src/runtime/NEON/functions/NEScale.cpp @@ -42,9 +42,11 @@ using namespace arm_compute; namespace { -void precompute_dx_dy_offsets(ITensor *dx, ITensor *dy, ITensor *offsets, float wr, float hr, size_t input_element_size) +void precompute_dx_dy_offsets(ITensor *dx, ITensor *dy, ITensor *offsets, float wr, float hr, size_t input_element_size, SamplingPolicy sampling_policy) { ARM_COMPUTE_ERROR_ON(nullptr == offsets); + ARM_COMPUTE_ERROR_ON(sampling_policy != SamplingPolicy::CENTER); + ARM_COMPUTE_UNUSED(sampling_policy); Window win; win.set(Window::DimX, Window::Dimension(0, offsets->info()->dimension(0), 1)); @@ -95,7 +97,7 @@ NEScale::NEScale() // NOLINT { } -void NEScale::configure(ITensor *input, ITensor *output, InterpolationPolicy policy, BorderMode border_mode, PixelValue constant_border_value) +void NEScale::configure(ITensor *input, ITensor *output, InterpolationPolicy policy, BorderMode border_mode, PixelValue constant_border_value, SamplingPolicy sampling_policy) { ARM_COMPUTE_ERROR_ON(nullptr == input); ARM_COMPUTE_ERROR_ON(nullptr == output); @@ -131,13 +133,13 @@ void NEScale::configure(ITensor *input, ITensor *output, InterpolationPolicy pol TensorInfo tensor_info_offsets(shape, Format::S32); _offsets.allocator()->init(tensor_info_offsets); - _scale_kernel.configure(input, nullptr, nullptr, &_offsets, output, policy, border_undefined); + _scale_kernel.configure(input, nullptr, nullptr, &_offsets, output, policy, border_undefined, sampling_policy); // Allocate once the configure methods have been called _offsets.allocator()->allocate(); // Pre-compute offsets for nearest interpolation - precompute_dx_dy_offsets(nullptr, nullptr, &_offsets, wr, hr, input_element_size); + precompute_dx_dy_offsets(nullptr, nullptr, &_offsets, wr, hr, input_element_size, sampling_policy); break; } case InterpolationPolicy::BILINEAR: @@ -149,7 +151,7 @@ void NEScale::configure(ITensor *input, ITensor *output, InterpolationPolicy pol _dx.allocator()->init(tensor_info_dxdy); _dy.allocator()->init(tensor_info_dxdy); - _scale_kernel.configure(input, &_dx, &_dy, &_offsets, output, policy, border_undefined); + _scale_kernel.configure(input, &_dx, &_dy, &_offsets, output, policy, border_undefined, sampling_policy); // Allocate once the configure methods have been called _offsets.allocator()->allocate(); @@ -157,7 +159,7 @@ void NEScale::configure(ITensor *input, ITensor *output, InterpolationPolicy pol _dy.allocator()->allocate(); // Pre-compute dx, dy and offsets for bilinear interpolation - precompute_dx_dy_offsets(&_dx, &_dy, &_offsets, wr, hr, input_element_size); + precompute_dx_dy_offsets(&_dx, &_dy, &_offsets, wr, hr, input_element_size, sampling_policy); break; } case InterpolationPolicy::AREA: diff --git a/tests/datasets/SamplingPolicyDataset.h b/tests/datasets/SamplingPolicyDataset.h new file mode 100644 index 0000000000..067bcd32a9 --- /dev/null +++ b/tests/datasets/SamplingPolicyDataset.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2017 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_SAMPLING_POLICY_DATASET_H__ +#define __ARM_COMPUTE_TEST_SAMPLING_POLICY_DATASET_H__ + +#include "arm_compute/core/Types.h" + +namespace arm_compute +{ +namespace test +{ +namespace datasets +{ +class SamplingPolicies final : public framework::dataset::ContainerDataset> +{ +public: + SamplingPolicies() + : ContainerDataset("SamplingPolicy", + { + SamplingPolicy::CENTER, + SamplingPolicy::TOP_LEFT + }) + { + } +}; +} // namespace datasets +} // namespace test +} // namespace arm_compute +#endif /* __ARM_COMPUTE_TEST_SAMPLING_POLICY_DATASET_H__ */ diff --git a/tests/validation/CL/Scale.cpp b/tests/validation/CL/Scale.cpp index 1ddf03a74c..aeda33b7c6 100644 --- a/tests/validation/CL/Scale.cpp +++ b/tests/validation/CL/Scale.cpp @@ -29,6 +29,7 @@ #include "tests/CL/CLAccessor.h" #include "tests/PaddingCalculator.h" #include "tests/datasets/BorderModeDataset.h" +#include "tests/datasets/SamplingPolicyDataset.h" #include "tests/datasets/ShapeDatasets.h" #include "tests/framework/Asserts.h" #include "tests/framework/Macros.h" @@ -66,10 +67,11 @@ constexpr float tolerance_num_f32(0.01f); TEST_SUITE(CL) TEST_SUITE(Scale) -DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(combine(combine(concat(datasets::MediumShapes(), datasets::LargeShapes()), ScaleDataTypes), - framework::dataset::make("InterpolationPolicy", { InterpolationPolicy::NEAREST_NEIGHBOR, InterpolationPolicy::BILINEAR })), - datasets::BorderModes()), - shape, data_type, policy, border_mode) +DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(combine(combine(combine(concat(datasets::MediumShapes(), datasets::LargeShapes()), ScaleDataTypes), + framework::dataset::make("InterpolationPolicy", { InterpolationPolicy::NEAREST_NEIGHBOR, InterpolationPolicy::BILINEAR })), + datasets::BorderModes()), + datasets::SamplingPolicies()), + shape, data_type, policy, border_mode, sampling_policy) { std::mt19937 generator(library->seed()); std::uniform_real_distribution distribution_float(0.25, 2); @@ -90,7 +92,7 @@ DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(combine(combi // Create and configure function CLScale clscale; - clscale.configure(&src, &dst, policy, border_mode, constant_border_value); + clscale.configure(&src, &dst, policy, border_mode, constant_border_value, sampling_policy); // Get border size depending on border mode const BorderSize border_size(border_mode == BorderMode::UNDEFINED ? 0 : 1); @@ -114,9 +116,10 @@ using CLScaleFixture = ScaleValidationFixture; TEST_SUITE(Float) TEST_SUITE(FP32) -FIXTURE_DATA_TEST_CASE(RunSmall, CLScaleFixture, framework::DatasetMode::ALL, combine(combine(combine(datasets::SmallShapes(), framework::dataset::make("DataType", DataType::F32)), - framework::dataset::make("InterpolationPolicy", { InterpolationPolicy::NEAREST_NEIGHBOR, InterpolationPolicy::BILINEAR })), - datasets::BorderModes())) +FIXTURE_DATA_TEST_CASE(RunSmall, CLScaleFixture, framework::DatasetMode::ALL, combine(combine(combine(combine(datasets::SmallShapes(), framework::dataset::make("DataType", DataType::F32)), + framework::dataset::make("InterpolationPolicy", { InterpolationPolicy::NEAREST_NEIGHBOR, InterpolationPolicy::BILINEAR })), + datasets::BorderModes()), + datasets::SamplingPolicies())) { //Create valid region TensorInfo src_info(_shape, 1, _data_type); @@ -125,9 +128,10 @@ FIXTURE_DATA_TEST_CASE(RunSmall, CLScaleFixture, framework::DatasetMode:: // Validate output validate(CLAccessor(_target), _reference, valid_region, tolerance_f32, tolerance_num_f32); } -FIXTURE_DATA_TEST_CASE(RunLarge, CLScaleFixture, framework::DatasetMode::NIGHTLY, combine(combine(combine(datasets::LargeShapes(), framework::dataset::make("DataType", DataType::F32)), - framework::dataset::make("InterpolationPolicy", { InterpolationPolicy::NEAREST_NEIGHBOR, InterpolationPolicy::BILINEAR })), - datasets::BorderModes())) +FIXTURE_DATA_TEST_CASE(RunLarge, CLScaleFixture, framework::DatasetMode::NIGHTLY, combine(combine(combine(combine(datasets::LargeShapes(), framework::dataset::make("DataType", DataType::F32)), + framework::dataset::make("InterpolationPolicy", { InterpolationPolicy::NEAREST_NEIGHBOR, InterpolationPolicy::BILINEAR })), + datasets::BorderModes()), + datasets::SamplingPolicies())) { //Create valid region TensorInfo src_info(_shape, 1, _data_type); @@ -138,9 +142,10 @@ FIXTURE_DATA_TEST_CASE(RunLarge, CLScaleFixture, framework::DatasetMode:: } TEST_SUITE_END() TEST_SUITE(FP16) -FIXTURE_DATA_TEST_CASE(RunSmall, CLScaleFixture, framework::DatasetMode::ALL, combine(combine(combine(datasets::SmallShapes(), framework::dataset::make("DataType", DataType::F16)), - framework::dataset::make("InterpolationPolicy", { InterpolationPolicy::NEAREST_NEIGHBOR, InterpolationPolicy::BILINEAR })), - datasets::BorderModes())) +FIXTURE_DATA_TEST_CASE(RunSmall, CLScaleFixture, framework::DatasetMode::ALL, combine(combine(combine(combine(datasets::SmallShapes(), framework::dataset::make("DataType", DataType::F16)), + framework::dataset::make("InterpolationPolicy", { InterpolationPolicy::NEAREST_NEIGHBOR, InterpolationPolicy::BILINEAR })), + datasets::BorderModes()), + datasets::SamplingPolicies())) { //Create valid region TensorInfo src_info(_shape, 1, _data_type); @@ -149,10 +154,11 @@ FIXTURE_DATA_TEST_CASE(RunSmall, CLScaleFixture, framework::DatasetMode::A // Validate output validate(CLAccessor(_target), _reference, valid_region, tolerance_f16); } -FIXTURE_DATA_TEST_CASE(RunLarge, CLScaleFixture, framework::DatasetMode::NIGHTLY, combine(combine(combine(datasets::LargeShapes(), framework::dataset::make("DataType", - DataType::F16)), - framework::dataset::make("InterpolationPolicy", { InterpolationPolicy::NEAREST_NEIGHBOR, InterpolationPolicy::BILINEAR })), - datasets::BorderModes())) +FIXTURE_DATA_TEST_CASE(RunLarge, CLScaleFixture, framework::DatasetMode::NIGHTLY, combine(combine(combine(combine(datasets::LargeShapes(), framework::dataset::make("DataType", + DataType::F16)), + framework::dataset::make("InterpolationPolicy", { InterpolationPolicy::NEAREST_NEIGHBOR, InterpolationPolicy::BILINEAR })), + datasets::BorderModes()), + datasets::SamplingPolicies())) { //Create valid region TensorInfo src_info(_shape, 1, _data_type); @@ -166,9 +172,10 @@ TEST_SUITE_END() TEST_SUITE(Integer) TEST_SUITE(U8) -FIXTURE_DATA_TEST_CASE(RunSmall, CLScaleFixture, framework::DatasetMode::ALL, combine(combine(combine(datasets::SmallShapes(), framework::dataset::make("DataType", DataType::U8)), - framework::dataset::make("InterpolationPolicy", { InterpolationPolicy::NEAREST_NEIGHBOR, InterpolationPolicy::BILINEAR })), - datasets::BorderModes())) +FIXTURE_DATA_TEST_CASE(RunSmall, CLScaleFixture, framework::DatasetMode::ALL, combine(combine(combine(combine(datasets::SmallShapes(), framework::dataset::make("DataType", DataType::U8)), + framework::dataset::make("InterpolationPolicy", { InterpolationPolicy::NEAREST_NEIGHBOR, InterpolationPolicy::BILINEAR })), + datasets::BorderModes()), + datasets::SamplingPolicies())) { //Create valid region TensorInfo src_info(_shape, 1, _data_type); @@ -177,9 +184,10 @@ FIXTURE_DATA_TEST_CASE(RunSmall, CLScaleFixture, framework::DatasetMode // Validate output validate(CLAccessor(_target), _reference, valid_region, tolerance_u8); } -FIXTURE_DATA_TEST_CASE(RunLarge, CLScaleFixture, framework::DatasetMode::NIGHTLY, combine(combine(combine(datasets::LargeShapes(), framework::dataset::make("DataType", DataType::U8)), - framework::dataset::make("InterpolationPolicy", { InterpolationPolicy::NEAREST_NEIGHBOR, InterpolationPolicy::BILINEAR })), - datasets::BorderModes())) +FIXTURE_DATA_TEST_CASE(RunLarge, CLScaleFixture, framework::DatasetMode::NIGHTLY, combine(combine(combine(combine(datasets::LargeShapes(), framework::dataset::make("DataType", DataType::U8)), + framework::dataset::make("InterpolationPolicy", { InterpolationPolicy::NEAREST_NEIGHBOR, InterpolationPolicy::BILINEAR })), + datasets::BorderModes()), + datasets::SamplingPolicies())) { //Create valid region TensorInfo src_info(_shape, 1, _data_type); @@ -190,9 +198,10 @@ FIXTURE_DATA_TEST_CASE(RunLarge, CLScaleFixture, framework::DatasetMode } TEST_SUITE_END() TEST_SUITE(S16) -FIXTURE_DATA_TEST_CASE(RunSmall, CLScaleFixture, framework::DatasetMode::ALL, combine(combine(combine(datasets::SmallShapes(), framework::dataset::make("DataType", DataType::S16)), - framework::dataset::make("InterpolationPolicy", { InterpolationPolicy::NEAREST_NEIGHBOR, InterpolationPolicy::BILINEAR })), - datasets::BorderModes())) +FIXTURE_DATA_TEST_CASE(RunSmall, CLScaleFixture, framework::DatasetMode::ALL, combine(combine(combine(combine(datasets::SmallShapes(), framework::dataset::make("DataType", DataType::S16)), + framework::dataset::make("InterpolationPolicy", { InterpolationPolicy::NEAREST_NEIGHBOR, InterpolationPolicy::BILINEAR })), + datasets::BorderModes()), + datasets::SamplingPolicies())) { //Create valid region TensorInfo src_info(_shape, 1, _data_type); @@ -201,9 +210,11 @@ FIXTURE_DATA_TEST_CASE(RunSmall, CLScaleFixture, framework::DatasetMode // Validate output validate(CLAccessor(_target), _reference, valid_region, tolerance_s16); } -FIXTURE_DATA_TEST_CASE(RunLarge, CLScaleFixture, framework::DatasetMode::NIGHTLY, combine(combine(combine(datasets::LargeShapes(), framework::dataset::make("DataType", DataType::S16)), - framework::dataset::make("InterpolationPolicy", { InterpolationPolicy::NEAREST_NEIGHBOR, InterpolationPolicy::BILINEAR })), - datasets::BorderModes())) +FIXTURE_DATA_TEST_CASE(RunLarge, CLScaleFixture, framework::DatasetMode::NIGHTLY, combine(combine(combine(combine(datasets::LargeShapes(), framework::dataset::make("DataType", + DataType::S16)), + framework::dataset::make("InterpolationPolicy", { InterpolationPolicy::NEAREST_NEIGHBOR, InterpolationPolicy::BILINEAR })), + datasets::BorderModes()), + datasets::SamplingPolicies())) { //Create valid region TensorInfo src_info(_shape, 1, _data_type); diff --git a/tests/validation/CPP/GaussianPyramidHalf.cpp b/tests/validation/CPP/GaussianPyramidHalf.cpp index 18d3daa288..0a68dedaee 100644 --- a/tests/validation/CPP/GaussianPyramidHalf.cpp +++ b/tests/validation/CPP/GaussianPyramidHalf.cpp @@ -51,7 +51,8 @@ std::vector> gaussian_pyramid_half(const SimpleTensor &src, B const SimpleTensor out_gaus5x5 = reference::gaussian5x5(dst[i - 1], border_mode, constant_border_value); // Scale down by 2 with nearest interpolation - const SimpleTensor out = reference::scale(out_gaus5x5, SCALE_PYRAMID_HALF, SCALE_PYRAMID_HALF, InterpolationPolicy::NEAREST_NEIGHBOR, border_mode, constant_border_value, true); + const SimpleTensor out = reference::scale(out_gaus5x5, SCALE_PYRAMID_HALF, SCALE_PYRAMID_HALF, InterpolationPolicy::NEAREST_NEIGHBOR, border_mode, constant_border_value, SamplingPolicy::CENTER, + true); dst.push_back(out); } diff --git a/tests/validation/CPP/Scale.cpp b/tests/validation/CPP/Scale.cpp index c368fa277a..727325f675 100644 --- a/tests/validation/CPP/Scale.cpp +++ b/tests/validation/CPP/Scale.cpp @@ -26,6 +26,7 @@ #include "Scale.h" #include "Utils.h" +#include "support/ToolchainSupport.h" namespace arm_compute { @@ -36,7 +37,8 @@ namespace validation namespace reference { template -SimpleTensor scale(const SimpleTensor &in, float scale_x, float scale_y, InterpolationPolicy policy, BorderMode border_mode, T constant_border_value, bool ceil_policy_scale) +SimpleTensor scale(const SimpleTensor &in, float scale_x, float scale_y, InterpolationPolicy policy, BorderMode border_mode, T constant_border_value, + SamplingPolicy sampling_policy, bool ceil_policy_scale) { // Add 1 if ceil_policy_scale is true const size_t round_value = ceil_policy_scale ? 1U : 0U; @@ -66,8 +68,23 @@ SimpleTensor scale(const SimpleTensor &in, float scale_x, float scale_y, I Coordinates id = index2coord(out.shape(), element_idx); int idx = id.x(); int idy = id.y(); - float x_src = (idx + 0.5f) * wr - 0.5f; - float y_src = (idy + 0.5f) * hr - 0.5f; + float x_src = 0; + float y_src = 0; + + switch(sampling_policy) + { + case SamplingPolicy::TOP_LEFT: + x_src = idx * wr; + y_src = idy * hr; + break; + case SamplingPolicy::CENTER: + x_src = (idx + 0.5f) * wr - 0.5f; + y_src = (idy + 0.5f) * hr - 0.5f; + break; + default: + ARM_COMPUTE_ERROR("Unsupported sampling policy."); + break; + } switch(policy) { @@ -152,12 +169,13 @@ SimpleTensor scale(const SimpleTensor &in, float scale_x, float scale_y, I } template SimpleTensor scale(const SimpleTensor &src, float scale_x, float scale_y, InterpolationPolicy policy, BorderMode border_mode, uint8_t constant_border_value, - bool ceil_policy_scale); + SamplingPolicy sampling_policy, bool ceil_policy_scale); template SimpleTensor scale(const SimpleTensor &src, float scale_x, float scale_y, InterpolationPolicy policy, BorderMode border_mode, int16_t constant_border_value, - bool ceil_policy_scale); -template SimpleTensor scale(const SimpleTensor &src, float scale_x, float scale_y, InterpolationPolicy policy, BorderMode border_mode, half constant_border_value, bool ceil_policy_scale); + SamplingPolicy sampling_policy, bool ceil_policy_scale); +template SimpleTensor scale(const SimpleTensor &src, float scale_x, float scale_y, InterpolationPolicy policy, BorderMode border_mode, half constant_border_value, + SamplingPolicy sampling_policy, bool ceil_policy_scale); template SimpleTensor scale(const SimpleTensor &src, float scale_x, float scale_y, InterpolationPolicy policy, BorderMode border_mode, float constant_border_value, - bool ceil_policy_scale); + SamplingPolicy sampling_policy, bool ceil_policy_scale); } // namespace reference } // namespace validation } // namespace test diff --git a/tests/validation/CPP/Scale.h b/tests/validation/CPP/Scale.h index 87af2fd204..566e30af10 100644 --- a/tests/validation/CPP/Scale.h +++ b/tests/validation/CPP/Scale.h @@ -35,7 +35,8 @@ namespace validation namespace reference { template -SimpleTensor scale(const SimpleTensor &in, float scale_x, float scale_y, InterpolationPolicy policy, BorderMode border_mode, T constant_border_value = 0, bool ceil_policy_scale = false); +SimpleTensor scale(const SimpleTensor &in, float scale_x, float scale_y, InterpolationPolicy policy, BorderMode border_mode, T constant_border_value = 0, + SamplingPolicy sampling_policy = SamplingPolicy::CENTER, bool ceil_policy_scale = false); } // namespace reference } // namespace validation } // namespace test diff --git a/tests/validation/NEON/Scale.cpp b/tests/validation/NEON/Scale.cpp index aa7dc67833..b92162ee38 100644 --- a/tests/validation/NEON/Scale.cpp +++ b/tests/validation/NEON/Scale.cpp @@ -30,6 +30,7 @@ #include "tests/PaddingCalculator.h" #include "tests/datasets/BorderModeDataset.h" #include "tests/datasets/InterpolationPolicyDataset.h" +#include "tests/datasets/SamplingPolicyDataset.h" #include "tests/datasets/ShapeDatasets.h" #include "tests/framework/Asserts.h" #include "tests/framework/Macros.h" @@ -66,10 +67,11 @@ constexpr float tolerance_num_f32 = 0.01f; TEST_SUITE(NEON) TEST_SUITE(Scale) -DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(combine(combine(concat(datasets::SmallShapes(), datasets::LargeShapes()), ScaleDataTypes), - framework::dataset::make("InterpolationPolicy", { InterpolationPolicy::NEAREST_NEIGHBOR, InterpolationPolicy::BILINEAR })), - datasets::BorderModes()), - shape, data_type, policy, border_mode) +DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(combine(combine(combine(concat(datasets::SmallShapes(), datasets::LargeShapes()), ScaleDataTypes), + framework::dataset::make("InterpolationPolicy", { InterpolationPolicy::NEAREST_NEIGHBOR, InterpolationPolicy::BILINEAR })), + datasets::BorderModes()), + framework::dataset::make("SamplingPolicy", { SamplingPolicy::CENTER })), + shape, data_type, policy, border_mode, sampling_policy) { std::mt19937 generator(library->seed()); std::uniform_real_distribution distribution_float(0.25, 2); @@ -94,7 +96,7 @@ DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(combine(combi // Create and configure function NEScale nescale; - nescale.configure(&src, &dst, policy, border_mode, constant_border_value); + nescale.configure(&src, &dst, policy, border_mode, constant_border_value, sampling_policy); // Validate valid region const ValidRegion dst_valid_region = calculate_valid_region_scale(*(src.info()), shape_scaled, policy, BorderSize(1), (border_mode == BorderMode::UNDEFINED)); @@ -116,10 +118,11 @@ using NEScaleFixture = ScaleValidationFixture; TEST_SUITE(Float) TEST_SUITE(FP32) -FIXTURE_DATA_TEST_CASE(RunSmall, NEScaleFixture, framework::DatasetMode::ALL, combine(combine(combine(datasets::SmallShapes(), framework::dataset::make("DataType", - DataType::F32)), - framework::dataset::make("InterpolationPolicy", { InterpolationPolicy::NEAREST_NEIGHBOR, InterpolationPolicy::BILINEAR })), - datasets::BorderModes())) +FIXTURE_DATA_TEST_CASE(RunSmall, NEScaleFixture, framework::DatasetMode::ALL, combine(combine(combine(combine(datasets::SmallShapes(), framework::dataset::make("DataType", + DataType::F32)), + framework::dataset::make("InterpolationPolicy", { InterpolationPolicy::NEAREST_NEIGHBOR, InterpolationPolicy::BILINEAR })), + datasets::BorderModes()), + framework::dataset::make("SamplingPolicy", { SamplingPolicy::CENTER }))) { //Create valid region TensorInfo src_info(_shape, 1, _data_type); @@ -128,10 +131,11 @@ FIXTURE_DATA_TEST_CASE(RunSmall, NEScaleFixture, framework::DatasetMode:: // Validate output validate(Accessor(_target), _reference, valid_region, tolerance_f32, tolerance_num_f32); } -FIXTURE_DATA_TEST_CASE(RunLarge, NEScaleFixture, framework::DatasetMode::NIGHTLY, combine(combine(combine(datasets::LargeShapes(), framework::dataset::make("DataType", +FIXTURE_DATA_TEST_CASE(RunLarge, NEScaleFixture, framework::DatasetMode::NIGHTLY, combine(combine(combine(combine(datasets::LargeShapes(), framework::dataset::make("DataType", DataType::F32)), - framework::dataset::make("InterpolationPolicy", { InterpolationPolicy::NEAREST_NEIGHBOR, InterpolationPolicy::BILINEAR })), - datasets::BorderModes())) + framework::dataset::make("InterpolationPolicy", { InterpolationPolicy::NEAREST_NEIGHBOR, InterpolationPolicy::BILINEAR })), + datasets::BorderModes()), + framework::dataset::make("SamplingPolicy", { SamplingPolicy::CENTER }))) { //Create valid region TensorInfo src_info(_shape, 1, _data_type); @@ -145,10 +149,11 @@ TEST_SUITE_END() TEST_SUITE(Integer) TEST_SUITE(U8) -FIXTURE_DATA_TEST_CASE(RunSmall, NEScaleFixture, framework::DatasetMode::ALL, combine(combine(combine(datasets::SmallShapes(), framework::dataset::make("DataType", - DataType::U8)), - framework::dataset::make("InterpolationPolicy", { InterpolationPolicy::NEAREST_NEIGHBOR, InterpolationPolicy::BILINEAR })), - datasets::BorderModes())) +FIXTURE_DATA_TEST_CASE(RunSmall, NEScaleFixture, framework::DatasetMode::ALL, combine(combine(combine(combine(datasets::SmallShapes(), framework::dataset::make("DataType", + DataType::U8)), + framework::dataset::make("InterpolationPolicy", { InterpolationPolicy::NEAREST_NEIGHBOR, InterpolationPolicy::BILINEAR })), + datasets::BorderModes()), + framework::dataset::make("SamplingPolicy", { SamplingPolicy::CENTER }))) { //Create valid region TensorInfo src_info(_shape, 1, _data_type); @@ -157,10 +162,11 @@ FIXTURE_DATA_TEST_CASE(RunSmall, NEScaleFixture, framework::DatasetMode // Validate output validate(Accessor(_target), _reference, valid_region, tolerance_u8); } -FIXTURE_DATA_TEST_CASE(RunLarge, NEScaleFixture, framework::DatasetMode::NIGHTLY, combine(combine(combine(datasets::LargeShapes(), framework::dataset::make("DataType", +FIXTURE_DATA_TEST_CASE(RunLarge, NEScaleFixture, framework::DatasetMode::NIGHTLY, combine(combine(combine(combine(datasets::LargeShapes(), framework::dataset::make("DataType", DataType::U8)), - framework::dataset::make("InterpolationPolicy", { InterpolationPolicy::NEAREST_NEIGHBOR, InterpolationPolicy::BILINEAR })), - datasets::BorderModes())) + framework::dataset::make("InterpolationPolicy", { InterpolationPolicy::NEAREST_NEIGHBOR, InterpolationPolicy::BILINEAR })), + datasets::BorderModes()), + framework::dataset::make("SamplingPolicy", { SamplingPolicy::CENTER }))) { //Create valid region TensorInfo src_info(_shape, 1, _data_type); @@ -171,10 +177,11 @@ FIXTURE_DATA_TEST_CASE(RunLarge, NEScaleFixture, framework::DatasetMode } TEST_SUITE_END() TEST_SUITE(S16) -FIXTURE_DATA_TEST_CASE(RunSmall, NEScaleFixture, framework::DatasetMode::ALL, combine(combine(combine(datasets::SmallShapes(), framework::dataset::make("DataType", - DataType::S16)), - framework::dataset::make("InterpolationPolicy", { InterpolationPolicy::NEAREST_NEIGHBOR, InterpolationPolicy::BILINEAR })), - datasets::BorderModes())) +FIXTURE_DATA_TEST_CASE(RunSmall, NEScaleFixture, framework::DatasetMode::ALL, combine(combine(combine(combine(datasets::SmallShapes(), framework::dataset::make("DataType", + DataType::S16)), + framework::dataset::make("InterpolationPolicy", { InterpolationPolicy::NEAREST_NEIGHBOR, InterpolationPolicy::BILINEAR })), + datasets::BorderModes()), + framework::dataset::make("SamplingPolicy", { SamplingPolicy::CENTER }))) { //Create valid region TensorInfo src_info(_shape, 1, _data_type); @@ -183,10 +190,11 @@ FIXTURE_DATA_TEST_CASE(RunSmall, NEScaleFixture, framework::DatasetMode // Validate output validate(Accessor(_target), _reference, valid_region, tolerance_s16, tolerance_num_s16); } -FIXTURE_DATA_TEST_CASE(RunLarge, NEScaleFixture, framework::DatasetMode::NIGHTLY, combine(combine(combine(datasets::LargeShapes(), framework::dataset::make("DataType", +FIXTURE_DATA_TEST_CASE(RunLarge, NEScaleFixture, framework::DatasetMode::NIGHTLY, combine(combine(combine(combine(datasets::LargeShapes(), framework::dataset::make("DataType", DataType::S16)), - framework::dataset::make("InterpolationPolicy", { InterpolationPolicy::NEAREST_NEIGHBOR, InterpolationPolicy::BILINEAR })), - datasets::BorderModes())) + framework::dataset::make("InterpolationPolicy", { InterpolationPolicy::NEAREST_NEIGHBOR, InterpolationPolicy::BILINEAR })), + datasets::BorderModes()), + framework::dataset::make("SamplingPolicy", { SamplingPolicy::CENTER }))) { //Create valid region TensorInfo src_info(_shape, 1, _data_type); diff --git a/tests/validation/fixtures/ScaleFixture.h b/tests/validation/fixtures/ScaleFixture.h index 476985e066..894260a02f 100644 --- a/tests/validation/fixtures/ScaleFixture.h +++ b/tests/validation/fixtures/ScaleFixture.h @@ -44,15 +44,16 @@ class ScaleValidationFixture : public framework::Fixture { public: template - void setup(TensorShape shape, DataType data_type, InterpolationPolicy policy, BorderMode border_mode) + void setup(TensorShape shape, DataType data_type, InterpolationPolicy policy, BorderMode border_mode, SamplingPolicy sampling_policy) { constexpr float max_width = 8192.0f; constexpr float max_height = 6384.0f; - _shape = shape; - _policy = policy; - _border_mode = border_mode; - _data_type = data_type; + _shape = shape; + _policy = policy; + _border_mode = border_mode; + _sampling_policy = sampling_policy; + _data_type = data_type; std::mt19937 generator(library->seed()); std::uniform_real_distribution distribution_float(0.25, 3); @@ -65,8 +66,8 @@ public: std::uniform_int_distribution distribution_u8(0, 255); T constant_border_value = static_cast(distribution_u8(generator)); - _target = compute_target(shape, scale_x, scale_y, policy, border_mode, constant_border_value); - _reference = compute_reference(shape, scale_x, scale_y, policy, border_mode, constant_border_value); + _target = compute_target(shape, scale_x, scale_y, policy, border_mode, constant_border_value, sampling_policy); + _reference = compute_reference(shape, scale_x, scale_y, policy, border_mode, constant_border_value, sampling_policy); } protected: @@ -77,7 +78,7 @@ protected: } TensorType compute_target(const TensorShape &shape, const float scale_x, const float scale_y, - InterpolationPolicy policy, BorderMode border_mode, T constant_border_value) + InterpolationPolicy policy, BorderMode border_mode, T constant_border_value, SamplingPolicy sampling_policy) { // Create tensors TensorType src = create_tensor(shape, _data_type); @@ -89,7 +90,7 @@ protected: // Create and configure function FunctionType scale; - scale.configure(&src, &dst, policy, border_mode, constant_border_value); + scale.configure(&src, &dst, policy, border_mode, constant_border_value, sampling_policy); ARM_COMPUTE_EXPECT(src.info()->is_resizable(), framework::LogLevel::ERRORS); ARM_COMPUTE_EXPECT(dst.info()->is_resizable(), framework::LogLevel::ERRORS); @@ -110,7 +111,7 @@ protected: } SimpleTensor compute_reference(const TensorShape &shape, const float scale_x, const float scale_y, - InterpolationPolicy policy, BorderMode border_mode, T constant_border_value) + InterpolationPolicy policy, BorderMode border_mode, T constant_border_value, SamplingPolicy sampling_policy) { // Create reference SimpleTensor src{ shape, _data_type }; @@ -118,7 +119,7 @@ protected: // Fill reference fill(src); - return reference::scale(src, scale_x, scale_y, policy, border_mode, constant_border_value); + return reference::scale(src, scale_x, scale_y, policy, border_mode, constant_border_value, sampling_policy); } TensorType _target{}; @@ -126,6 +127,7 @@ protected: TensorShape _shape{}; InterpolationPolicy _policy{}; BorderMode _border_mode{}; + SamplingPolicy _sampling_policy{}; DataType _data_type{}; }; } // namespace validation diff --git a/utils/TypePrinter.h b/utils/TypePrinter.h index 863fcaf6d9..876f3fc36f 100644 --- a/utils/TypePrinter.h +++ b/utils/TypePrinter.h @@ -572,6 +572,24 @@ inline ::std::ostream &operator<<(::std::ostream &os, const InterpolationPolicy return os; } +/** Formatted output of the SamplingPolicy type. */ +inline ::std::ostream &operator<<(::std::ostream &os, const SamplingPolicy &policy) +{ + switch(policy) + { + case SamplingPolicy::CENTER: + os << "CENTER"; + break; + case SamplingPolicy::TOP_LEFT: + os << "TOP_LEFT"; + break; + default: + ARM_COMPUTE_ERROR("NOT_SUPPORTED!"); + } + + return os; +} + /** Formatted output of the TensorInfo type. */ inline std::string to_string(const TensorInfo &info) { @@ -663,6 +681,13 @@ inline std::string to_string(const InterpolationPolicy &policy) return str.str(); } +inline std::string to_string(const SamplingPolicy &policy) +{ + std::stringstream str; + str << policy; + return str.str(); +} + /** Formatted output of the ConversionPolicy type. */ inline ::std::ostream &operator<<(::std::ostream &os, const ConvertPolicy &policy) { -- cgit v1.2.1