From ef4b4ae784f7533ed6d9e7b51827a894c32ed48e Mon Sep 17 00:00:00 2001 From: Michele Di Giorgio Date: Tue, 4 Jul 2017 17:19:43 +0100 Subject: COMPMID-438: Add support for floating point Min-Max Location layer. Change-Id: I84ae564a40fc7320a6f94a84d53906ba51404f51 Reviewed-on: http://mpd-gerrit.cambridge.arm.com/79797 Reviewed-by: Anthony Barbier Tested-by: Kaizen --- tests/validation/CL/MinMaxLocation.cpp | 133 ++++++++++++++++++++++++++----- tests/validation/NEON/MinMaxLocation.cpp | 75 ++++++++++++----- tests/validation/Reference.cpp | 2 +- tests/validation/Reference.h | 2 +- tests/validation/ReferenceCPP.cpp | 2 +- tests/validation/ReferenceCPP.h | 2 +- tests/validation/TensorOperations.h | 46 +++++++---- tests/validation/TensorVisitors.h | 6 +- tests/validation/Validation.cpp | 37 --------- tests/validation/Validation.h | 36 ++++++++- 10 files changed, 241 insertions(+), 100 deletions(-) (limited to 'tests') diff --git a/tests/validation/CL/MinMaxLocation.cpp b/tests/validation/CL/MinMaxLocation.cpp index 0646ad9bbf..5f8be433cd 100644 --- a/tests/validation/CL/MinMaxLocation.cpp +++ b/tests/validation/CL/MinMaxLocation.cpp @@ -50,22 +50,27 @@ 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. -* -* @return Computed output tensor. -*/ -void compute_min_max_location(const TensorShape &shape, DataType dt_in, int32_t &min, int32_t &max, + * + * @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); - src.info()->set_format((dt_in == DataType::U8) ? Format::U8 : Format::S16); // 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); + min_max_loc.configure(&src, min, max, &min_loc, &max_loc, &min_count, &max_count); // Allocate tensors src.allocator()->allocate(); @@ -141,13 +146,13 @@ BOOST_DATA_TEST_CASE(RunSmall, Small2DShapes(), 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_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); + 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(); @@ -181,13 +186,13 @@ BOOST_DATA_TEST_CASE(RunLarge, Large2DShapes(), 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_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); + 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(); @@ -234,13 +239,13 @@ BOOST_DATA_TEST_CASE(RunSmall, Small2DShapes(), 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_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); + 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(); @@ -274,13 +279,105 @@ BOOST_DATA_TEST_CASE(RunLarge, Large2DShapes(), 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_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::S16, ref_min, ref_max, ref_min_loc, ref_max_loc, ref_min_count, ref_max_count); + 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(); @@ -297,4 +394,4 @@ BOOST_AUTO_TEST_SUITE_END() BOOST_AUTO_TEST_SUITE_END() BOOST_AUTO_TEST_SUITE_END() -#endif /* DOXYGEN_SKIP_THIS */ \ No newline at end of file +#endif /* DOXYGEN_SKIP_THIS */ diff --git a/tests/validation/NEON/MinMaxLocation.cpp b/tests/validation/NEON/MinMaxLocation.cpp index b1fa8cd7a9..a467172550 100644 --- a/tests/validation/NEON/MinMaxLocation.cpp +++ b/tests/validation/NEON/MinMaxLocation.cpp @@ -51,29 +51,28 @@ 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, int32_t &min, int32_t &max, + * + * @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); - src.info()->set_format((dt_in == DataType::U8) ? Format::U8 : Format::S16); // 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); + min_max_loc.configure(&src, min, max, &min_loc, &max_loc, &min_count, &max_count); // Allocate tensors src.allocator()->allocate(); @@ -117,6 +116,7 @@ void validate_configuration(const Tensor &src, TensorShape shape) 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) @@ -148,10 +148,10 @@ BOOST_DATA_TEST_CASE(RunSmall, Small2DShapes() * boost::unit_test::data::make({ uint32_t ref_max_count; // Compute function - compute_min_max_location(shape, dt, min, max, min_loc, max_loc, min_count, max_count); + 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); + 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); @@ -177,15 +177,48 @@ BOOST_DATA_TEST_CASE(RunLarge, Large2DShapes() * boost::unit_test::data::make({ uint32_t ref_max_count; // Compute function - compute_min_max_location(shape, dt, min, max, min_loc, max_loc, min_count, max_count); + 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); + 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 */ \ No newline at end of file +#endif /* DOXYGEN_SKIP_THIS */ diff --git a/tests/validation/Reference.cpp b/tests/validation/Reference.cpp index e9ddea78cb..f9052f1dba 100644 --- a/tests/validation/Reference.cpp +++ b/tests/validation/Reference.cpp @@ -71,7 +71,7 @@ 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, int32_t &min, int32_t &max, IArray &min_loc, IArray &max_loc, +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 diff --git a/tests/validation/Reference.h b/tests/validation/Reference.h index 778e7b0b2b..eeaa55c739 100644 --- a/tests/validation/Reference.h +++ b/tests/validation/Reference.h @@ -72,7 +72,7 @@ public: * * @return Computed minimum, maximum values and their locations. */ - static void compute_reference_min_max_location(const TensorShape &shape, DataType dt_in, int32_t &min, int32_t &max, IArray &min_loc, IArray &max_loc, + 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 mean and standard deviation. diff --git a/tests/validation/ReferenceCPP.cpp b/tests/validation/ReferenceCPP.cpp index 13f4b90a82..81ec60d5b9 100644 --- a/tests/validation/ReferenceCPP.cpp +++ b/tests/validation/ReferenceCPP.cpp @@ -71,7 +71,7 @@ void ReferenceCPP::sobel_5x5(RawTensor &src, RawTensor &dst_x, RawTensor &dst_y, } // Minimum maximum location -void ReferenceCPP::min_max_location(const RawTensor &src, int32_t &min, int32_t &max, IArray &min_loc, IArray &max_loc, uint32_t &min_count, uint32_t &max_count) +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); diff --git a/tests/validation/ReferenceCPP.h b/tests/validation/ReferenceCPP.h index 3f5e4aeaf5..97e573cfa2 100644 --- a/tests/validation/ReferenceCPP.h +++ b/tests/validation/ReferenceCPP.h @@ -74,7 +74,7 @@ public: * @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, int32_t &min, int32_t &max, IArray &min_loc, IArray &max_loc, uint32_t &min_count, uint32_t &max_count); + 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 mean and standard deviation of a tensor. * * @param[in] src Input tensor. diff --git a/tests/validation/TensorOperations.h b/tests/validation/TensorOperations.h index a5039a4641..b472e3d5cf 100644 --- a/tests/validation/TensorOperations.h +++ b/tests/validation/TensorOperations.h @@ -305,34 +305,50 @@ void sobel_5x5(Tensor &in, Tensor &out_x, Tensor &out_y, BorderMode } } -// Min max location -template -void min_max_location(const Tensor &in, int32_t &min, int32_t &max, IArray &min_loc, IArray &max_loc, uint32_t &min_count, uint32_t &max_count) +template +void compute_min_max(const Tensor &in, void *min, void *max) { - // Set min and max to first pixel - min = in[0]; - max = in[0]; - min_count = 0; - max_count = 0; + using type = typename std::conditional::value, float, int32_t>::type; - const size_t width = in.shape().x(); + // 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]) < min) + if(static_cast(in[i]) < tmp_min) { - min = in[i]; + tmp_min = static_cast(in[i]); } - if(static_cast(in[i]) > max) + if(static_cast(in[i]) > tmp_max) { - max = in[i]; + 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) + if(static_cast(in[i]) == min_value) { Coordinates2D min_coord; min_coord.x = static_cast(i % width); @@ -342,7 +358,7 @@ void min_max_location(const Tensor &in, int32_t &min, int32_t &max, IArray(in[i]) == max) + if(static_cast(in[i]) == max_value) { Coordinates2D max_coord; max_coord.x = static_cast(i % width); diff --git a/tests/validation/TensorVisitors.h b/tests/validation/TensorVisitors.h index fa9c3ecbb8..44ae6f13e8 100644 --- a/tests/validation/TensorVisitors.h +++ b/tests/validation/TensorVisitors.h @@ -49,7 +49,7 @@ namespace tensor_visitors struct min_max_location_visitor : public boost::static_visitor<> { public: - explicit min_max_location_visitor(int32_t &min, int32_t &max, IArray &min_loc, IArray &max_loc, uint32_t &min_count, uint32_t &max_count) + 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) { } @@ -60,8 +60,8 @@ public: } private: - int32_t &_min; - int32_t &_max; + void *_min; + void *_max; IArray &_min_loc; IArray &_max_loc; uint32_t &_min_count; diff --git a/tests/validation/Validation.cpp b/tests/validation/Validation.cpp index a13eeb0b85..eac4105b21 100644 --- a/tests/validation/Validation.cpp +++ b/tests/validation/Validation.cpp @@ -403,43 +403,6 @@ void validate(float target, float ref, float tolerance_abs_error, float toleranc BOOST_TEST_INFO("target = " << std::setprecision(5) << target); BOOST_TEST(equal); } - -void validate_min_max_loc(int32_t min, int32_t ref_min, int32_t max, int32_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); - } -} - } // namespace validation } // namespace test } // namespace arm_compute diff --git a/tests/validation/Validation.h b/tests/validation/Validation.h index 217ec63658..66bb2be2ca 100644 --- a/tests/validation/Validation.h +++ b/tests/validation/Validation.h @@ -133,10 +133,42 @@ void validate(float target, float ref, float tolerance_abs_error = std::numeric_ * * - All values should match */ -void validate_min_max_loc(int32_t min, int32_t ref_min, int32_t max, int32_t ref_max, +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); + 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); + } +} } // namespace validation } // namespace test } // namespace arm_compute -- cgit v1.2.1