From 3ec0b09cea24bae19cfffc5dc6480d7186d29215 Mon Sep 17 00:00:00 2001 From: Ioana Ghiban Date: Wed, 24 Apr 2024 08:44:15 +0200 Subject: [PATCH 1/4] Expose min_max in OpenCV HAL --- CHANGELOG.md | 1 + adapters/opencv/kleidicv_hal.cpp | 4 ++++ doc/functionality.md | 10 +++++----- doc/opencv.md | 1 + 4 files changed, 11 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f8d9b9d5f..5ee73a883 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,7 @@ This changelog aims to follow the guiding principles of - Gaussian Blur for 7x7 kernels. - Scale function for float. - Add, subtract, multiply & absdiff enabled in OpenCV HAL. +- MinMax enabled in OpenCV HAL, float version added. ### Fixed diff --git a/adapters/opencv/kleidicv_hal.cpp b/adapters/opencv/kleidicv_hal.cpp index 1ae98c562..4f3051f31 100644 --- a/adapters/opencv/kleidicv_hal.cpp +++ b/adapters/opencv/kleidicv_hal.cpp @@ -683,6 +683,10 @@ int min_max_idx(const uchar *src_data, size_t src_step, int width, int height, return convert_error(call_min_max(kleidicv_min_max_s32, src_data, src_step, width, height, minVal, maxVal)); + case CV_32F: + return convert_error(call_min_max(kleidicv_min_max_f32, src_data, + src_step, width, height, minVal, + maxVal)); default: return CV_HAL_ERROR_NOT_IMPLEMENTED; } diff --git a/doc/functionality.md b/doc/functionality.md index da7e88899..30bb835c2 100644 --- a/doc/functionality.md +++ b/doc/functionality.md @@ -50,11 +50,11 @@ See `doc/opencv.md` for details of the functionality available in OpenCV. | BGRA-YUV | x | ## Aggregate operations -| | s8 | u8 | s16 | u16 | s32 | u32 | s64 | -|-----------------|-----|-----|-----|-----|-----|-----|-----| -| Minmax | x | x | x | x | x | | | -| Minmax loc | | x | | | | | | -| Count non-zeros | | x | | | | | | +| | s8 | u8 | s16 | u16 | s32 | u32 | s64 | f32 | +|-----------------|-----|-----|-----|-----|-----|-----|-----|-----| +| Minmax | x | x | x | x | x | | | x | +| Minmax loc | | x | | | | | | | +| Count non-zeros | | x | | | | | | | ## Matrix transformation functions | | 8-bit | 16-bit | 32-bit | 64-bit | diff --git a/doc/opencv.md b/doc/opencv.md index 0257535bd..e8b38fa0a 100644 --- a/doc/opencv.md +++ b/doc/opencv.md @@ -185,6 +185,7 @@ Notes on parameters: + `CV_16S` + `CV_16U` + `CV_32S` + + `CV_32F` ### `convertTo` This function will scale given input using `scale` and `shift` if they are significant enough, and if `src_depth` equals `dst_depth`. Supported depths: -- GitLab From 6672bf150ba84cb778e1505f3be044fe93d36c56 Mon Sep 17 00:00:00 2001 From: Ioana Ghiban Date: Thu, 25 Apr 2024 10:05:59 +0200 Subject: [PATCH 2/4] Add min_max conformity tests --- conformity/opencv/CMakeLists.txt | 3 ++- conformity/opencv/tests.cpp | 14 ++++++++++---- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/conformity/opencv/CMakeLists.txt b/conformity/opencv/CMakeLists.txt index 360a57639..97103f97e 100644 --- a/conformity/opencv/CMakeLists.txt +++ b/conformity/opencv/CMakeLists.txt @@ -32,12 +32,12 @@ add_executable( tests.cpp test_binary_op.cpp test_gaussian_blur.cpp - test_min_max.cpp test_rgb2yuv.cpp test_sobel.cpp test_exp.cpp test_float_conv.cpp test_scale.cpp + test_min_max.cpp ) target_link_libraries( @@ -80,6 +80,7 @@ add_executable( test_exp.cpp test_float_conv.cpp test_scale.cpp + test_min_max.cpp ) target_link_libraries( diff --git a/conformity/opencv/tests.cpp b/conformity/opencv/tests.cpp index b7f3e38aa..a24a5ec55 100644 --- a/conformity/opencv/tests.cpp +++ b/conformity/opencv/tests.cpp @@ -29,10 +29,16 @@ static std::vector merge_tests( return all_tests; } -std::vector all_tests = - merge_tests({binary_op_tests_get, gaussian_blur_tests_get, - min_max_tests_get, rgb2yuv_tests_get, sobel_tests_get, - exp_tests_get, float_conversion_tests_get, scale_tests_get}); +std::vector all_tests = merge_tests({ + binary_op_tests_get, + gaussian_blur_tests_get, + rgb2yuv_tests_get, + sobel_tests_get, + exp_tests_get, + float_conversion_tests_get, + scale_tests_get, + min_max_tests_get, +}); #if MANAGER void fail_print_matrices(size_t height, size_t width, cv::Mat& input, -- GitLab From 17ec8596fc906f4e96663e1ac66e088fc0d10670 Mon Sep 17 00:00:00 2001 From: Ioana Ghiban Date: Fri, 26 Apr 2024 09:40:46 +0200 Subject: [PATCH 3/4] Fix min_max SVE/SME implementation --- kleidicv/src/analysis/min_max_sc.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/kleidicv/src/analysis/min_max_sc.h b/kleidicv/src/analysis/min_max_sc.h index 05e913155..a57e756fd 100644 --- a/kleidicv/src/analysis/min_max_sc.h +++ b/kleidicv/src/analysis/min_max_sc.h @@ -23,8 +23,8 @@ class MinMax final : public UnrollTwice { void vector_path(ContextType ctx, VectorType src) { auto pg = ctx.predicate(); - vmin_ = svmin_x(pg, vmin_, src); - vmax_ = svmax_x(pg, vmax_, src); + vmin_ = svmin_m(pg, vmin_, src); + vmax_ = svmax_m(pg, vmax_, src); } ScalarType get_min() const { -- GitLab From faf8078bf34e7fb2dcee67324cf9f59bd3bc70c0 Mon Sep 17 00:00:00 2001 From: Ioana Ghiban Date: Thu, 13 Jun 2024 21:51:10 +0200 Subject: [PATCH 4/4] Add MinMax benchmarks --- benchmark/benchmark.cpp | 31 +++++++++++++++++++++++++ scripts/benchmark/run_benchmarks_4K.sh | 7 ++++++ scripts/benchmark/run_benchmarks_FHD.sh | 7 ++++++ 3 files changed, 45 insertions(+) diff --git a/benchmark/benchmark.cpp b/benchmark/benchmark.cpp index 4ea11cca0..8155ebd94 100644 --- a/benchmark/benchmark.cpp +++ b/benchmark/benchmark.cpp @@ -156,6 +156,37 @@ BENCH_SCALE(scale_u8_generic, scale_u8, 1.234, 4.567, uint8_t); BENCH_SCALE(scale_f32_1, scale_f32, 1.0, 4.567, float); BENCH_SCALE(scale_f32_generic, scale_f32, 1.234, 4.567, float); +template +static void min_max(F f, benchmark::State& state) { + // Setup + std::vector src; + src.resize(image_width * image_height); + std::mt19937 generator; + std::generate(src.begin(), src.end(), generator); + + T min_value = 0, max_value = 0; + + for (auto _ : state) { + // This code gets benchmarked + auto unused = f(src.data(), image_width * sizeof(T), image_width, + image_height, &min_value, &max_value); + (void)unused; + } +} + +#define BENCH_MIN_MAX(name, type) \ + static void name(benchmark::State& state) { \ + min_max(kleidicv_##name, state); \ + } \ + BENCHMARK(name) + +BENCH_MIN_MAX(min_max_s8, int8_t); +BENCH_MIN_MAX(min_max_u8, uint8_t); +BENCH_MIN_MAX(min_max_s16, int16_t); +BENCH_MIN_MAX(min_max_u16, uint16_t); +BENCH_MIN_MAX(min_max_s32, int32_t); +BENCH_MIN_MAX(min_max_f32, float); + template static void resize_linear(F f, size_t scale_x, size_t scale_y, benchmark::State& state) { diff --git a/scripts/benchmark/run_benchmarks_4K.sh b/scripts/benchmark/run_benchmarks_4K.sh index 1c02d51db..09b0d1bc1 100755 --- a/scripts/benchmark/run_benchmarks_4K.sh +++ b/scripts/benchmark/run_benchmarks_4K.sh @@ -57,4 +57,11 @@ RES+=$(printf "\n$(${DEV_DIR}/perf_test_op.sh $CUSTOM_BUILD_SUFFIX $CPU $THERMAL RES+=$(printf "\n$(${DEV_DIR}/perf_test_op.sh $CUSTOM_BUILD_SUFFIX $CPU $THERMAL Scale_float_1.0 opencv_perf_core '*convertTo*' '(3840x2160, 32FC1, 32FC1, 1, 1, 4.567)')") RES+=$(printf "\n$(${DEV_DIR}/perf_test_op.sh $CUSTOM_BUILD_SUFFIX $CPU $THERMAL Scale_float opencv_perf_core '*convertTo*' '(3840x2160, 32FC1, 32FC1, 1, 1.234, 4.567)')") +RES=$(printf "${RES}\n$(${DEV_DIR}/perf_test_op.sh $CPU $THERMAL MinMax_S8_4K opencv_perf_core '*minMaxVals*' '(3840x2160, 8SC1)')") +RES=$(printf "${RES}\n$(${DEV_DIR}/perf_test_op.sh $CPU $THERMAL MinMax_U8_4K opencv_perf_core '*minMaxVals*' '(3840x2160, 8UC1)')") +RES=$(printf "${RES}\n$(${DEV_DIR}/perf_test_op.sh $CPU $THERMAL MinMax_S16_4K opencv_perf_core '*minMaxVals*' '(3840x2160, 16SC1)')") +RES=$(printf "${RES}\n$(${DEV_DIR}/perf_test_op.sh $CPU $THERMAL MinMax_U16_4K opencv_perf_core '*minMaxVals*' '(3840x2160, 16UC1)')") +RES=$(printf "${RES}\n$(${DEV_DIR}/perf_test_op.sh $CPU $THERMAL MinMax_S32_4K opencv_perf_core '*minMaxVals*' '(3840x2160, 32SC1)')") +RES=$(printf "${RES}\n$(${DEV_DIR}/perf_test_op.sh $CPU $THERMAL MinMax_F32_4K opencv_perf_core '*minMaxVals*' '(3840x2160, 32FC1)')") + echo "$RES" diff --git a/scripts/benchmark/run_benchmarks_FHD.sh b/scripts/benchmark/run_benchmarks_FHD.sh index c62f060aa..300e677b5 100755 --- a/scripts/benchmark/run_benchmarks_FHD.sh +++ b/scripts/benchmark/run_benchmarks_FHD.sh @@ -57,4 +57,11 @@ RES+=$(printf "\n$(${DEV_DIR}/perf_test_op.sh $CUSTOM_BUILD_SUFFIX $CPU $THERMAL RES+=$(printf "\n$(${DEV_DIR}/perf_test_op.sh $CUSTOM_BUILD_SUFFIX $CPU $THERMAL Scale_float_1.0 opencv_perf_core '*convertTo*' '(1920x1080, 32FC1, 32FC1, 1, 1, 4.567)')") RES+=$(printf "\n$(${DEV_DIR}/perf_test_op.sh $CUSTOM_BUILD_SUFFIX $CPU $THERMAL Scale_float opencv_perf_core '*convertTo*' '(1920x1080, 32FC1, 32FC1, 1, 1.234, 4.567)')") +RES=$(printf "${RES}\n$(${DEV_DIR}/perf_test_op.sh $CPU $THERMAL MinMax_S8_FHD opencv_perf_core '*minMaxVals*' '(1920x1080, 8SC1)')") +RES=$(printf "${RES}\n$(${DEV_DIR}/perf_test_op.sh $CPU $THERMAL MinMax_U8_FHD opencv_perf_core '*minMaxVals*' '(1920x1080, 8UC1)')") +RES=$(printf "${RES}\n$(${DEV_DIR}/perf_test_op.sh $CPU $THERMAL MinMax_S16_FHD opencv_perf_core '*minMaxVals*' '(1920x1080, 16SC1)')") +RES=$(printf "${RES}\n$(${DEV_DIR}/perf_test_op.sh $CPU $THERMAL MinMax_U16_FHD opencv_perf_core '*minMaxVals*' '(1920x1080, 16UC1)')") +RES=$(printf "${RES}\n$(${DEV_DIR}/perf_test_op.sh $CPU $THERMAL MinMax_S32_FHD opencv_perf_core '*minMaxVals*' '(1920x1080, 32SC1)')") +RES=$(printf "${RES}\n$(${DEV_DIR}/perf_test_op.sh $CPU $THERMAL MinMax_F32_FHD opencv_perf_core '*minMaxVals*' '(1920x1080, 32FC1)')") + echo "$RES" -- GitLab