From 8c91a91cba20225e724196823895ff4eed961d5a Mon Sep 17 00:00:00 2001 From: Mark Horvath Date: Wed, 7 Aug 2024 09:13:27 +0200 Subject: [PATCH] Make possible to choose SIMD backend for GRAY2RGB --- adapters/opencv/kleidicv_hal.cpp | 3 +- benchmark/benchmark.cpp | 2 +- kleidicv/include/kleidicv/ctypes.h | 16 +++++++++++ kleidicv/include/kleidicv/kleidicv.h | 8 ++++-- kleidicv/src/conversions/gray_to_rgb_api.cpp | 29 +++++++++++++++++++- test/api/test_rgb_and_gray.cpp | 13 +++++++-- 6 files changed, 62 insertions(+), 9 deletions(-) diff --git a/adapters/opencv/kleidicv_hal.cpp b/adapters/opencv/kleidicv_hal.cpp index df03a09f5..618cffcff 100644 --- a/adapters/opencv/kleidicv_hal.cpp +++ b/adapters/opencv/kleidicv_hal.cpp @@ -83,7 +83,8 @@ int gray_to_bgr(const uchar *src_data, size_t src_step, uchar *dst_data, if (dcn == 3) { return convert_error(kleidicv_gray_to_rgb_u8( reinterpret_cast(src_data), src_step, - reinterpret_cast(dst_data), dst_step, width, height)); + reinterpret_cast(dst_data), dst_step, width, height, + KLEIDICV_BACKEND_AUTO)); } return convert_error(kleidicv_gray_to_rgba_u8( reinterpret_cast(src_data), src_step, diff --git a/benchmark/benchmark.cpp b/benchmark/benchmark.cpp index 3b881ccd3..95bb46942 100644 --- a/benchmark/benchmark.cpp +++ b/benchmark/benchmark.cpp @@ -119,7 +119,7 @@ BENCH_UNARY_OP_DIFFERENT_CHANNEL_NUMBER(rgba_to_yuv_u8, 4, 3, uint8_t); BENCH_UNARY_OP_DIFFERENT_CHANNEL_NUMBER(bgr_to_yuv_u8, 3, 3, uint8_t); BENCH_UNARY_OP_DIFFERENT_CHANNEL_NUMBER(bgra_to_yuv_u8, 4, 3, uint8_t); -BENCH_UNARY_OP_DIFFERENT_CHANNEL_NUMBER(gray_to_rgb_u8, 1, 3, uint8_t); +// BENCH_UNARY_OP_DIFFERENT_CHANNEL_NUMBER(gray_to_rgb_u8, 1, 3, uint8_t); BENCH_UNARY_OP_DIFFERENT_CHANNEL_NUMBER(gray_to_rgba_u8, 1, 4, uint8_t); BENCH_UNARY_OP_DIFFERENT_CHANNEL_NUMBER(rgb_to_bgr_u8, 3, 3, uint8_t); diff --git a/kleidicv/include/kleidicv/ctypes.h b/kleidicv/include/kleidicv/ctypes.h index 0349db0a4..5d9d6cc8e 100644 --- a/kleidicv/include/kleidicv/ctypes.h +++ b/kleidicv/include/kleidicv/ctypes.h @@ -87,6 +87,22 @@ typedef enum { KLEIDICV_BORDER_TYPE_NONE, } kleidicv_border_type_t; +/// KleidiCV backends +typedef enum { + /// Let KleidiCV choose the backend. + KLEIDICV_BACKEND_AUTO, + /// NEON backend. + KLEIDICV_BACKEND_NEON, +#ifdef KLEIDICV_HAVE_SVE2 + /// SVE2 backend. + KLEIDICV_BACKEND_SVE2, +#endif +#ifdef KLEIDICV_HAVE_SME2 + /// SME2 backend. + KLEIDICV_BACKEND_SME2, +#endif +} kleidicv_backend_t; + /// Internal structure where morphology operations store their state typedef struct kleidicv_morphology_context_t_ kleidicv_morphology_context_t; diff --git a/kleidicv/include/kleidicv/kleidicv.h b/kleidicv/include/kleidicv/kleidicv.h index 54d8cc4bc..c4f236d22 100644 --- a/kleidicv/include/kleidicv/kleidicv.h +++ b/kleidicv/include/kleidicv/kleidicv.h @@ -313,10 +313,12 @@ KLEIDICV_BINARY_OP(kleidicv_bitwise_and, uint8_t); /// images. /// @param width Number of pixels in a row. /// @param height Number of rows in the data. +/// @param backend SIMD backend to be used. /// -KLEIDICV_API_DECLARATION(kleidicv_gray_to_rgb_u8, const uint8_t *src, - size_t src_stride, uint8_t *dst, size_t dst_stride, - size_t width, size_t height); +kleidicv_error_t kleidicv_gray_to_rgb_u8(const uint8_t *src, size_t src_stride, + uint8_t *dst, size_t dst_stride, + size_t width, size_t height, + kleidicv_backend_t backend); /// Converts a grayscale image to RGBA. All channels are 8-bit wide. /// diff --git a/kleidicv/src/conversions/gray_to_rgb_api.cpp b/kleidicv/src/conversions/gray_to_rgb_api.cpp index 6d40ef5a4..dd4362963 100644 --- a/kleidicv/src/conversions/gray_to_rgb_api.cpp +++ b/kleidicv/src/conversions/gray_to_rgb_api.cpp @@ -12,5 +12,32 @@ KLEIDICV_SVE2_IMPL_IF(&kleidicv::sve2::partialname), \ &kleidicv::sme2::partialname) -KLEIDICV_DEFINE_C_API(kleidicv_gray_to_rgb_u8, gray_to_rgb_u8); +KLEIDICV_DEFINE_C_API(kleidicv_auto_backend_gray_to_rgb_u8, gray_to_rgb_u8); KLEIDICV_DEFINE_C_API(kleidicv_gray_to_rgba_u8, gray_to_rgba_u8); + +kleidicv_error_t kleidicv_gray_to_rgb_u8(const uint8_t *src, size_t src_stride, + uint8_t *dst, size_t dst_stride, + size_t width, size_t height, + kleidicv_backend_t backend) { + switch (backend) { + case KLEIDICV_BACKEND_AUTO: + return kleidicv_auto_backend_gray_to_rgb_u8(src, src_stride, dst, + dst_stride, width, height); + case KLEIDICV_BACKEND_NEON: + return kleidicv::neon::gray_to_rgb_u8(src, src_stride, dst, dst_stride, + width, height); +#ifdef KLEIDICV_HAVE_SVE2 + case KLEIDICV_BACKEND_SVE2: + return kleidicv::sve2::gray_to_rgb_u8(src, src_stride, dst, dst_stride, + width, height); +#endif + +#ifdef KLEIDICV_HAVE_SME2 + case KLEIDICV_BACKEND_SME2: + return kleidicv::sme2::gray_to_rgb_u8(src, src_stride, dst, dst_stride, + width, height); +#endif + default: + return KLEIDICV_ERROR_NOT_IMPLEMENTED; + } +} diff --git a/test/api/test_rgb_and_gray.cpp b/test/api/test_rgb_and_gray.cpp index cdffcea90..da1e559e9 100644 --- a/test/api/test_rgb_and_gray.cpp +++ b/test/api/test_rgb_and_gray.cpp @@ -166,12 +166,19 @@ class ColorTest final { bool swapBlue_; }; +static kleidicv_error_t kleidicv_gray_to_rgb_u8_wrapper( + const uint8_t *src, size_t src_stride, uint8_t *dst, size_t dst_stride, + size_t width, size_t height) { + return kleidicv_gray_to_rgb_u8(src, src_stride, dst, dst_stride, width, + height, KLEIDICV_BACKEND_AUTO); +} + TEST(GRAY2, RGB) { - GrayTest{false}.execute_test(kleidicv_gray_to_rgb_u8); - GrayTest{false}.with_padding(1).execute_test(kleidicv_gray_to_rgb_u8); + GrayTest{false}.execute_test(kleidicv_gray_to_rgb_u8_wrapper); + GrayTest{false}.with_padding(1).execute_test(kleidicv_gray_to_rgb_u8_wrapper); GrayTest{false} .with_width(2 * test::Options::vector_lanes()) - .execute_test(kleidicv_gray_to_rgb_u8); + .execute_test(kleidicv_gray_to_rgb_u8_wrapper); } TEST(GRAY2, RGBA) { -- GitLab