From f89a49f7bdd8d03400060488596c8757745e19cf Mon Sep 17 00:00:00 2001 From: John Richardson Date: Tue, 5 Sep 2017 11:21:56 +0100 Subject: COMPMID-503: Move MinMaxLocation to new validation Change-Id: I2d518b3a3f15e2c4786488593dac244c1d74a0f9 Reviewed-on: http://mpd-gerrit.cambridge.arm.com/86533 Tested-by: Kaizen Reviewed-by: Moritz Pflanzer --- tests/CL/CLArrayAccessor.h | 9 +- tests/IArrayAccessor.h | 10 +- tests/NEON/ArrayAccessor.h | 9 +- tests/Types.h | 14 + tests/validation/CL/MinMaxLocation.cpp | 140 ++++++++ tests/validation/CPP/MinMaxLocation.cpp | 92 +++++ tests/validation/CPP/MinMaxLocation.h | 44 +++ tests/validation/NEON/MinMaxLocation.cpp | 141 ++++++++ tests/validation/Validation.h | 32 ++ tests/validation/fixtures/MinMaxLocationFixture.h | 122 +++++++ tests/validation_old/CL/MinMaxLocation.cpp | 397 ---------------------- tests/validation_old/NEON/MinMaxLocation.cpp | 224 ------------ tests/validation_old/Reference.cpp | 12 - tests/validation_old/Reference.h | 16 - tests/validation_old/ReferenceCPP.cpp | 7 - tests/validation_old/ReferenceCPP.h | 11 - tests/validation_old/TensorOperations.h | 66 ---- tests/validation_old/TensorVisitors.h | 22 -- tests/validation_old/Validation.h | 41 --- 19 files changed, 610 insertions(+), 799 deletions(-) create mode 100644 tests/validation/CL/MinMaxLocation.cpp create mode 100644 tests/validation/CPP/MinMaxLocation.cpp create mode 100644 tests/validation/CPP/MinMaxLocation.h create mode 100644 tests/validation/NEON/MinMaxLocation.cpp create mode 100644 tests/validation/fixtures/MinMaxLocationFixture.h delete mode 100644 tests/validation_old/CL/MinMaxLocation.cpp delete mode 100644 tests/validation_old/NEON/MinMaxLocation.cpp diff --git a/tests/CL/CLArrayAccessor.h b/tests/CL/CLArrayAccessor.h index a38907dd78..a516a9d96a 100644 --- a/tests/CL/CLArrayAccessor.h +++ b/tests/CL/CLArrayAccessor.h @@ -60,7 +60,7 @@ public: _array.unmap(); } - int num_values() const override + size_t num_values() const override { return _array.num_values(); } @@ -75,6 +75,13 @@ public: _array.resize(num); } + T &at(size_t index) const override + { + ARM_COMPUTE_ERROR_ON(_array.buffer() == nullptr); + ARM_COMPUTE_ERROR_ON(index >= num_values()); + return _array.buffer()[index]; + } + private: CLArray &_array; }; diff --git a/tests/IArrayAccessor.h b/tests/IArrayAccessor.h index 73f8829ed2..f128d8f67e 100644 --- a/tests/IArrayAccessor.h +++ b/tests/IArrayAccessor.h @@ -41,7 +41,7 @@ public: virtual ~IArrayAccessor() = default; /** Number of elements of the tensor. */ - virtual int num_values() const = 0; + virtual size_t num_values() const = 0; /** Access to the buffer. * @@ -54,6 +54,14 @@ public: * @param[in] num The new array size in number of elements */ virtual void resize(size_t num) = 0; + + /** Reference to the element of the array located at the given index + * + * @param[in] index Index of the element + * + * @return A reference to the element of the array located at the given index. + */ + virtual T &at(size_t index) const = 0; }; } // namespace test } // namespace arm_compute diff --git a/tests/NEON/ArrayAccessor.h b/tests/NEON/ArrayAccessor.h index e56e6538ba..26bae10e00 100644 --- a/tests/NEON/ArrayAccessor.h +++ b/tests/NEON/ArrayAccessor.h @@ -50,7 +50,7 @@ public: ArrayAccessor(ArrayAccessor &&) = default; ArrayAccessor &operator=(ArrayAccessor &&) = default; - int num_values() const override + size_t num_values() const override { return _array.num_values(); } @@ -65,6 +65,13 @@ public: _array.resize(num); } + T &at(size_t index) const override + { + ARM_COMPUTE_ERROR_ON(_array.buffer() == nullptr); + ARM_COMPUTE_ERROR_ON(index >= num_values()); + return _array.buffer()[index]; + } + private: Array &_array; }; diff --git a/tests/Types.h b/tests/Types.h index cb9b0b9d5a..516f61c44b 100644 --- a/tests/Types.h +++ b/tests/Types.h @@ -23,6 +23,11 @@ */ #ifndef __ARM_COMPUTE_TEST_TYPES_H__ #define __ARM_COMPUTE_TEST_TYPES_H__ + +#include "arm_compute/core/Types.h" + +#include + namespace arm_compute { /** Fixed point operation */ @@ -33,5 +38,14 @@ enum class FixedPointOp INV_SQRT, /**< Inverse square root */ RECIPROCAL /**< Reciprocal */ }; + +template +struct MinMaxLocationValues +{ + MinMaxType min{}; + MinMaxType max{}; + std::vector min_loc{}; + std::vector max_loc{}; +}; } // namespace arm_compute #endif /* __ARM_COMPUTE_TEST_TYPES_H__ */ diff --git a/tests/validation/CL/MinMaxLocation.cpp b/tests/validation/CL/MinMaxLocation.cpp new file mode 100644 index 0000000000..58a84bd649 --- /dev/null +++ b/tests/validation/CL/MinMaxLocation.cpp @@ -0,0 +1,140 @@ +/* + * 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. + */ +#include "arm_compute/runtime/CL/functions/CLMinMaxLocation.h" +#include "tests/CL/CLAccessor.h" +#include "tests/CL/CLArrayAccessor.h" +#include "tests/PaddingCalculator.h" +#include "tests/datasets/ShapeDatasets.h" +#include "tests/framework/Macros.h" +#include "tests/validation/Validation.h" +#include "tests/validation/fixtures/MinMaxLocationFixture.h" + +namespace arm_compute +{ +namespace test +{ +namespace validation +{ +TEST_SUITE(CL) +TEST_SUITE(MinMaxLocation) + +template +using CLMinMaxLocationFixture = MinMaxLocationValidationFixture, CLArrayAccessor, CLMinMaxLocation, T>; + +void validate_configuration(const CLTensor &src, TensorShape shape) +{ + ARM_COMPUTE_EXPECT(src.info()->is_resizable(), framework::LogLevel::ERRORS); + + // Create output storage + int32_t min{}; + int32_t max{}; + CLCoordinates2DArray min_loc(shape.total_size()); + CLCoordinates2DArray max_loc(shape.total_size()); + + // Create and configure function + CLMinMaxLocation min_max_loc; + min_max_loc.configure(&src, &min, &max, &min_loc, &max_loc); + + // Validate padding + const PaddingSize padding = PaddingCalculator(shape.x(), src.info()->dimension(0)).required_padding(); + validate(src.info()->padding(), padding); +} + +TEST_SUITE(U8) +DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(concat(datasets::Small2DShapes(), datasets::Large2DShapes()), framework::dataset::make("DataType", DataType::U8)), shape, data_type) +{ + // Create tensors + CLTensor src = create_tensor(shape, data_type); + src.info()->set_format(Format::U8); + + validate_configuration(src, shape); +} + +FIXTURE_DATA_TEST_CASE(RunSmall, CLMinMaxLocationFixture, framework::DatasetMode::PRECOMMIT, combine(datasets::Small2DShapes(), framework::dataset::make("DataType", + DataType::U8))) +{ + validate_min_max_loc(_target, _reference); +} + +FIXTURE_DATA_TEST_CASE(RunLarge, CLMinMaxLocationFixture, framework::DatasetMode::NIGHTLY, combine(datasets::Large2DShapes(), framework::dataset::make("DataType", + DataType::U8))) +{ + validate_min_max_loc(_target, _reference); +} + +TEST_SUITE_END() // U8 + +TEST_SUITE(S16) +DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(concat(datasets::Small2DShapes(), datasets::Large2DShapes()), framework::dataset::make("DataType", DataType::S16)), shape, data_type) +{ + // Create tensors + CLTensor src = create_tensor(shape, data_type); + src.info()->set_format(Format::S16); + + validate_configuration(src, shape); +} + +FIXTURE_DATA_TEST_CASE(RunSmall, CLMinMaxLocationFixture, framework::DatasetMode::PRECOMMIT, combine(datasets::Small2DShapes(), framework::dataset::make("DataType", + DataType::S16))) +{ + validate_min_max_loc(_target, _reference); +} + +FIXTURE_DATA_TEST_CASE(RunLarge, CLMinMaxLocationFixture, framework::DatasetMode::NIGHTLY, combine(datasets::Large2DShapes(), framework::dataset::make("DataType", + DataType::S16))) +{ + validate_min_max_loc(_target, _reference); +} + +TEST_SUITE_END() // S16 + +TEST_SUITE(Float) +DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(concat(datasets::Small2DShapes(), datasets::Large2DShapes()), framework::dataset::make("DataType", DataType::F32)), shape, data_type) +{ + // Create tensors + CLTensor src = create_tensor(shape, data_type); + src.info()->set_format(Format::F32); + + validate_configuration(src, shape); +} + +FIXTURE_DATA_TEST_CASE(RunSmall, CLMinMaxLocationFixture, framework::DatasetMode::PRECOMMIT, combine(datasets::Small2DShapes(), framework::dataset::make("DataType", + DataType::F32))) +{ + validate_min_max_loc(_target, _reference); +} + +FIXTURE_DATA_TEST_CASE(RunLarge, CLMinMaxLocationFixture, framework::DatasetMode::NIGHTLY, combine(datasets::Large2DShapes(), framework::dataset::make("DataType", + DataType::F32))) +{ + validate_min_max_loc(_target, _reference); +} + +TEST_SUITE_END() // F32 + +TEST_SUITE_END() // MinMaxLocation +TEST_SUITE_END() // CL +} // namespace validation +} // namespace test +} // namespace arm_compute diff --git a/tests/validation/CPP/MinMaxLocation.cpp b/tests/validation/CPP/MinMaxLocation.cpp new file mode 100644 index 0000000000..427adebc61 --- /dev/null +++ b/tests/validation/CPP/MinMaxLocation.cpp @@ -0,0 +1,92 @@ +/* + * 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 src 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 src 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. src NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER src AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR src CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include "MinMaxLocation.h" + +namespace arm_compute +{ +namespace test +{ +namespace validation +{ +namespace reference +{ +template +void compute_min_max(const SimpleTensor &src, T &min, T &max) +{ + // Set min and max to first pixel + min = src[0]; + max = src[0]; + + ARM_COMPUTE_ERROR_ON(src.num_elements() == 0); + + // Look for min and max values + for(int i = 1; i < src.num_elements(); ++i) + { + if(src[i] < min) + { + min = src[i]; + } + if(src[i] > max) + { + max = src[i]; + } + } +} + +template +MinMaxLocationValues min_max_location(const SimpleTensor &src) +{ + MinMaxLocationValues dst; + + const size_t width = src.shape().x(); + + compute_min_max(src, dst.min, dst.max); + + Coordinates2D coord{ 0, 0 }; + + for(int i = 0; i < src.num_elements(); ++i) + { + coord.x = static_cast(i % width); + coord.y = static_cast(i / width); + + if(src[i] == dst.min) + { + dst.min_loc.push_back(coord); + } + if(src[i] == dst.max) + { + dst.max_loc.push_back(coord); + } + } + + return dst; +} + +template MinMaxLocationValues min_max_location(const SimpleTensor &src); +template MinMaxLocationValues min_max_location(const SimpleTensor &src); +template MinMaxLocationValues min_max_location(const SimpleTensor &src); +} // namespace reference +} // namespace validation +} // namespace test +} // namespace arm_compute diff --git a/tests/validation/CPP/MinMaxLocation.h b/tests/validation/CPP/MinMaxLocation.h new file mode 100644 index 0000000000..ebaf90b131 --- /dev/null +++ b/tests/validation/CPP/MinMaxLocation.h @@ -0,0 +1,44 @@ +/* + * 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_MIN_MAX_LOCATION_H__ +#define __ARM_COMPUTE_TEST_MIN_MAX_LOCATION_H__ + +#include "tests/SimpleTensor.h" +#include "tests/Types.h" + +namespace arm_compute +{ +namespace test +{ +namespace validation +{ +namespace reference +{ +template +MinMaxLocationValues min_max_location(const SimpleTensor &src); +} // namespace reference +} // namespace validation +} // namespace test +} // namespace arm_compute +#endif /* __ARM_COMPUTE_TEST_MIN_MAX_LOCATION_H__ */ diff --git a/tests/validation/NEON/MinMaxLocation.cpp b/tests/validation/NEON/MinMaxLocation.cpp new file mode 100644 index 0000000000..367bb6a2df --- /dev/null +++ b/tests/validation/NEON/MinMaxLocation.cpp @@ -0,0 +1,141 @@ +/* + * 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. + */ + +#include "arm_compute/runtime/NEON/functions/NEMinMaxLocation.h" +#include "tests/NEON/Accessor.h" +#include "tests/NEON/ArrayAccessor.h" +#include "tests/PaddingCalculator.h" +#include "tests/datasets/ShapeDatasets.h" +#include "tests/framework/Macros.h" +#include "tests/validation/Validation.h" +#include "tests/validation/fixtures/MinMaxLocationFixture.h" + +namespace arm_compute +{ +namespace test +{ +namespace validation +{ +TEST_SUITE(NEON) +TEST_SUITE(MinMaxLocation) + +template +using NEMinMaxLocationFixture = MinMaxLocationValidationFixture, ArrayAccessor, NEMinMaxLocation, T>; + +void validate_configuration(const Tensor &src, TensorShape shape) +{ + ARM_COMPUTE_EXPECT(src.info()->is_resizable(), framework::LogLevel::ERRORS); + + // Create output storage + int32_t min{}; + int32_t max{}; + Coordinates2DArray min_loc(shape.total_size()); + Coordinates2DArray max_loc(shape.total_size()); + + // Create and configure function + NEMinMaxLocation min_max_loc; + min_max_loc.configure(&src, &min, &max, &min_loc, &max_loc); + + // Validate padding + const PaddingSize padding = PaddingCalculator(shape.x(), 1).required_padding(); + validate(src.info()->padding(), padding); +} + +TEST_SUITE(U8) +DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(concat(datasets::Small2DShapes(), datasets::Large2DShapes()), framework::dataset::make("DataType", DataType::U8)), shape, data_type) +{ + // Create tensors + Tensor src = create_tensor(shape, data_type); + src.info()->set_format(Format::U8); + + validate_configuration(src, shape); +} + +FIXTURE_DATA_TEST_CASE(RunSmall, NEMinMaxLocationFixture, framework::DatasetMode::PRECOMMIT, combine(datasets::Small2DShapes(), framework::dataset::make("DataType", + DataType::U8))) +{ + validate_min_max_loc(_target, _reference); +} + +FIXTURE_DATA_TEST_CASE(RunLarge, NEMinMaxLocationFixture, framework::DatasetMode::NIGHTLY, combine(datasets::Large2DShapes(), framework::dataset::make("DataType", + DataType::U8))) +{ + validate_min_max_loc(_target, _reference); +} + +TEST_SUITE_END() // U8 + +TEST_SUITE(S16) +DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(concat(datasets::Small2DShapes(), datasets::Large2DShapes()), framework::dataset::make("DataType", DataType::S16)), shape, data_type) +{ + // Create tensors + Tensor src = create_tensor(shape, data_type); + src.info()->set_format(Format::S16); + + validate_configuration(src, shape); +} + +FIXTURE_DATA_TEST_CASE(RunSmall, NEMinMaxLocationFixture, framework::DatasetMode::PRECOMMIT, combine(datasets::Small2DShapes(), framework::dataset::make("DataType", + DataType::S16))) +{ + validate_min_max_loc(_target, _reference); +} + +FIXTURE_DATA_TEST_CASE(RunLarge, NEMinMaxLocationFixture, framework::DatasetMode::NIGHTLY, combine(datasets::Large2DShapes(), framework::dataset::make("DataType", + DataType::S16))) +{ + validate_min_max_loc(_target, _reference); +} + +TEST_SUITE_END() // S16 + +TEST_SUITE(Float) +DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(concat(datasets::Small2DShapes(), datasets::Large2DShapes()), framework::dataset::make("DataType", DataType::F32)), shape, data_type) +{ + // Create tensors + Tensor src = create_tensor(shape, data_type); + src.info()->set_format(Format::F32); + + validate_configuration(src, shape); +} + +FIXTURE_DATA_TEST_CASE(RunSmall, NEMinMaxLocationFixture, framework::DatasetMode::PRECOMMIT, combine(datasets::Small2DShapes(), framework::dataset::make("DataType", + DataType::F32))) +{ + validate_min_max_loc(_target, _reference); +} + +FIXTURE_DATA_TEST_CASE(RunLarge, NEMinMaxLocationFixture, framework::DatasetMode::NIGHTLY, combine(datasets::Large2DShapes(), framework::dataset::make("DataType", + DataType::F32))) +{ + validate_min_max_loc(_target, _reference); +} + +TEST_SUITE_END() // F32 + +TEST_SUITE_END() // MinMaxLocation +TEST_SUITE_END() // NEON +} // namespace validation +} // namespace test +} // namespace arm_compute diff --git a/tests/validation/Validation.h b/tests/validation/Validation.h index 38cbadaa9b..60461f3579 100644 --- a/tests/validation/Validation.h +++ b/tests/validation/Validation.h @@ -28,6 +28,7 @@ #include "arm_compute/core/Types.h" #include "tests/IAccessor.h" #include "tests/SimpleTensor.h" +#include "tests/Types.h" #include "tests/Utils.h" #include "tests/framework/Asserts.h" #include "tests/framework/Exceptions.h" @@ -365,6 +366,37 @@ void validate(T target, T reference, U tolerance) ARM_COMPUTE_TEST_INFO("tolerance = " << std::setprecision(5) << framework::make_printable(static_cast(tolerance))); ARM_COMPUTE_EXPECT((compare(target, reference, tolerance)), framework::LogLevel::ERRORS); } + +template +void validate_min_max_loc(const MinMaxLocationValues &target, const MinMaxLocationValues &reference) +{ + ARM_COMPUTE_EXPECT_EQUAL(target.min, reference.min, framework::LogLevel::ERRORS); + ARM_COMPUTE_EXPECT_EQUAL(target.max, reference.max, framework::LogLevel::ERRORS); + + ARM_COMPUTE_EXPECT_EQUAL(target.min_loc.size(), reference.min_loc.size(), framework::LogLevel::ERRORS); + ARM_COMPUTE_EXPECT_EQUAL(target.max_loc.size(), reference.max_loc.size(), framework::LogLevel::ERRORS); + + for(uint32_t i = 0; i < target.min_loc.size(); ++i) + { + const auto same_coords = std::find_if(reference.min_loc.begin(), reference.min_loc.end(), [&target, i](Coordinates2D coord) + { + return coord.x == target.min_loc.at(i).x && coord.y == target.min_loc.at(i).y; + }); + + ARM_COMPUTE_EXPECT(same_coords != reference.min_loc.end(), framework::LogLevel::ERRORS); + } + + for(uint32_t i = 0; i < target.max_loc.size(); ++i) + { + const auto same_coords = std::find_if(reference.max_loc.begin(), reference.max_loc.end(), [&target, i](Coordinates2D coord) + { + return coord.x == target.max_loc.at(i).x && coord.y == target.max_loc.at(i).y; + }); + + ARM_COMPUTE_EXPECT(same_coords != reference.max_loc.end(), framework::LogLevel::ERRORS); + } +} + } // namespace validation } // namespace test } // namespace arm_compute diff --git a/tests/validation/fixtures/MinMaxLocationFixture.h b/tests/validation/fixtures/MinMaxLocationFixture.h new file mode 100644 index 0000000000..bf076ef0ab --- /dev/null +++ b/tests/validation/fixtures/MinMaxLocationFixture.h @@ -0,0 +1,122 @@ +/* + * 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_MIN_MAX_LOCATION_FIXTURE +#define ARM_COMPUTE_TEST_MIN_MAX_LOCATION_FIXTURE + +#include "arm_compute/core/TensorShape.h" +#include "arm_compute/core/Types.h" +#include "tests/AssetsLibrary.h" +#include "tests/Globals.h" +#include "tests/Types.h" +#include "tests/framework/Asserts.h" +#include "tests/framework/Fixture.h" +#include "tests/validation/CPP/MinMaxLocation.h" + +namespace arm_compute +{ +namespace test +{ +namespace validation +{ +template +class MinMaxLocationValidationFixture : public framework::Fixture +{ +public: + using target_type = typename std::conditional::value, int32_t, float>::type; + + template + void setup(TensorShape shape, DataType data_type) + { + _target = compute_target(shape, data_type); + _reference = compute_reference(shape, data_type); + } + +protected: + template + void fill(U &&tensor) + { + library->fill_tensor_uniform(tensor, 0); + } + + MinMaxLocationValues compute_target(const TensorShape &shape, DataType data_type) + { + MinMaxLocationValues target; + + ArrayType min_loc(shape.total_size()); + ArrayType max_loc(shape.total_size()); + + // Create tensors + TensorType src = create_tensor(shape, data_type); + + // Create and configure function + FunctionType min_max_loc; + min_max_loc.configure(&src, &target.min, &target.max, &min_loc, &max_loc); + + // Allocate tensors + src.allocator()->allocate(); + ARM_COMPUTE_EXPECT(!src.info()->is_resizable(), framework::LogLevel::ERRORS); + + // Fill tensors + fill(AccessorType(src)); + + // Compute function + min_max_loc.run(); + + // Create accessor objects for mapping operations + ArrayAccessorType min_loc_accessor(min_loc); + ArrayAccessorType max_loc_accessor(max_loc); + + // Move min Coordinates2D values from ArrayType to vector + for(size_t i = 0; i < min_loc.num_values(); ++i) + { + target.min_loc.push_back(std::move(min_loc_accessor.at(i))); + } + + // Move max Coordinates2D values from ArrayType to vector + for(size_t i = 0; i < max_loc.num_values(); ++i) + { + target.max_loc.push_back(std::move(max_loc_accessor.at(i))); + } + + return target; + } + + MinMaxLocationValues compute_reference(const TensorShape &shape, DataType data_type) + { + // Create reference + SimpleTensor src{ shape, data_type }; + + // Fill reference + fill(src); + + return reference::min_max_location(src); + } + + MinMaxLocationValues _target{}; + MinMaxLocationValues _reference{}; +}; +} // namespace validation +} // namespace test +} // namespace arm_compute +#endif /* ARM_COMPUTE_TEST_MIN_MAX_LOCATION_FIXTURE */ diff --git a/tests/validation_old/CL/MinMaxLocation.cpp b/tests/validation_old/CL/MinMaxLocation.cpp deleted file mode 100644 index 06e9388abc..0000000000 --- a/tests/validation_old/CL/MinMaxLocation.cpp +++ /dev/null @@ -1,397 +0,0 @@ -/* - * 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. - */ - -#include "CL/CLAccessor.h" -#include "Utils.h" -#include "tests/AssetsLibrary.h" -#include "tests/Globals.h" -#include "tests/validation_old/Datasets.h" -#include "tests/validation_old/Reference.h" -#include "tests/validation_old/Validation.h" -#include "utils/TypePrinter.h" - -#include "arm_compute/core/Helpers.h" -#include "arm_compute/core/Types.h" -#include "arm_compute/runtime/CL/functions/CLMinMaxLocation.h" -#include "arm_compute/runtime/Tensor.h" -#include "arm_compute/runtime/TensorAllocator.h" - -#include "PaddingCalculator.h" -#include "tests/validation_old/boost_wrapper.h" - -#include -#include - -using namespace arm_compute; -using namespace arm_compute::test; -using namespace arm_compute::test::validation; - -namespace -{ -/** Compute CL MinMaxLocation function. - * - * @param[in] shape Shape of the input and output tensors. - * @param[in] dt_in Data type of first input tensor. - * @param[out] min Minimum value of tensor - * @param[out] max Maximum value of tensor - * @param[out] min_loc Array with locations of minimum values - * @param[out] max_loc Array with locations of maximum values - * @param[out] min_count Number of minimum values found - * @param[out] max_count Number of maximum values found - * - * @return Computed output tensor. - */ -void compute_min_max_location(const TensorShape &shape, DataType dt_in, void *min, void *max, - CLCoordinates2DArray &min_loc, CLCoordinates2DArray &max_loc, uint32_t &min_count, uint32_t &max_count) -{ - // Create tensor - CLTensor src = create_tensor(shape, dt_in); - - // Create and configure min_max_location configure function - CLMinMaxLocation min_max_loc; - min_max_loc.configure(&src, min, max, &min_loc, &max_loc, &min_count, &max_count); - - // Allocate tensors - src.allocator()->allocate(); - - BOOST_TEST(!src.info()->is_resizable()); - - // Fill tensors - library->fill_tensor_uniform(CLAccessor(src), 0); - - // Compute function - min_max_loc.run(); -} - -void validate_configuration(const CLTensor &src, TensorShape shape) -{ - BOOST_TEST(src.info()->is_resizable()); - - // Create output storage - int32_t min; - int32_t max; - CLCoordinates2DArray min_loc(shape.total_size()); - CLCoordinates2DArray max_loc(shape.total_size()); - uint32_t min_count; - uint32_t max_count; - - // Create and configure function - CLMinMaxLocation min_max_loc; - min_max_loc.configure(&src, &min, &max, &min_loc, &max_loc, &min_count, &max_count); - - // Validate valid region - const ValidRegion valid_region = shape_to_valid_region(shape); - validate(src.info()->valid_region(), valid_region); - - // Validate padding - const PaddingSize padding = PaddingCalculator(shape.x(), src.info()->dimension(0)).required_padding(); - validate(src.info()->padding(), padding); -} -} // namespace - -#ifndef DOXYGEN_SKIP_THIS -BOOST_AUTO_TEST_SUITE(CL) -BOOST_AUTO_TEST_SUITE(MinMaxLocation) -BOOST_AUTO_TEST_SUITE(U8) - -BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit") * boost::unit_test::label("nightly")) -BOOST_DATA_TEST_CASE(Configuration, (Small2DShapes() + Large2DShapes()), - shape) -{ - // Create tensor - CLTensor src = create_tensor(shape, DataType::U8); - src.info()->set_format(Format::U8); - - validate_configuration(src, shape); -} - -BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit")) -BOOST_DATA_TEST_CASE(RunSmall, Small2DShapes(), - shape) -{ - // Create output storage - int32_t min; - int32_t max; - CLCoordinates2DArray min_loc(shape.total_size()); - CLCoordinates2DArray max_loc(shape.total_size()); - uint32_t min_count; - uint32_t max_count; - - int32_t ref_min; - int32_t ref_max; - CLCoordinates2DArray ref_min_loc(shape.total_size()); - CLCoordinates2DArray ref_max_loc(shape.total_size()); - uint32_t ref_min_count; - uint32_t ref_max_count; - - // Compute function - compute_min_max_location(shape, DataType::U8, &min, &max, min_loc, max_loc, min_count, max_count); - - // Compute reference - ref_min_loc.map(); - ref_max_loc.map(); - - Reference::compute_reference_min_max_location(shape, DataType::U8, &ref_min, &ref_max, ref_min_loc, ref_max_loc, ref_min_count, ref_max_count); - - min_loc.map(); - max_loc.map(); - - // Validate output - validate_min_max_loc(min, ref_min, max, ref_max, min_loc, ref_min_loc, max_loc, ref_max_loc, min_count, ref_min_count, max_count, ref_max_count); - - ref_min_loc.unmap(); - ref_max_loc.unmap(); - min_loc.unmap(); - max_loc.unmap(); -} - -BOOST_TEST_DECORATOR(*boost::unit_test::label("nightly")) -BOOST_DATA_TEST_CASE(RunLarge, Large2DShapes(), - shape) -{ - // Create output storage - int32_t min; - int32_t max; - CLCoordinates2DArray min_loc(shape.total_size()); - CLCoordinates2DArray max_loc(shape.total_size()); - uint32_t min_count; - uint32_t max_count; - - int32_t ref_min; - int32_t ref_max; - CLCoordinates2DArray ref_min_loc(shape.total_size()); - CLCoordinates2DArray ref_max_loc(shape.total_size()); - uint32_t ref_min_count; - uint32_t ref_max_count; - - // Compute function - compute_min_max_location(shape, DataType::U8, &min, &max, min_loc, max_loc, min_count, max_count); - - // Compute reference - ref_min_loc.map(); - ref_max_loc.map(); - - Reference::compute_reference_min_max_location(shape, DataType::U8, &ref_min, &ref_max, ref_min_loc, ref_max_loc, ref_min_count, ref_max_count); - - min_loc.map(); - max_loc.map(); - - // Validate output - validate_min_max_loc(min, ref_min, max, ref_max, min_loc, ref_min_loc, max_loc, ref_max_loc, min_count, ref_min_count, max_count, ref_max_count); - - ref_min_loc.unmap(); - ref_max_loc.unmap(); - min_loc.unmap(); - max_loc.unmap(); -} -BOOST_AUTO_TEST_SUITE_END() - -BOOST_AUTO_TEST_SUITE(S16) -BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit") * boost::unit_test::label("nightly")) -BOOST_DATA_TEST_CASE(Configuration, (Small2DShapes() + Large2DShapes()), - shape) -{ - // Create tensor - CLTensor src = create_tensor(shape, DataType::S16); - src.info()->set_format(Format::S16); - - validate_configuration(src, shape); -} - -BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit")) -BOOST_DATA_TEST_CASE(RunSmall, Small2DShapes(), - shape) -{ - // Create output storage - int32_t min; - int32_t max; - CLCoordinates2DArray min_loc(shape.total_size()); - CLCoordinates2DArray max_loc(shape.total_size()); - uint32_t min_count; - uint32_t max_count; - - int32_t ref_min; - int32_t ref_max; - CLCoordinates2DArray ref_min_loc(shape.total_size()); - CLCoordinates2DArray ref_max_loc(shape.total_size()); - uint32_t ref_min_count; - uint32_t ref_max_count; - - // Compute function - compute_min_max_location(shape, DataType::S16, &min, &max, min_loc, max_loc, min_count, max_count); - - // Compute reference - ref_min_loc.map(); - ref_max_loc.map(); - - Reference::compute_reference_min_max_location(shape, DataType::S16, &ref_min, &ref_max, ref_min_loc, ref_max_loc, ref_min_count, ref_max_count); - - min_loc.map(); - max_loc.map(); - - // Validate output - validate_min_max_loc(min, ref_min, max, ref_max, min_loc, ref_min_loc, max_loc, ref_max_loc, min_count, ref_min_count, max_count, ref_max_count); - - ref_min_loc.unmap(); - ref_max_loc.unmap(); - min_loc.unmap(); - max_loc.unmap(); -} - -BOOST_TEST_DECORATOR(*boost::unit_test::label("nightly")) -BOOST_DATA_TEST_CASE(RunLarge, Large2DShapes(), - shape) -{ - // Create output storage - int32_t min; - int32_t max; - CLCoordinates2DArray min_loc(shape.total_size()); - CLCoordinates2DArray max_loc(shape.total_size()); - uint32_t min_count; - uint32_t max_count; - - int32_t ref_min; - int32_t ref_max; - CLCoordinates2DArray ref_min_loc(shape.total_size()); - CLCoordinates2DArray ref_max_loc(shape.total_size()); - uint32_t ref_min_count; - uint32_t ref_max_count; - - // Compute function - compute_min_max_location(shape, DataType::S16, &min, &max, min_loc, max_loc, min_count, max_count); - - // Compute reference - ref_min_loc.map(); - ref_max_loc.map(); - - Reference::compute_reference_min_max_location(shape, DataType::S16, &ref_min, &ref_max, ref_min_loc, ref_max_loc, ref_min_count, ref_max_count); - - min_loc.map(); - max_loc.map(); - - // Validate output - validate_min_max_loc(min, ref_min, max, ref_max, min_loc, ref_min_loc, max_loc, ref_max_loc, min_count, ref_min_count, max_count, ref_max_count); - - ref_min_loc.unmap(); - ref_max_loc.unmap(); - min_loc.unmap(); - max_loc.unmap(); -} -BOOST_AUTO_TEST_SUITE_END() - -BOOST_AUTO_TEST_SUITE(Float) -BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit") * boost::unit_test::label("nightly")) -BOOST_DATA_TEST_CASE(Configuration, (Small2DShapes() + Large2DShapes()), - shape) -{ - // Create tensor - CLTensor src = create_tensor(shape, DataType::F32); - - validate_configuration(src, shape); -} - -BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit")) -BOOST_DATA_TEST_CASE(RunSmall, Small2DShapes(), - shape) -{ - // Create output storage - float min; - float max; - CLCoordinates2DArray min_loc(shape.total_size()); - CLCoordinates2DArray max_loc(shape.total_size()); - uint32_t min_count; - uint32_t max_count; - - float ref_min; - float ref_max; - CLCoordinates2DArray ref_min_loc(shape.total_size()); - CLCoordinates2DArray ref_max_loc(shape.total_size()); - uint32_t ref_min_count; - uint32_t ref_max_count; - - // Compute function - compute_min_max_location(shape, DataType::F32, &min, &max, min_loc, max_loc, min_count, max_count); - - // Compute reference - ref_min_loc.map(); - ref_max_loc.map(); - - Reference::compute_reference_min_max_location(shape, DataType::F32, &ref_min, &ref_max, ref_min_loc, ref_max_loc, ref_min_count, ref_max_count); - - min_loc.map(); - max_loc.map(); - - // Validate output - validate_min_max_loc(min, ref_min, max, ref_max, min_loc, ref_min_loc, max_loc, ref_max_loc, min_count, ref_min_count, max_count, ref_max_count); - - ref_min_loc.unmap(); - ref_max_loc.unmap(); - min_loc.unmap(); - max_loc.unmap(); -} - -BOOST_TEST_DECORATOR(*boost::unit_test::label("nightly")) -BOOST_DATA_TEST_CASE(RunLarge, Large2DShapes(), - shape) -{ - // Create output storage - float min; - float max; - CLCoordinates2DArray min_loc(shape.total_size()); - CLCoordinates2DArray max_loc(shape.total_size()); - uint32_t min_count; - uint32_t max_count; - - float ref_min; - float ref_max; - CLCoordinates2DArray ref_min_loc(shape.total_size()); - CLCoordinates2DArray ref_max_loc(shape.total_size()); - uint32_t ref_min_count; - uint32_t ref_max_count; - - // Compute function - compute_min_max_location(shape, DataType::F32, &min, &max, min_loc, max_loc, min_count, max_count); - - // Compute reference - ref_min_loc.map(); - ref_max_loc.map(); - - Reference::compute_reference_min_max_location(shape, DataType::F32, &ref_min, &ref_max, ref_min_loc, ref_max_loc, ref_min_count, ref_max_count); - - min_loc.map(); - max_loc.map(); - - // Validate output - validate_min_max_loc(min, ref_min, max, ref_max, min_loc, ref_min_loc, max_loc, ref_max_loc, min_count, ref_min_count, max_count, ref_max_count); - - ref_min_loc.unmap(); - ref_max_loc.unmap(); - min_loc.unmap(); - max_loc.unmap(); -} -BOOST_AUTO_TEST_SUITE_END() - -BOOST_AUTO_TEST_SUITE_END() -BOOST_AUTO_TEST_SUITE_END() -#endif /* DOXYGEN_SKIP_THIS */ diff --git a/tests/validation_old/NEON/MinMaxLocation.cpp b/tests/validation_old/NEON/MinMaxLocation.cpp deleted file mode 100644 index 1b258d19d6..0000000000 --- a/tests/validation_old/NEON/MinMaxLocation.cpp +++ /dev/null @@ -1,224 +0,0 @@ -/* - * 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. - */ - -#include "NEON/Accessor.h" -#include "NEON/Helper.h" -#include "PaddingCalculator.h" -#include "Utils.h" -#include "tests/AssetsLibrary.h" -#include "tests/Globals.h" -#include "tests/validation_old/Datasets.h" -#include "tests/validation_old/Reference.h" -#include "tests/validation_old/Validation.h" -#include "utils/TypePrinter.h" - -#include "arm_compute/core/Helpers.h" -#include "arm_compute/core/Types.h" -#include "arm_compute/runtime/NEON/functions/NEMinMaxLocation.h" -#include "arm_compute/runtime/Tensor.h" -#include "arm_compute/runtime/TensorAllocator.h" - -#include "tests/validation_old/boost_wrapper.h" - -#include -#include - -using namespace arm_compute; -using namespace arm_compute::test; -using namespace arm_compute::test::validation; - -namespace -{ -/** Compute Neon MinMaxLocation function. - * - * @param[in] shape Shape of the input and output tensors. - * @param[in] dt_in Data type of first input tensor. - * @param[out] min Minimum value of tensor - * @param[out] max Maximum value of tensor - * @param[out] min_loc Array with locations of minimum values - * @param[out] max_loc Array with locations of maximum values - * @param[out] min_count Number of minimum values found - * @param[out] max_count Number of maximum values found - * - * @return Computed output tensor. - */ - -void compute_min_max_location(const TensorShape &shape, DataType dt_in, void *min, void *max, - Coordinates2DArray &min_loc, Coordinates2DArray &max_loc, uint32_t &min_count, uint32_t &max_count) -{ - // Create tensor - Tensor src = create_tensor(shape, dt_in); - - // Create and configure min_max_location configure function - NEMinMaxLocation min_max_loc; - min_max_loc.configure(&src, min, max, &min_loc, &max_loc, &min_count, &max_count); - - // Allocate tensors - src.allocator()->allocate(); - - BOOST_TEST(!src.info()->is_resizable()); - - // Fill tensors - library->fill_tensor_uniform(Accessor(src), 0); - - // Compute function - min_max_loc.run(); -} - -void validate_configuration(const Tensor &src, TensorShape shape) -{ - BOOST_TEST(src.info()->is_resizable()); - - // Create output storage - int32_t min; - int32_t max; - Coordinates2DArray min_loc; - Coordinates2DArray max_loc; - uint32_t min_count; - uint32_t max_count; - - // Create and configure function - NEMinMaxLocation min_max_loc; - min_max_loc.configure(&src, &min, &max, &min_loc, &max_loc, &min_count, &max_count); - - // Validate valid region - const ValidRegion valid_region = shape_to_valid_region(shape); - validate(src.info()->valid_region(), valid_region); - - // Validate padding - const PaddingSize padding = PaddingCalculator(shape.x(), 1).required_padding(); - validate(src.info()->padding(), padding); -} -} // namespace - -#ifndef DOXYGEN_SKIP_THIS -BOOST_AUTO_TEST_SUITE(NEON) -BOOST_AUTO_TEST_SUITE(MinMaxLocation) - -BOOST_AUTO_TEST_SUITE(Integer) -BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit") * boost::unit_test::label("nightly")) -BOOST_DATA_TEST_CASE(Configuration, (Small2DShapes() + Large2DShapes()) * boost::unit_test::data::make({ DataType::U8, DataType::S16 }), - shape, dt) -{ - // Create tensor - Tensor src = create_tensor(shape, dt); - src.info()->set_format(dt == DataType::U8 ? Format::U8 : Format::S16); - - validate_configuration(src, shape); -} - -BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit")) -BOOST_DATA_TEST_CASE(RunSmall, Small2DShapes() * boost::unit_test::data::make({ DataType::U8, DataType::S16 }), - shape, dt) -{ - // Create output storage - int32_t min; - int32_t max; - Coordinates2DArray min_loc(shape.total_size()); - Coordinates2DArray max_loc(shape.total_size()); - uint32_t min_count; - uint32_t max_count; - - int32_t ref_min; - int32_t ref_max; - Coordinates2DArray ref_min_loc(shape.total_size()); - Coordinates2DArray ref_max_loc(shape.total_size()); - uint32_t ref_min_count; - uint32_t ref_max_count; - - // Compute function - compute_min_max_location(shape, dt, &min, &max, min_loc, max_loc, min_count, max_count); - - // Compute reference - Reference::compute_reference_min_max_location(shape, dt, &ref_min, &ref_max, ref_min_loc, ref_max_loc, ref_min_count, ref_max_count); - - // Validate output - validate_min_max_loc(min, ref_min, max, ref_max, min_loc, ref_min_loc, max_loc, ref_max_loc, min_count, ref_min_count, max_count, ref_max_count); -} - -BOOST_TEST_DECORATOR(*boost::unit_test::label("nightly")) -BOOST_DATA_TEST_CASE(RunLarge, Large2DShapes() * boost::unit_test::data::make({ DataType::U8, DataType::S16 }), - shape, dt) -{ - // Create output storage - int32_t min; - int32_t max; - Coordinates2DArray min_loc(shape.total_size()); - Coordinates2DArray max_loc(shape.total_size()); - uint32_t min_count; - uint32_t max_count; - - int32_t ref_min; - int32_t ref_max; - Coordinates2DArray ref_min_loc(shape.total_size()); - Coordinates2DArray ref_max_loc(shape.total_size()); - uint32_t ref_min_count; - uint32_t ref_max_count; - - // Compute function - compute_min_max_location(shape, dt, &min, &max, min_loc, max_loc, min_count, max_count); - - // Compute reference - Reference::compute_reference_min_max_location(shape, dt, &ref_min, &ref_max, ref_min_loc, ref_max_loc, ref_min_count, ref_max_count); - - // Validate output - validate_min_max_loc(min, ref_min, max, ref_max, min_loc, ref_min_loc, max_loc, ref_max_loc, min_count, ref_min_count, max_count, ref_max_count); -} -BOOST_AUTO_TEST_SUITE_END() - -BOOST_AUTO_TEST_SUITE(Float) -BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit")) -BOOST_DATA_TEST_CASE(RunSmall, Small2DShapes() * DataType::F32, - shape, dt) -{ - // Create output storage - float min; - float max; - Coordinates2DArray min_loc(shape.total_size()); - Coordinates2DArray max_loc(shape.total_size()); - uint32_t min_count; - uint32_t max_count; - - float ref_min; - float ref_max; - Coordinates2DArray ref_min_loc(shape.total_size()); - Coordinates2DArray ref_max_loc(shape.total_size()); - uint32_t ref_min_count; - uint32_t ref_max_count; - - // Compute function - compute_min_max_location(shape, dt, &min, &max, min_loc, max_loc, min_count, max_count); - - // Compute reference - Reference::compute_reference_min_max_location(shape, dt, &ref_min, &ref_max, ref_min_loc, ref_max_loc, ref_min_count, ref_max_count); - - // Validate output - validate_min_max_loc(min, ref_min, max, ref_max, min_loc, ref_min_loc, max_loc, ref_max_loc, min_count, ref_min_count, max_count, ref_max_count); -} - -BOOST_AUTO_TEST_SUITE_END() - -BOOST_AUTO_TEST_SUITE_END() -BOOST_AUTO_TEST_SUITE_END() -#endif /* DOXYGEN_SKIP_THIS */ diff --git a/tests/validation_old/Reference.cpp b/tests/validation_old/Reference.cpp index fc5484606e..b5fe1d2baf 100644 --- a/tests/validation_old/Reference.cpp +++ b/tests/validation_old/Reference.cpp @@ -72,18 +72,6 @@ std::pair Reference::compute_reference_sobel_5x5(const Ten return std::make_pair(ref_dst_x, ref_dst_y); } -void Reference::compute_reference_min_max_location(const TensorShape &shape, DataType dt_in, void *min, void *max, IArray &min_loc, IArray &max_loc, - uint32_t &min_count, uint32_t &max_count) -{ - // Create reference - RawTensor ref_src(shape, dt_in); - - // Fill reference - library->fill_tensor_uniform(ref_src, 0); - - // Compute reference - ReferenceCPP::min_max_location(ref_src, min, max, min_loc, max_loc, min_count, max_count); -} KeyPointArray Reference::compute_reference_harris_corners(const TensorShape &shape, float threshold, float min_dist, float sensitivity, int32_t gradient_size, int32_t block_size, BorderMode border_mode, uint8_t constant_border_value) diff --git a/tests/validation_old/Reference.h b/tests/validation_old/Reference.h index e363bb2ecd..153986d82a 100644 --- a/tests/validation_old/Reference.h +++ b/tests/validation_old/Reference.h @@ -74,22 +74,6 @@ public: */ static KeyPointArray compute_reference_harris_corners(const TensorShape &shape, float threshold, float min_dist, float sensitivity, int32_t gradient_size, int32_t block_size, BorderMode border_mode, uint8_t constant_border_value); - /** Compute min max location. - * - * @param[in] shape Shape of the input tensors. - * @param[in] dt_in Data type of input tensor. - * @param[out] min Minimum value of tensor - * @param[out] max Maximum value of tensor - * @param[out] min_loc Array with locations of minimum values - * @param[out] max_loc Array with locations of maximum values - * @param[out] min_count Number of minimum values found - * @param[out] max_count Number of maximum values found - * - * @return Computed minimum, maximum values and their locations. - */ - static void compute_reference_min_max_location(const TensorShape &shape, DataType dt_in, void *min, void *max, IArray &min_loc, IArray &max_loc, - uint32_t &min_count, - uint32_t &max_count); /** Compute reference integral image. * * @param[in] shape Shape of the input and output tensors. diff --git a/tests/validation_old/ReferenceCPP.cpp b/tests/validation_old/ReferenceCPP.cpp index cca8997485..55aac59211 100644 --- a/tests/validation_old/ReferenceCPP.cpp +++ b/tests/validation_old/ReferenceCPP.cpp @@ -95,13 +95,6 @@ void ReferenceCPP::harris_corners(RawTensor &src, RawTensor &Gx, RawTensor &Gy, } } -// Minimum maximum location -void ReferenceCPP::min_max_location(const RawTensor &src, void *min, void *max, IArray &min_loc, IArray &max_loc, uint32_t &min_count, uint32_t &max_count) -{ - const TensorVariant s = TensorFactory::get_tensor(src); - boost::apply_visitor(tensor_visitors::min_max_location_visitor(min, max, min_loc, max_loc, min_count, max_count), s); -} - // Absolute difference void ReferenceCPP::absolute_difference(const RawTensor &src1, const RawTensor &src2, RawTensor &dst) { diff --git a/tests/validation_old/ReferenceCPP.h b/tests/validation_old/ReferenceCPP.h index 2f02afc30e..b04d5e331f 100644 --- a/tests/validation_old/ReferenceCPP.h +++ b/tests/validation_old/ReferenceCPP.h @@ -83,17 +83,6 @@ public: */ static void harris_corners(RawTensor &src, RawTensor &Gx, RawTensor &Gy, const RawTensor &candidates, const RawTensor &non_maxima, float threshold, float min_dist, float sensitivity, int32_t gradient_size, int32_t block_size, KeyPointArray &corners, BorderMode border_mode, uint8_t constant_border_value); - /** Function to compute the min max values and their location in a tensor. - * - * @param[in] src Input tensor. - * @param[out] min Minimum value of the tensor. - * @param[out] max Maximum value of the tensor - * @param[out] min_loc Array with locations of minimum values - * @param[out] max_loc Array with locations of maximum values - * @param[out] min_count Number of minimum values found - * @param[out] max_count Number of maximum values found - */ - static void min_max_location(const RawTensor &src, void *min, void *max, IArray &min_loc, IArray &max_loc, uint32_t &min_count, uint32_t &max_count); /** Function to compute the integral image of a tensor. * * @param[in] src Input tensor. diff --git a/tests/validation_old/TensorOperations.h b/tests/validation_old/TensorOperations.h index 04a79f0de3..af17ea8dfd 100644 --- a/tests/validation_old/TensorOperations.h +++ b/tests/validation_old/TensorOperations.h @@ -406,72 +406,6 @@ void harris_corners(Tensor &in, Tensor &Gx, Tensor &Gy, Tensor & } } -template -void compute_min_max(const Tensor &in, void *min, void *max) -{ - using type = typename std::conditional::value, float, int32_t>::type; - - // Set min and max to first pixel - type tmp_min = static_cast(in[0]); - type tmp_max = static_cast(in[0]); - - // Look for min and max values - for(int i = 1; i < in.num_elements(); ++i) - { - if(static_cast(in[i]) < tmp_min) - { - tmp_min = static_cast(in[i]); - } - if(static_cast(in[i]) > tmp_max) - { - tmp_max = static_cast(in[i]); - } - } - - *static_cast(min) = tmp_min; - *static_cast(max) = tmp_max; -} - -// Min max location -template -void min_max_location(const Tensor &in, void *min, void *max, IArray &min_loc, IArray &max_loc, uint32_t &min_count, uint32_t &max_count) -{ - const size_t width = in.shape().x(); - - compute_min_max(in, min, max); - - using type = typename std::conditional::value, float, int32_t>::type; - - type min_value = *static_cast(min); - type max_value = *static_cast(max); - - min_count = 0; - max_count = 0; - for(int i = 0; i < in.num_elements(); ++i) - { - if(static_cast(in[i]) == min_value) - { - Coordinates2D min_coord; - min_coord.x = static_cast(i % width); - min_coord.y = static_cast(i / width); - - min_loc.push_back(min_coord); - - min_count++; - } - if(static_cast(in[i]) == max_value) - { - Coordinates2D max_coord; - max_coord.x = static_cast(i % width); - max_coord.y = static_cast(i / width); - - max_loc.push_back(max_coord); - - max_count++; - } - } -} - // Integral Image void integral_image(const Tensor &in, Tensor &out) { diff --git a/tests/validation_old/TensorVisitors.h b/tests/validation_old/TensorVisitors.h index 8af035be08..30b552ae3c 100644 --- a/tests/validation_old/TensorVisitors.h +++ b/tests/validation_old/TensorVisitors.h @@ -46,28 +46,6 @@ namespace validation { namespace tensor_visitors { -// Min max location visitor -struct min_max_location_visitor : public boost::static_visitor<> -{ -public: - explicit min_max_location_visitor(void *min, void *max, IArray &min_loc, IArray &max_loc, uint32_t &min_count, uint32_t &max_count) - : _min(min), _max(max), _min_loc(min_loc), _max_loc(max_loc), _min_count(min_count), _max_count(max_count) - { - } - template - void operator()(const Tensor &in) const - { - tensor_operations::min_max_location(in, _min, _max, _min_loc, _max_loc, _min_count, _max_count); - } - -private: - void *_min; - void *_max; - IArray &_min_loc; - IArray &_max_loc; - uint32_t &_min_count; - uint32_t &_max_count; -}; // Absolute Difference visitor struct absolute_difference_visitor : public boost::static_visitor<> { diff --git a/tests/validation_old/Validation.h b/tests/validation_old/Validation.h index 4c8752b937..f0630c1d3e 100644 --- a/tests/validation_old/Validation.h +++ b/tests/validation_old/Validation.h @@ -141,47 +141,6 @@ void validate(std::vector classified_labels, std::vector::epsilon(), float tolerance_relative_error = 0.0001f); -/** Validate min max location. - * - * - All values should match - */ -template -void validate_min_max_loc(T min, T ref_min, T max, T ref_max, - IArray &min_loc, IArray &ref_min_loc, IArray &max_loc, IArray &ref_max_loc, - uint32_t min_count, uint32_t ref_min_count, uint32_t max_count, uint32_t ref_max_count) -{ - BOOST_TEST(min == ref_min); - BOOST_TEST(max == ref_max); - - BOOST_TEST(min_count == min_loc.num_values()); - BOOST_TEST(max_count == max_loc.num_values()); - BOOST_TEST(ref_min_count == ref_min_loc.num_values()); - BOOST_TEST(ref_max_count == ref_max_loc.num_values()); - - BOOST_TEST(min_count == ref_min_count); - BOOST_TEST(max_count == ref_max_count); - - for(uint32_t i = 0; i < min_count; i++) - { - Coordinates2D *same_coords = std::find_if(ref_min_loc.buffer(), ref_min_loc.buffer() + min_count, [&min_loc, i](Coordinates2D coord) - { - return coord.x == min_loc.at(i).x && coord.y == min_loc.at(i).y; - }); - - BOOST_TEST(same_coords != ref_min_loc.buffer() + min_count); - } - - for(uint32_t i = 0; i < max_count; i++) - { - Coordinates2D *same_coords = std::find_if(ref_max_loc.buffer(), ref_max_loc.buffer() + max_count, [&max_loc, i](Coordinates2D coord) - { - return coord.x == max_loc.at(i).x && coord.y == max_loc.at(i).y; - }); - - BOOST_TEST(same_coords != ref_max_loc.buffer() + max_count); - } -} - /** Validate KeyPoint arrays. * * - All values should match -- cgit v1.2.1