From 76b6ba0e88e608a5e5610c0647134e25dd46945a Mon Sep 17 00:00:00 2001 From: Ioana Ghiban Date: Wed, 17 Apr 2024 16:37:33 +0200 Subject: [PATCH] Implement and test min_max on NEON using float --- kleidicv/include/kleidicv/kleidicv.h | 4 ++++ kleidicv/src/analysis/min_max_api.cpp | 1 + kleidicv/src/analysis/min_max_neon.cpp | 5 +++-- test/api/test_min_max.cpp | 27 +++++++++++++------------- 4 files changed, 22 insertions(+), 15 deletions(-) diff --git a/kleidicv/include/kleidicv/kleidicv.h b/kleidicv/include/kleidicv/kleidicv.h index 19297bd0e..48283d67b 100644 --- a/kleidicv/include/kleidicv/kleidicv.h +++ b/kleidicv/include/kleidicv/kleidicv.h @@ -1202,6 +1202,10 @@ KLEIDICV_API_DECLARATION(kleidicv_min_max_s16, const int16_t *src, KLEIDICV_API_DECLARATION(kleidicv_min_max_s32, const int32_t *src, size_t src_stride, size_t width, size_t height, int32_t *min_value, int32_t *max_value); +/// @copydoc kleidicv_min_max_u8 +KLEIDICV_API_DECLARATION(kleidicv_min_max_f32, const float *src, + size_t src_stride, size_t width, size_t height, + float *min_value, float *max_value); /// Finds minimum and maximum element value across the source data, /// and returns their location in the source data as offset in bytes diff --git a/kleidicv/src/analysis/min_max_api.cpp b/kleidicv/src/analysis/min_max_api.cpp index 8136236aa..3fcdf995a 100644 --- a/kleidicv/src/analysis/min_max_api.cpp +++ b/kleidicv/src/analysis/min_max_api.cpp @@ -36,6 +36,7 @@ KLEIDICV_DEFINE_MINMAX_API(kleidicv_min_max_s8, int8_t); KLEIDICV_DEFINE_MINMAX_API(kleidicv_min_max_u16, uint16_t); KLEIDICV_DEFINE_MINMAX_API(kleidicv_min_max_s16, int16_t); KLEIDICV_DEFINE_MINMAX_API(kleidicv_min_max_s32, int32_t); +KLEIDICV_DEFINE_MINMAX_API(kleidicv_min_max_f32, float); #define KLEIDICV_DEFINE_MINMAXLOC_API(name, type) \ KLEIDICV_MULTIVERSION_C_API(name, &kleidicv::neon::min_max_loc, \ diff --git a/kleidicv/src/analysis/min_max_neon.cpp b/kleidicv/src/analysis/min_max_neon.cpp index ba1e26d8e..28bf0508b 100644 --- a/kleidicv/src/analysis/min_max_neon.cpp +++ b/kleidicv/src/analysis/min_max_neon.cpp @@ -17,9 +17,9 @@ class MinMax final : public UnrollTwice { MinMax() : vmin_(vdupq_n(std::numeric_limits::max())), - vmax_(vdupq_n(std::numeric_limits::min())), + vmax_(vdupq_n(std::numeric_limits::lowest())), min_(std::numeric_limits::max()), - max_(std::numeric_limits::min()) {} + max_(std::numeric_limits::lowest()) {} void vector_path(VectorType src) { vmin_ = vminq(vmin_, src); @@ -78,5 +78,6 @@ KLEIDICV_INSTANTIATE_TEMPLATE(uint8_t); KLEIDICV_INSTANTIATE_TEMPLATE(int16_t); KLEIDICV_INSTANTIATE_TEMPLATE(uint16_t); KLEIDICV_INSTANTIATE_TEMPLATE(int32_t); +KLEIDICV_INSTANTIATE_TEMPLATE(float); } // namespace kleidicv::neon diff --git a/test/api/test_min_max.cpp b/test/api/test_min_max.cpp index b5a0ed43c..3101099de 100644 --- a/test/api/test_min_max.cpp +++ b/test/api/test_min_max.cpp @@ -17,6 +17,7 @@ KLEIDICV_MIN_MAX(uint8_t, u8); KLEIDICV_MIN_MAX(int16_t, s16); KLEIDICV_MIN_MAX(uint16_t, u16); KLEIDICV_MIN_MAX(int32_t, s32); +KLEIDICV_MIN_MAX(float, f32); #define KLEIDICV_MIN_MAX_LOC(type, suffix) \ KLEIDICV_API(min_max_loc, kleidicv_min_max_loc_##suffix, type) @@ -28,9 +29,9 @@ class MinMaxTest { using ArrayType = test::Array2D; protected: - // Returns the minimum value for ElementType. - static constexpr ElementType min() { - return std::numeric_limits::min(); + // Returns the lowest value for ElementType. + static constexpr ElementType lowest() { + return std::numeric_limits::lowest(); } // Returns the maximum value for ElementType. @@ -81,8 +82,8 @@ class MinMaxTest { { {}, {}, {}, {}, - min(), - min(), min(), + lowest(), + lowest(), lowest(), 0, 0 }, { @@ -100,17 +101,17 @@ class MinMaxTest { 0, 0 }, { - {min()+10}, {}, + {lowest()+10}, {}, {max()}, {}, - min()+20, - min()+10, max(), + lowest()+20, + lowest()+10, max(), 0, stride() }, { - {}, {min()}, + {}, {lowest()}, {}, {max() - 10}, - min()+20, - min(), max()-10, + lowest()+20, + lowest(), max()-10, scalar_offset(), stride() + scalar_offset() }, { @@ -198,7 +199,7 @@ class MinMaxTest { *p_min = std::numeric_limits::max(); } if (p_max) { - *p_max = std::numeric_limits::min(); + *p_max = std::numeric_limits::lowest(); } EXPECT_EQ(KLEIDICV_OK, min_max()(source.data(), source.stride(), width(), @@ -295,7 +296,7 @@ template class MinMax : public testing::Test {}; using MinMaxElementTypes = - ::testing::Types; + ::testing::Types; TYPED_TEST_SUITE(MinMax, MinMaxElementTypes); TYPED_TEST(MinMax, API) { -- GitLab