From 143355fb7f4b2e252c359d50978050a5b98e3f7f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Igor=20Podgain=C3=B5i?= Date: Fri, 8 Mar 2024 14:45:28 +0100 Subject: [PATCH 1/7] Only use SVE2 and SME2 on Linux and Android --- intrinsiccv/CMakeLists.txt | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/intrinsiccv/CMakeLists.txt b/intrinsiccv/CMakeLists.txt index 188b61fa3..c0caf9a7b 100644 --- a/intrinsiccv/CMakeLists.txt +++ b/intrinsiccv/CMakeLists.txt @@ -8,9 +8,15 @@ project("IntrinsicCV") include(CheckCXXCompilerFlag) -option(INTRINSICCV_ENABLE_SVE2 "Explicitly enables or disables SVE2 code paths for all supported algorithms" OFF) -option(INTRINSICCV_ENABLE_SVE2_SELECTIVELY "Explicitly enables or disables SVE2 code paths for selected algorithms" ON) -option(INTRINSICCV_ENABLE_SME2 "Explicitly enables or disables SME2 code paths for all supported algorithms" ON) +if (CMAKE_SYSTEM_NAME MATCHES "^(Linux|Android)$") + option(INTRINSICCV_ENABLE_SVE2 "Explicitly enables or disables SVE2 code paths for all supported algorithms" OFF) + option(INTRINSICCV_ENABLE_SVE2_SELECTIVELY "Explicitly enables or disables SVE2 code paths for selected algorithms" ON) + option(INTRINSICCV_ENABLE_SME2 "Explicitly enables or disables SME2 code paths for all supported algorithms" ON) +else() + set(INTRINSICCV_ENABLE_SVE2 OFF) + set(INTRINSICCV_ENABLE_SVE2_SELECTIVELY OFF) + set(INTRINSICCV_ENABLE_SME2 OFF) +endif() option(INTRINSICCV_CHECK_BANNED_FUNCTIONS "Check source for deprecated or obsolescent functions" OFF) option(INTRINSICCV_ASSUME_128BIT_SVE2 "Internal - If turned ON 128-bit SVE2 vector length is assumed" OFF) option(INTRINSICCV_PREFER_INTERLEAVING_LOAD_STORE "Internal - If turned ON interleaving loads and stores are preferred instead of continuous loads and stores" OFF) -- GitLab From c39c29b9328d23ec6fd73ea773899d4a8a30076b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Igor=20Podgain=C3=B5i?= Date: Mon, 11 Mar 2024 12:55:40 +0100 Subject: [PATCH 2/7] Use function pointers instead of ifuncs --- intrinsiccv/include/intrinsiccv/config.h.in | 4 - intrinsiccv/include/intrinsiccv/dispatch.h | 47 ++- intrinsiccv/include/intrinsiccv/intrinsiccv.h | 296 +++++++++--------- .../src/analysis/count_nonzeros_neon.cpp | 26 +- .../src/conversions/rgb_to_rgb_api.cpp | 20 +- test/api/test_morphology.cpp | 2 +- test/framework/utils.h | 2 +- 7 files changed, 191 insertions(+), 206 deletions(-) diff --git a/intrinsiccv/include/intrinsiccv/config.h.in b/intrinsiccv/include/intrinsiccv/config.h.in index a92ddfc1a..581230f39 100644 --- a/intrinsiccv/include/intrinsiccv/config.h.in +++ b/intrinsiccv/include/intrinsiccv/config.h.in @@ -53,7 +53,6 @@ #define INTRINSICCV_STREAMING_COMPATIBLE #endif -#define INTRINSICCV_ATTR_IFUNC(resolver) __attribute__((ifunc(resolver))) #define INTRINSICCV_ATTR_SECTION(section_to_use) \ __attribute__((section(section_to_use))) #define INTRINSICCV_ATTR_NOINLINE __attribute__((noinline)) @@ -62,9 +61,6 @@ #define INTRINSICCV_LIKELY(cond) __builtin_expect((cond), 1) #define INTRINSICCV_UNLIKELY(cond) __builtin_expect((cond), 0) -#define INTRINSICCV_IFUNC_RESOLVER \ - INTRINSICCV_ATTR_SECTION(".text.ifunc_resolvers") - #ifdef __clang__ #define INTRINSICCV_FORCE_LOOP_UNROLL _Pragma("clang loop unroll(full)") #else diff --git a/intrinsiccv/include/intrinsiccv/dispatch.h b/intrinsiccv/include/intrinsiccv/dispatch.h index 6c5d91675..26058bec5 100644 --- a/intrinsiccv/include/intrinsiccv/dispatch.h +++ b/intrinsiccv/include/intrinsiccv/dispatch.h @@ -5,11 +5,12 @@ #ifndef INTRINSICCV_DISPATCH_H #define INTRINSICCV_DISPATCH_H +#include + #include #include #include "intrinsiccv/config.h" -#include "sys/ifunc.h" namespace intrinsiccv { @@ -20,9 +21,8 @@ struct HwCaps final { HwCapTy hwcap2; }; -static inline HwCaps make_hwcaps(HwCapTy hwcap, __ifunc_arg_t *arg) { - HwCapTy hwcap2 = hwcap & _IFUNC_ARG_HWCAP ? arg->_hwcap2 : 0; - return HwCaps{hwcap, hwcap2}; +static inline HwCaps get_hwcaps() { + return HwCaps{getauxval(AT_HWCAP), getauxval(AT_HWCAP2)}; } static inline bool hwcaps_has_sve2(HwCaps hwcaps) { @@ -43,44 +43,39 @@ static inline bool hwcaps_has_sme2(HwCaps hwcaps) { #endif #ifdef INTRINSICCV_HAVE_SVE2 -#define INTRINSICCV_SVE2_RESOLVE_IFUNC(sve2_impl) \ +#define INTRINSICCV_SVE2_RESOLVE(sve2_impl) \ if (!std::is_null_pointer_v && \ hwcaps_has_sve2(hwcaps)) { \ return sve2_impl; \ } #else -#define INTRINSICCV_SVE2_RESOLVE_IFUNC(sve2_impl) +#define INTRINSICCV_SVE2_RESOLVE(sve2_impl) #endif #ifdef INTRINSICCV_HAVE_SME2 -#define INTRINSICCV_SME2_RESOLVE_IFUNC(sme2_impl) \ +#define INTRINSICCV_SME2_RESOLVE(sme2_impl) \ if (!std::is_null_pointer_v && \ hwcaps_has_sme2(hwcaps)) { \ return sme2_impl; \ } #else -#define INTRINSICCV_SME2_RESOLVE_IFUNC(sme2_impl) +#define INTRINSICCV_SME2_RESOLVE(sme2_impl) #endif -// Creates a multiversioned C API with an ifunc resolver for it -#define INTRINSICCV_MULTIVERSION_C_API(api_name, neon_impl, sve2_impl, \ - sme2_impl, ...) \ - typedef intrinsiccv_error_t (*api_name##_function_type)(__VA_ARGS__); \ - \ - extern "C" INTRINSICCV_IFUNC_RESOLVER api_name##_function_type \ - api_name##_ifunc_resolver(HwCapTy, __ifunc_arg_t *arg); \ - \ - extern "C" api_name##_function_type api_name##_ifunc_resolver( \ - HwCapTy hwcap, __ifunc_arg_t *arg) { \ - [[maybe_unused]] HwCaps hwcaps = make_hwcaps(hwcap, arg); \ - INTRINSICCV_SME2_RESOLVE_IFUNC(sme2_impl); \ - INTRINSICCV_SVE2_RESOLVE_IFUNC(sve2_impl); \ - return neon_impl; \ - } \ - \ - extern "C" intrinsiccv_error_t api_name(__VA_ARGS__) \ - INTRINSICCV_ATTR_IFUNC(#api_name "_ifunc_resolver") +// Creates a multiversioned C API with a resolver for it +#define INTRINSICCV_MULTIVERSION_C_API(api_name, neon_impl, sve2_impl, \ + sme2_impl, ...) \ + decltype(neon_impl) *api_name##_resolver() { \ + [[maybe_unused]] HwCaps hwcaps = get_hwcaps(); \ + INTRINSICCV_SME2_RESOLVE(sme2_impl); \ + INTRINSICCV_SVE2_RESOLVE(sve2_impl); \ + return neon_impl; \ + } \ + \ + extern "C" { \ + decltype(neon_impl) *api_name = api_name##_resolver(); \ + } } // namespace intrinsiccv diff --git a/intrinsiccv/include/intrinsiccv/intrinsiccv.h b/intrinsiccv/include/intrinsiccv/intrinsiccv.h index c691afc7c..d594797f1 100644 --- a/intrinsiccv/include/intrinsiccv/intrinsiccv.h +++ b/intrinsiccv/include/intrinsiccv/intrinsiccv.h @@ -48,16 +48,20 @@ extern "C" { #endif // __cplusplus -#define INTRINSICCV_BINARY_OP(name, type) \ - intrinsiccv_error_t name(const type *src_a, size_t src_a_stride, \ - const type *src_b, size_t src_b_stride, type *dst, \ - size_t dst_stride, size_t width, size_t height) +#define INTRINSICCV_API_DECLARATION(name, ...) \ + extern intrinsiccv_error_t (*name)(__VA_ARGS__) -#define INTRINSICCV_BINARY_OP_SCALE(name, type, scaletype) \ - intrinsiccv_error_t name(const type *src_a, size_t src_a_stride, \ - const type *src_b, size_t src_b_stride, type *dst, \ - size_t dst_stride, size_t width, size_t height, \ - scaletype scale) +#define INTRINSICCV_BINARY_OP(name, type) \ + INTRINSICCV_API_DECLARATION(name, const type *src_a, size_t src_a_stride, \ + const type *src_b, size_t src_b_stride, \ + type *dst, size_t dst_stride, size_t width, \ + size_t height) + +#define INTRINSICCV_BINARY_OP_SCALE(name, type, scaletype) \ + INTRINSICCV_API_DECLARATION(name, const type *src_a, size_t src_a_stride, \ + const type *src_b, size_t src_b_stride, \ + type *dst, size_t dst_stride, size_t width, \ + size_t height, scaletype scale) /// Adds the values of the corresponding elements in `src_a` and `src_b`, and /// puts the result into `dst`. @@ -255,10 +259,11 @@ INTRINSICCV_BINARY_OP_SCALE(intrinsiccv_saturating_multiply_s32, int32_t, /// @param threshold The value that the elements of the addition result /// are compared to. /// -intrinsiccv_error_t intrinsiccv_saturating_add_abs_with_threshold_s16( - const int16_t *src_a, size_t src_a_stride, const int16_t *src_b, - size_t src_b_stride, int16_t *dst, size_t dst_stride, size_t width, - size_t height, int16_t threshold); +INTRINSICCV_API_DECLARATION(intrinsiccv_saturating_add_abs_with_threshold_s16, + const int16_t *src_a, size_t src_a_stride, + const int16_t *src_b, size_t src_b_stride, + int16_t *dst, size_t dst_stride, size_t width, + size_t height, int16_t threshold); /// Converts a grayscale image to RGB. All channels are 8-bit wide. /// @@ -281,10 +286,9 @@ intrinsiccv_error_t intrinsiccv_saturating_add_abs_with_threshold_s16( /// @param width Number of pixels in a row. /// @param height Number of rows in the data. /// -intrinsiccv_error_t intrinsiccv_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); +INTRINSICCV_API_DECLARATION(intrinsiccv_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); /// Converts a grayscale image to RGBA. All channels are 8-bit wide. /// @@ -307,10 +311,9 @@ intrinsiccv_error_t intrinsiccv_gray_to_rgb_u8(const uint8_t *src, /// @param width Number of pixels in a row. /// @param height Number of rows in the data. /// -intrinsiccv_error_t intrinsiccv_gray_to_rgba_u8(const uint8_t *src, - size_t src_stride, uint8_t *dst, - size_t dst_stride, size_t width, - size_t height); +INTRINSICCV_API_DECLARATION(intrinsiccv_gray_to_rgba_u8, const uint8_t *src, + size_t src_stride, uint8_t *dst, size_t dst_stride, + size_t width, size_t height); /// Converts an RGB image to BGR. All channels are 8-bit wide. /// @@ -333,10 +336,9 @@ intrinsiccv_error_t intrinsiccv_gray_to_rgba_u8(const uint8_t *src, /// @param width Number of pixels in a row. /// @param height Number of rows in the data. /// -intrinsiccv_error_t intrinsiccv_rgb_to_bgr_u8(const uint8_t *src, - size_t src_stride, uint8_t *dst, - size_t dst_stride, size_t width, - size_t height); +INTRINSICCV_API_DECLARATION(intrinsiccv_rgb_to_bgr_u8, const uint8_t *src, + size_t src_stride, uint8_t *dst, size_t dst_stride, + size_t width, size_t height); /// Copies a source RBG image to destination buffer. /// All channels are 8-bit wide. @@ -355,10 +357,9 @@ intrinsiccv_error_t intrinsiccv_rgb_to_bgr_u8(const uint8_t *src, /// @param width Number of pixels in a row. /// @param height Number of rows in the data. /// -intrinsiccv_error_t intrinsiccv_rgb_to_rgb_u8(const uint8_t *src, - size_t src_stride, uint8_t *dst, - size_t dst_stride, size_t width, - size_t height); +INTRINSICCV_API_DECLARATION(intrinsiccv_rgb_to_rgb_u8, const uint8_t *src, + size_t src_stride, uint8_t *dst, size_t dst_stride, + size_t width, size_t height); /// Converts an RGBA image to BGRA. All channels are 8-bit wide. /// @@ -381,10 +382,9 @@ intrinsiccv_error_t intrinsiccv_rgb_to_rgb_u8(const uint8_t *src, /// @param width Number of pixels in a row. /// @param height Number of rows in the data. /// -intrinsiccv_error_t intrinsiccv_rgba_to_bgra_u8(const uint8_t *src, - size_t src_stride, uint8_t *dst, - size_t dst_stride, size_t width, - size_t height); +INTRINSICCV_API_DECLARATION(intrinsiccv_rgba_to_bgra_u8, const uint8_t *src, + size_t src_stride, uint8_t *dst, size_t dst_stride, + size_t width, size_t height); /// Copies a source RBGA image to destination buffer. /// All channels are 8-bit wide. @@ -403,10 +403,9 @@ intrinsiccv_error_t intrinsiccv_rgba_to_bgra_u8(const uint8_t *src, /// @param width Number of pixels in a row. /// @param height Number of rows in the data. /// -intrinsiccv_error_t intrinsiccv_rgba_to_rgba_u8(const uint8_t *src, - size_t src_stride, uint8_t *dst, - size_t dst_stride, size_t width, - size_t height); +INTRINSICCV_API_DECLARATION(intrinsiccv_rgba_to_rgba_u8, const uint8_t *src, + size_t src_stride, uint8_t *dst, size_t dst_stride, + size_t width, size_t height); /// Converts an RGB image to BGRA. All channels are 8-bit wide. /// @@ -430,10 +429,9 @@ intrinsiccv_error_t intrinsiccv_rgba_to_rgba_u8(const uint8_t *src, /// @param width Number of pixels in a row. /// @param height Number of rows in the data. /// -intrinsiccv_error_t intrinsiccv_rgb_to_bgra_u8(const uint8_t *src, - size_t src_stride, uint8_t *dst, - size_t dst_stride, size_t width, - size_t height); +INTRINSICCV_API_DECLARATION(intrinsiccv_rgb_to_bgra_u8, const uint8_t *src, + size_t src_stride, uint8_t *dst, size_t dst_stride, + size_t width, size_t height); /// Converts an RGB image to RGBA. All channels are 8-bit wide. /// @@ -457,10 +455,9 @@ intrinsiccv_error_t intrinsiccv_rgb_to_bgra_u8(const uint8_t *src, /// @param width Number of pixels in a row. /// @param height Number of rows in the data. /// -intrinsiccv_error_t intrinsiccv_rgb_to_rgba_u8(const uint8_t *src, - size_t src_stride, uint8_t *dst, - size_t dst_stride, size_t width, - size_t height); +INTRINSICCV_API_DECLARATION(intrinsiccv_rgb_to_rgba_u8, const uint8_t *src, + size_t src_stride, uint8_t *dst, size_t dst_stride, + size_t width, size_t height); /// Converts an RGBA image to BGR. All channels are 8-bit wide. /// @@ -484,10 +481,9 @@ intrinsiccv_error_t intrinsiccv_rgb_to_rgba_u8(const uint8_t *src, /// @param width Number of pixels in a row. /// @param height Number of rows in the data. /// -intrinsiccv_error_t intrinsiccv_rgba_to_bgr_u8(const uint8_t *src, - size_t src_stride, uint8_t *dst, - size_t dst_stride, size_t width, - size_t height); +INTRINSICCV_API_DECLARATION(intrinsiccv_rgba_to_bgr_u8, const uint8_t *src, + size_t src_stride, uint8_t *dst, size_t dst_stride, + size_t width, size_t height); /// Converts an RGBA image to RGB. All channels are 8-bit wide. /// @@ -511,10 +507,9 @@ intrinsiccv_error_t intrinsiccv_rgba_to_bgr_u8(const uint8_t *src, /// @param width Number of pixels in a row. /// @param height Number of rows in the data. /// -intrinsiccv_error_t intrinsiccv_rgba_to_rgb_u8(const uint8_t *src, - size_t src_stride, uint8_t *dst, - size_t dst_stride, size_t width, - size_t height); +INTRINSICCV_API_DECLARATION(intrinsiccv_rgba_to_rgb_u8, const uint8_t *src, + size_t src_stride, uint8_t *dst, size_t dst_stride, + size_t width, size_t height); /// Converts an NV12 or NV21 YUV image to RGB. All channels are 8-bit wide. /// @@ -548,10 +543,11 @@ intrinsiccv_error_t intrinsiccv_rgba_to_rgb_u8(const uint8_t *src, /// @param is_nv21 If true, input is treated as NV21, otherwise treated /// as NV12. /// -intrinsiccv_error_t intrinsiccv_yuv_sp_to_rgb_u8( - const uint8_t *src_y, size_t src_y_stride, const uint8_t *src_uv, - size_t src_uv_stride, uint8_t *dst, size_t dst_stride, size_t width, - size_t height, bool is_nv21); +INTRINSICCV_API_DECLARATION(intrinsiccv_yuv_sp_to_rgb_u8, const uint8_t *src_y, + size_t src_y_stride, const uint8_t *src_uv, + size_t src_uv_stride, uint8_t *dst, + size_t dst_stride, size_t width, size_t height, + bool is_nv21); /// Converts an NV12 or NV21 YUV image to BGR. All channels are 8-bit wide. /// @@ -585,10 +581,11 @@ intrinsiccv_error_t intrinsiccv_yuv_sp_to_rgb_u8( /// @param is_nv21 If true, input is treated as NV21, otherwise treated /// as NV12. /// -intrinsiccv_error_t intrinsiccv_yuv_sp_to_bgr_u8( - const uint8_t *src_y, size_t src_y_stride, const uint8_t *src_uv, - size_t src_uv_stride, uint8_t *dst, size_t dst_stride, size_t width, - size_t height, bool is_nv21); +INTRINSICCV_API_DECLARATION(intrinsiccv_yuv_sp_to_bgr_u8, const uint8_t *src_y, + size_t src_y_stride, const uint8_t *src_uv, + size_t src_uv_stride, uint8_t *dst, + size_t dst_stride, size_t width, size_t height, + bool is_nv21); /// Converts an NV12 or NV21 YUV image to RGBA. All channels are 8-bit wide. /// Alpha channel is set to 0xFF. @@ -621,10 +618,11 @@ intrinsiccv_error_t intrinsiccv_yuv_sp_to_bgr_u8( /// @param is_nv21 If true, input is treated as NV21, otherwise treated /// as NV12. /// -intrinsiccv_error_t intrinsiccv_yuv_sp_to_rgba_u8( - const uint8_t *src_y, size_t src_y_stride, const uint8_t *src_uv, - size_t src_uv_stride, uint8_t *dst, size_t dst_stride, size_t width, - size_t height, bool is_nv21); +INTRINSICCV_API_DECLARATION(intrinsiccv_yuv_sp_to_rgba_u8, const uint8_t *src_y, + size_t src_y_stride, const uint8_t *src_uv, + size_t src_uv_stride, uint8_t *dst, + size_t dst_stride, size_t width, size_t height, + bool is_nv21); /// Converts an NV12 or NV21 YUV image to BGRA. All channels are 8-bit wide. /// Alpha channel is set to 0xFF. @@ -657,10 +655,11 @@ intrinsiccv_error_t intrinsiccv_yuv_sp_to_rgba_u8( /// @param is_nv21 If true, input is treated as NV21, otherwise treated /// as NV12. /// -intrinsiccv_error_t intrinsiccv_yuv_sp_to_bgra_u8( - const uint8_t *src_y, size_t src_y_stride, const uint8_t *src_uv, - size_t src_uv_stride, uint8_t *dst, size_t dst_stride, size_t width, - size_t height, bool is_nv21); +INTRINSICCV_API_DECLARATION(intrinsiccv_yuv_sp_to_bgra_u8, const uint8_t *src_y, + size_t src_y_stride, const uint8_t *src_uv, + size_t src_uv_stride, uint8_t *dst, + size_t dst_stride, size_t width, size_t height, + bool is_nv21); /// Performs a comparison of each element's value in `src` with respect to a /// caller defined threshold. The strictly larger elements are set to @@ -685,9 +684,10 @@ intrinsiccv_error_t intrinsiccv_yuv_sp_to_bgra_u8( /// compared to. /// @param value The value that the larger elements are set to. /// -intrinsiccv_error_t intrinsiccv_threshold_binary_u8( - const uint8_t *src, size_t src_stride, uint8_t *dst, size_t dst_stride, - size_t width, size_t height, uint8_t threshold, uint8_t value); +INTRINSICCV_API_DECLARATION(intrinsiccv_threshold_binary_u8, const uint8_t *src, + size_t src_stride, uint8_t *dst, size_t dst_stride, + size_t width, size_t height, uint8_t threshold, + uint8_t value); /// Creates a morphology context according to the parameters. /// @@ -769,15 +769,17 @@ intrinsiccv_error_t intrinsiccv_morphology_release( /// @param height Number of rows in the data. /// @param context Pointer to morphology context. /// -intrinsiccv_error_t intrinsiccv_dilate_u8( - const uint8_t *src, size_t src_stride, uint8_t *dst, size_t dst_stride, - size_t width, size_t height, intrinsiccv_morphology_context_t *context); +INTRINSICCV_API_DECLARATION(intrinsiccv_dilate_u8, const uint8_t *src, + size_t src_stride, uint8_t *dst, size_t dst_stride, + size_t width, size_t height, + intrinsiccv_morphology_context_t *context); /// @copydoc intrinsiccv_dilate_u8 /// -intrinsiccv_error_t intrinsiccv_erode_u8( - const uint8_t *src, size_t src_stride, uint8_t *dst, size_t dst_stride, - size_t width, size_t height, intrinsiccv_morphology_context_t *context); +INTRINSICCV_API_DECLARATION(intrinsiccv_erode_u8, const uint8_t *src, + size_t src_stride, uint8_t *dst, size_t dst_stride, + size_t width, size_t height, + intrinsiccv_morphology_context_t *context); /// Counts how many nonzero elements are in the source data. Number of elements /// is limited to @ref INTRINSICCV_MAX_IMAGE_PIXELS. @@ -791,10 +793,9 @@ intrinsiccv_error_t intrinsiccv_erode_u8( /// @param height Number of rows in the data. /// @param count Pointer to variable to store result. Must be non-null. /// -intrinsiccv_error_t intrinsiccv_count_nonzeros_u8(const uint8_t *src, - size_t src_stride, - size_t width, size_t height, - size_t *count); +INTRINSICCV_API_DECLARATION(intrinsiccv_count_nonzeros_u8, const uint8_t *src, + size_t src_stride, size_t width, size_t height, + size_t *count); /// Resizes source data by averaging 4 elements to one. /// @@ -839,9 +840,11 @@ intrinsiccv_error_t intrinsiccv_count_nonzeros_u8(const uint8_t *src, /// For odd src_height it must be either src_height / 2 /// or (src_height / 2) + 1. /// -intrinsiccv_error_t intrinsiccv_resize_to_quarter_u8( - const uint8_t *src, size_t src_stride, size_t src_width, size_t src_height, - uint8_t *dst, size_t dst_stride, size_t dst_width, size_t dst_height); +INTRINSICCV_API_DECLARATION(intrinsiccv_resize_to_quarter_u8, + const uint8_t *src, size_t src_stride, + size_t src_width, size_t src_height, uint8_t *dst, + size_t dst_stride, size_t dst_width, + size_t dst_height); /// Calculates vertical derivative approximation with Sobel filter. /// @@ -875,9 +878,10 @@ intrinsiccv_error_t intrinsiccv_resize_to_quarter_u8( /// @param channels Number of channels in the data. Must be not more than /// @ref INTRINSICCV_MAXIMUM_CHANNEL_COUNT. /// -intrinsiccv_error_t intrinsiccv_sobel_3x3_vertical_s16_u8( - const uint8_t *src, size_t src_stride, int16_t *dst, size_t dst_stride, - size_t width, size_t height, size_t channels); +INTRINSICCV_API_DECLARATION(intrinsiccv_sobel_3x3_vertical_s16_u8, + const uint8_t *src, size_t src_stride, int16_t *dst, + size_t dst_stride, size_t width, size_t height, + size_t channels); /// Calculates horizontal derivative approximation with Sobel filter. /// @@ -911,9 +915,10 @@ intrinsiccv_error_t intrinsiccv_sobel_3x3_vertical_s16_u8( /// @param channels Number of channels in the data. Must be not more than /// @ref INTRINSICCV_MAXIMUM_CHANNEL_COUNT. /// -intrinsiccv_error_t intrinsiccv_sobel_3x3_horizontal_s16_u8( - const uint8_t *src, size_t src_stride, int16_t *dst, size_t dst_stride, - size_t width, size_t height, size_t channels); +INTRINSICCV_API_DECLARATION(intrinsiccv_sobel_3x3_horizontal_s16_u8, + const uint8_t *src, size_t src_stride, int16_t *dst, + size_t dst_stride, size_t width, size_t height, + size_t channels); #if INTRINSICCV_EXPERIMENTAL_FEATURE_CANNY /// Canny edge detector for uint8_t grayscale input. Output is also a uint8_t @@ -943,11 +948,10 @@ intrinsiccv_error_t intrinsiccv_sobel_3x3_horizontal_s16_u8( /// @param low_threshold Low threshold for the edge detector algorithm. /// @param high_threshold High threshold for the edge detector algorithm. /// -intrinsiccv_error_t intrinsiccv_canny_u8(const uint8_t *src, size_t src_stride, - uint8_t *dst, size_t dst_stride, - size_t width, size_t height, - double low_threshold, - double high_threshold); +INTRINSICCV_API_DECLARATION(intrinsiccv_canny_u8, const uint8_t *src, + size_t src_stride, uint8_t *dst, size_t dst_stride, + size_t width, size_t height, double low_threshold, + double high_threshold); #endif // INTRINSICCV_EXPERIMENTAL_FEATURE_CANNY /// Creates a filter context according to the parameters. @@ -1027,19 +1031,21 @@ intrinsiccv_error_t intrinsiccv_filter_release( /// @param border_type Way of handling the border. /// @param context Pointer to filter context. /// -intrinsiccv_error_t intrinsiccv_gaussian_blur_3x3_u8( - const uint8_t *src, size_t src_stride, uint8_t *dst, size_t dst_stride, - size_t width, size_t height, size_t channels, - intrinsiccv_border_type_t border_type, - intrinsiccv_filter_context_t *context); +INTRINSICCV_API_DECLARATION(intrinsiccv_gaussian_blur_3x3_u8, + const uint8_t *src, size_t src_stride, uint8_t *dst, + size_t dst_stride, size_t width, size_t height, + size_t channels, + intrinsiccv_border_type_t border_type, + intrinsiccv_filter_context_t *context); /// @copydoc intrinsiccv_gaussian_blur_3x3_u8 /// -intrinsiccv_error_t intrinsiccv_gaussian_blur_5x5_u8( - const uint8_t *src, size_t src_stride, uint8_t *dst, size_t dst_stride, - size_t width, size_t height, size_t channels, - intrinsiccv_border_type_t border_type, - intrinsiccv_filter_context_t *context); +INTRINSICCV_API_DECLARATION(intrinsiccv_gaussian_blur_5x5_u8, + const uint8_t *src, size_t src_stride, uint8_t *dst, + size_t dst_stride, size_t width, size_t height, + size_t channels, + intrinsiccv_border_type_t border_type, + intrinsiccv_filter_context_t *context); /// Splits a multi channel source stream into separate 1-channel streams. Width /// and height are the same for the source stream and for all the destination @@ -1069,11 +1075,11 @@ intrinsiccv_error_t intrinsiccv_gaussian_blur_5x5_u8( /// 4. /// @param element_size Size of one element in bytes. Must be 1, 2, 4 or 8. /// -intrinsiccv_error_t intrinsiccv_split(const void *src_data, size_t src_stride, - void **dst_data, - const size_t *dst_strides, size_t width, - size_t height, size_t channels, - size_t element_size); +INTRINSICCV_API_DECLARATION(intrinsiccv_split, const void *src_data, + size_t src_stride, void **dst_data, + const size_t *dst_strides, size_t width, + size_t height, size_t channels, + size_t element_size); /// Matrix transpose operation. /// Inplace transpose ('src == dst') is only supported for @@ -1106,10 +1112,10 @@ intrinsiccv_error_t intrinsiccv_split(const void *src_data, size_t src_stride, /// @param src_height Number of rows in the data. /// @param element_size Size of one element in bytes. Must be 1, 2, 4 or 8. /// -intrinsiccv_error_t intrinsiccv_transpose(const void *src, size_t src_stride, - void *dst, size_t dst_stride, - size_t src_width, size_t src_height, - size_t element_size); +INTRINSICCV_API_DECLARATION(intrinsiccv_transpose, const void *src, + size_t src_stride, void *dst, size_t dst_stride, + size_t src_width, size_t src_height, + size_t element_size); /// Merges separate 1-channel source streams to one multi channel stream. Width /// and height are the same for all the source streams and for the destination. @@ -1139,11 +1145,10 @@ intrinsiccv_error_t intrinsiccv_transpose(const void *src, size_t src_stride, /// 3 or 4. /// @param element_size Size of one element in bytes. Must be 1, 2, 4 or 8. /// -intrinsiccv_error_t intrinsiccv_merge(const void **srcs, - const size_t *src_strides, void *dst, - size_t dst_stride, size_t width, - size_t height, size_t channels, - size_t element_size); +INTRINSICCV_API_DECLARATION(intrinsiccv_merge, const void **srcs, + const size_t *src_strides, void *dst, + size_t dst_stride, size_t width, size_t height, + size_t channels, size_t element_size); /// Calculates minimum and maximum element value across the source data. Number /// of elements is limited to @ref INTRINSICCV_MAX_IMAGE_PIXELS. @@ -1160,30 +1165,25 @@ intrinsiccv_error_t intrinsiccv_merge(const void **srcs, /// @param max_value Pointer to save result maximum value to, or nullptr if /// maximum is not to be calculated. /// -intrinsiccv_error_t intrinsiccv_min_max_u8(const uint8_t *src, - size_t src_stride, size_t width, - size_t height, uint8_t *min_value, - uint8_t *max_value); +INTRINSICCV_API_DECLARATION(intrinsiccv_min_max_u8, const uint8_t *src, + size_t src_stride, size_t width, size_t height, + uint8_t *min_value, uint8_t *max_value); /// @copydoc intrinsiccv_min_max_u8 -intrinsiccv_error_t intrinsiccv_min_max_s8(const int8_t *src, size_t src_stride, - size_t width, size_t height, - int8_t *min_value, - int8_t *max_value); +INTRINSICCV_API_DECLARATION(intrinsiccv_min_max_s8, const int8_t *src, + size_t src_stride, size_t width, size_t height, + int8_t *min_value, int8_t *max_value); /// @copydoc intrinsiccv_min_max_u8 -intrinsiccv_error_t intrinsiccv_min_max_u16(const uint16_t *src, - size_t src_stride, size_t width, - size_t height, uint16_t *min_value, - uint16_t *max_value); +INTRINSICCV_API_DECLARATION(intrinsiccv_min_max_u16, const uint16_t *src, + size_t src_stride, size_t width, size_t height, + uint16_t *min_value, uint16_t *max_value); /// @copydoc intrinsiccv_min_max_u8 -intrinsiccv_error_t intrinsiccv_min_max_s16(const int16_t *src, - size_t src_stride, size_t width, - size_t height, int16_t *min_value, - int16_t *max_value); +INTRINSICCV_API_DECLARATION(intrinsiccv_min_max_s16, const int16_t *src, + size_t src_stride, size_t width, size_t height, + int16_t *min_value, int16_t *max_value); /// @copydoc intrinsiccv_min_max_u8 -intrinsiccv_error_t intrinsiccv_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); +INTRINSICCV_API_DECLARATION(intrinsiccv_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); /// Finds minimum and maximum element value across the source data, /// and returns their location in the source data as offset in bytes @@ -1202,11 +1202,9 @@ intrinsiccv_error_t intrinsiccv_min_max_s32(const int32_t *src, /// @param max_offset Pointer to save result offset of maximum value to, or /// nullptr if maximum is not to be calculated. /// -intrinsiccv_error_t intrinsiccv_min_max_loc_u8(const uint8_t *src, - size_t src_stride, size_t width, - size_t height, - size_t *min_offset, - size_t *max_offset); +INTRINSICCV_API_DECLARATION(intrinsiccv_min_max_loc_u8, const uint8_t *src, + size_t src_stride, size_t width, size_t height, + size_t *min_offset, size_t *max_offset); /// Multiplies the elements in `src` by `scale`, then adds `shift` to the /// result and stores it in `dst`. @@ -1230,10 +1228,10 @@ intrinsiccv_error_t intrinsiccv_min_max_loc_u8(const uint8_t *src, /// @param scale Value to multiply the input by. /// @param shift Value to add to the result. /// -intrinsiccv_error_t intrinsiccv_scale_u8(const uint8_t *src, size_t src_stride, - uint8_t *dst, size_t dst_stride, - size_t width, size_t height, - float scale, float shift); +INTRINSICCV_API_DECLARATION(intrinsiccv_scale_u8, const uint8_t *src, + size_t src_stride, uint8_t *dst, size_t dst_stride, + size_t width, size_t height, float scale, + float shift); #ifdef __cplusplus } // extern "C" diff --git a/intrinsiccv/src/analysis/count_nonzeros_neon.cpp b/intrinsiccv/src/analysis/count_nonzeros_neon.cpp index 32c3b5418..f56a27618 100644 --- a/intrinsiccv/src/analysis/count_nonzeros_neon.cpp +++ b/intrinsiccv/src/analysis/count_nonzeros_neon.cpp @@ -41,15 +41,6 @@ class CountNonZeros final : public UnrollTwice { VectorType v_accumulator_; }; // end of class CountNonZeros -template -static size_t count_nonzeros_impl(Rows src, Rectangle rect) { - CountNonZeros operation; - apply_block_operation_by_rows(operation, rect, src); - return operation.result(); -} - -} // namespace neon - template INTRINSICCV_TARGET_FN_ATTRS static intrinsiccv_error_t count_nonzeros( const T *src, size_t src_stride, size_t width, size_t height, @@ -60,19 +51,20 @@ INTRINSICCV_TARGET_FN_ATTRS static intrinsiccv_error_t count_nonzeros( Rectangle rect{width, height}; Rows src_rows{src, src_stride}; - *count = neon::count_nonzeros_impl(src_rows, rect); + + CountNonZeros operation; + apply_block_operation_by_rows(operation, rect, src_rows); + *count = operation.result(); + return INTRINSICCV_OK; } +} // namespace neon + extern "C" { -INTRINSICCV_TARGET_FN_ATTRS -intrinsiccv_error_t intrinsiccv_count_nonzeros_u8(const uint8_t *src, - size_t src_stride, - size_t width, size_t height, - size_t *count) { - return count_nonzeros(src, src_stride, width, height, count); -} +decltype(neon::count_nonzeros) *intrinsiccv_count_nonzeros_u8 = + neon::count_nonzeros; } // extern "C" diff --git a/intrinsiccv/src/conversions/rgb_to_rgb_api.cpp b/intrinsiccv/src/conversions/rgb_to_rgb_api.cpp index 8f2906f4d..81efd3735 100644 --- a/intrinsiccv/src/conversions/rgb_to_rgb_api.cpp +++ b/intrinsiccv/src/conversions/rgb_to_rgb_api.cpp @@ -25,10 +25,9 @@ INTRINSICCV_DEFINE_C_API(intrinsiccv_rgba_to_rgb_u8, rgba_to_rgb_u8); extern "C" { -intrinsiccv_error_t intrinsiccv_rgb_to_rgb_u8(const uint8_t *src, - size_t src_stride, uint8_t *dst, - size_t dst_stride, size_t width, - size_t height) { +intrinsiccv_error_t intrinsiccv_rgb_to_rgb_u8_impl( + const uint8_t *src, size_t src_stride, uint8_t *dst, size_t dst_stride, + size_t width, size_t height) { CHECK_POINTER_AND_STRIDE(src, src_stride); CHECK_POINTER_AND_STRIDE(dst, dst_stride); CHECK_IMAGE_SIZE(width, height); @@ -40,10 +39,12 @@ intrinsiccv_error_t intrinsiccv_rgb_to_rgb_u8(const uint8_t *src, return INTRINSICCV_OK; } -intrinsiccv_error_t intrinsiccv_rgba_to_rgba_u8(const uint8_t *src, - size_t src_stride, uint8_t *dst, - size_t dst_stride, size_t width, - size_t height) { +decltype(intrinsiccv_rgb_to_rgb_u8_impl) *intrinsiccv_rgb_to_rgb_u8 = + intrinsiccv_rgb_to_rgb_u8_impl; + +intrinsiccv_error_t intrinsiccv_rgba_to_rgba_u8_impl( + const uint8_t *src, size_t src_stride, uint8_t *dst, size_t dst_stride, + size_t width, size_t height) { CHECK_POINTER_AND_STRIDE(src, src_stride); CHECK_POINTER_AND_STRIDE(dst, dst_stride); CHECK_IMAGE_SIZE(width, height); @@ -55,6 +56,9 @@ intrinsiccv_error_t intrinsiccv_rgba_to_rgba_u8(const uint8_t *src, return INTRINSICCV_OK; } +decltype(intrinsiccv_rgba_to_rgba_u8_impl) *intrinsiccv_rgba_to_rgba_u8 = + intrinsiccv_rgba_to_rgba_u8_impl; + } // extern "C" } // namespace intrinsiccv diff --git a/test/api/test_morphology.cpp b/test/api/test_morphology.cpp index 5c25c8d8b..78d7d34ff 100644 --- a/test/api/test_morphology.cpp +++ b/test/api/test_morphology.cpp @@ -18,7 +18,7 @@ std::enable_if_t, bool> = true> \ class name { \ public: \ - static decltype(auto) api() { return &impl; } \ + static decltype(auto) api() { return impl; } \ static decltype(auto) operation() { \ return [](type a, type b) { return op(a, b); }; \ } \ diff --git a/test/framework/utils.h b/test/framework/utils.h index 3c4a9bba5..35e41e62e 100644 --- a/test/framework/utils.h +++ b/test/framework/utils.h @@ -21,7 +21,7 @@ template , bool> = true> \ static decltype(auto) name() { \ - return &impl; \ + return impl; \ } // Generates a fatal failure with a generic message, and returns with a given -- GitLab From dad62f2a2094e4de3eb92a4e7ea0f8c194ef3d0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Igor=20Podgain=C3=B5i?= Date: Mon, 11 Mar 2024 12:56:00 +0100 Subject: [PATCH 3/7] Split some functionality for Linux and Android only --- intrinsiccv/include/intrinsiccv/config.h.in | 5 ++++ intrinsiccv/include/intrinsiccv/dispatch.h | 9 +++++- test/CMakeLists.txt | 20 +++++++++++-- test/api/test_add_abs_with_threshold.cpp | 1 + test/api/test_canny.cpp | 1 + test/api/test_count_nonzeros.cpp | 1 + test/api/test_gaussian_blur.cpp | 3 ++ test/api/test_merge.cpp | 1 + test/api/test_min_max.cpp | 1 + test/api/test_morphology.cpp | 20 +++++++++---- test/api/test_resize_to_quarter.cpp | 1 + test/api/test_rgb_and_gray.cpp | 1 + test/api/test_saturating_absdiff.cpp | 1 + test/api/test_saturating_add.cpp | 1 + test/api/test_saturating_multiply.cpp | 1 + test/api/test_saturating_sub.cpp | 1 + test/api/test_scale.cpp | 1 + test/api/test_sobel.cpp | 32 +++++++++++---------- test/api/test_split.cpp | 1 + test/api/test_threshold_binary.cpp | 1 + test/api/test_transpose.cpp | 1 + test/api/test_yuv_to_rgb.cpp | 1 + test/test_config.h.in | 12 ++++++++ 23 files changed, 93 insertions(+), 24 deletions(-) create mode 100644 test/test_config.h.in diff --git a/intrinsiccv/include/intrinsiccv/config.h.in b/intrinsiccv/include/intrinsiccv/config.h.in index 581230f39..710049712 100644 --- a/intrinsiccv/include/intrinsiccv/config.h.in +++ b/intrinsiccv/include/intrinsiccv/config.h.in @@ -53,8 +53,13 @@ #define INTRINSICCV_STREAMING_COMPATIBLE #endif +#ifdef __linux__ #define INTRINSICCV_ATTR_SECTION(section_to_use) \ __attribute__((section(section_to_use))) +#else +#define INTRINSICCV_ATTR_SECTION(x) +#endif + #define INTRINSICCV_ATTR_NOINLINE __attribute__((noinline)) #define INTRINSICCV_ATTR_ALIGNED(alignment) __attribute__((aligned(alignment))) diff --git a/intrinsiccv/include/intrinsiccv/dispatch.h b/intrinsiccv/include/intrinsiccv/dispatch.h index 26058bec5..27473cb1d 100644 --- a/intrinsiccv/include/intrinsiccv/dispatch.h +++ b/intrinsiccv/include/intrinsiccv/dispatch.h @@ -5,7 +5,9 @@ #ifndef INTRINSICCV_DISPATCH_H #define INTRINSICCV_DISPATCH_H +#ifdef __linux__ #include +#endif #include #include @@ -21,9 +23,14 @@ struct HwCaps final { HwCapTy hwcap2; }; +#ifdef __linux__ static inline HwCaps get_hwcaps() { return HwCaps{getauxval(AT_HWCAP), getauxval(AT_HWCAP2)}; } +#define GET_HWCAPS_OR_FAIL(x) [[maybe_unused]] HwCaps hwcaps = get_hwcaps() +#else +#define GET_HWCAPS_OR_FAIL(fallback_impl) return fallback_impl +#endif static inline bool hwcaps_has_sve2(HwCaps hwcaps) { return hwcaps.hwcap2 & (1 << 1); @@ -67,7 +74,7 @@ static inline bool hwcaps_has_sme2(HwCaps hwcaps) { #define INTRINSICCV_MULTIVERSION_C_API(api_name, neon_impl, sve2_impl, \ sme2_impl, ...) \ decltype(neon_impl) *api_name##_resolver() { \ - [[maybe_unused]] HwCaps hwcaps = get_hwcaps(); \ + GET_HWCAPS_OR_FAIL(neon_impl); \ INTRINSICCV_SME2_RESOLVE(sme2_impl); \ INTRINSICCV_SVE2_RESOLVE(sve2_impl); \ return neon_impl; \ diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index af5c11849..6de1e2a88 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -8,7 +8,10 @@ set(INTRINSICCV_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../intrinsiccv/include ${CMAKE_CURRENT_BINARY_DIR}/../intrinsiccv/include ) -set(INTRINSICCV_TEST_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}) +set(INTRINSICCV_TEST_INCLUDE_DIR + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_BINARY_DIR} +) set(INTRINSICCV_TEST_CXX_FLAGS "-Werror" @@ -23,15 +26,26 @@ else() list(APPEND INTRINSICCV_TEST_CXX_FLAGS "-O2" "-g0") endif() -SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--wrap,malloc") +# Only perform allocation tests on Linux and Android +if (CMAKE_SYSTEM_NAME MATCHES "^(Linux|Android)$") + set(INTRINSICCV_ALLOCATION_TESTS TRUE) +endif() set(INTRINSICCV_TEST_FRAMEWORK_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/framework/border.cpp ${CMAKE_CURRENT_SOURCE_DIR}/framework/test_main.cpp ${CMAKE_CURRENT_SOURCE_DIR}/framework/utils.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/framework/wrap_malloc.cpp ) +if (INTRINSICCV_ALLOCATION_TESTS) + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--wrap,malloc") + list(APPEND INTRINSICCV_TEST_FRAMEWORK_SOURCES + ${CMAKE_CURRENT_SOURCE_DIR}/framework/wrap_malloc.cpp + ) +endif() + +configure_file("${CMAKE_CURRENT_LIST_DIR}/test_config.h.in" "test_config.h") + include(FetchContent) # Please update SECURITY.md if adding, removing or changing the version of third party content. FetchContent_Declare( diff --git a/test/api/test_add_abs_with_threshold.cpp b/test/api/test_add_abs_with_threshold.cpp index d7d1ea890..eae22c00b 100644 --- a/test/api/test_add_abs_with_threshold.cpp +++ b/test/api/test_add_abs_with_threshold.cpp @@ -6,6 +6,7 @@ #include "framework/operation.h" #include "intrinsiccv/intrinsiccv.h" +#include "test_config.h" template class SaturatingAddAbsWithThresholdTestBase diff --git a/test/api/test_canny.cpp b/test/api/test_canny.cpp index 4be2534d6..995846ec4 100644 --- a/test/api/test_canny.cpp +++ b/test/api/test_canny.cpp @@ -6,6 +6,7 @@ #include "framework/utils.h" #include "intrinsiccv/intrinsiccv.h" +#include "test_config.h" #if INTRINSICCV_EXPERIMENTAL_FEATURE_CANNY diff --git a/test/api/test_count_nonzeros.cpp b/test/api/test_count_nonzeros.cpp index 80abe474a..6ea26392f 100644 --- a/test/api/test_count_nonzeros.cpp +++ b/test/api/test_count_nonzeros.cpp @@ -9,6 +9,7 @@ #include "framework/array.h" #include "framework/utils.h" #include "intrinsiccv/intrinsiccv.h" +#include "test_config.h" #define INTRINSICCV_COUNT_NONZEROS(type, suffix) \ INTRINSICCV_API(count_nonzeros, intrinsiccv_count_nonzeros_##suffix, type) diff --git a/test/api/test_gaussian_blur.cpp b/test/api/test_gaussian_blur.cpp index da70ee83e..20c5a1699 100644 --- a/test/api/test_gaussian_blur.cpp +++ b/test/api/test_gaussian_blur.cpp @@ -9,6 +9,7 @@ #include "framework/kernel.h" #include "framework/utils.h" #include "intrinsiccv/intrinsiccv.h" +#include "test_config.h" #define INTRINSICCV_GAUSSIAN_BLUR(type, kernel_suffix, type_suffix) \ INTRINSICCV_API(gaussian_blur_##kernel_suffix, \ @@ -563,6 +564,7 @@ TYPED_TEST(GaussianBlur, InvalidContextImageSize) { EXPECT_EQ(INTRINSICCV_OK, intrinsiccv_filter_release(context)); } +#ifdef INTRINSICCV_ALLOCATION_TESTS TEST(FilterCreate, CannotAllocateFilter) { MockMallocToFail::enable(); intrinsiccv_filter_context_t *context = nullptr; @@ -571,6 +573,7 @@ TEST(FilterCreate, CannotAllocateFilter) { intrinsiccv_filter_create(&context, 1, 1, rect)); MockMallocToFail::disable(); } +#endif TEST(FilterCreate, OversizeImage) { intrinsiccv_filter_context_t *context = nullptr; diff --git a/test/api/test_merge.cpp b/test/api/test_merge.cpp index 6259929e5..8334cc108 100644 --- a/test/api/test_merge.cpp +++ b/test/api/test_merge.cpp @@ -7,6 +7,7 @@ #include "framework/array.h" #include "framework/utils.h" #include "intrinsiccv/intrinsiccv.h" +#include "test_config.h" template class MergeTest final { diff --git a/test/api/test_min_max.cpp b/test/api/test_min_max.cpp index 999c448c6..d98e64d7f 100644 --- a/test/api/test_min_max.cpp +++ b/test/api/test_min_max.cpp @@ -7,6 +7,7 @@ #include "framework/array.h" #include "framework/utils.h" #include "intrinsiccv/intrinsiccv.h" +#include "test_config.h" #define INTRINSICCV_MIN_MAX(type, suffix) \ INTRINSICCV_API(min_max, intrinsiccv_min_max_##suffix, type) diff --git a/test/api/test_morphology.cpp b/test/api/test_morphology.cpp index 78d7d34ff..ce72b4389 100644 --- a/test/api/test_morphology.cpp +++ b/test/api/test_morphology.cpp @@ -12,6 +12,7 @@ #include "framework/kernel.h" #include "framework/operation.h" #include "intrinsiccv/intrinsiccv.h" +#include "test_config.h" #define INTRINSICCV_PARAMS(name, impl, type, op) \ template ; typename KernelTestParams::InputType src[1] = {}; typename KernelTestParams::OutputType dst[1]; size_t validSize = 2; + EXPECT_EQ( + INTRINSICCV_ERROR_ALLOCATION, + sobel_3x3_horizontal()( + src, sizeof(src), dst, sizeof(dst), INTRINSICCV_MAX_IMAGE_PIXELS / 2, + validSize, INTRINSICCV_MAXIMUM_CHANNEL_COUNT)); + MockMallocToFail::disable(); +} +#endif + +TYPED_TEST(Sobel, OversizeImageHorizontal) { + using KernelTestParams = SobelKernelTestParams; + typename KernelTestParams::InputType src[1] = {}; + typename KernelTestParams::OutputType dst[1]; + EXPECT_EQ(INTRINSICCV_ERROR_RANGE, sobel_3x3_horizontal()( src, sizeof(src), dst, sizeof(dst), @@ -238,20 +254,12 @@ TYPED_TEST(Sobel, OversizeImageHorizontal) { sobel_3x3_horizontal()( src, sizeof(src), dst, sizeof(dst), INTRINSICCV_MAX_IMAGE_PIXELS, INTRINSICCV_MAX_IMAGE_PIXELS, 1)); - EXPECT_EQ( - INTRINSICCV_ERROR_ALLOCATION, - sobel_3x3_horizontal()( - src, sizeof(src), dst, sizeof(dst), INTRINSICCV_MAX_IMAGE_PIXELS / 2, - validSize, INTRINSICCV_MAXIMUM_CHANNEL_COUNT)); - MockMallocToFail::disable(); } TYPED_TEST(Sobel, OversizeImageVertical) { - MockMallocToFail::enable(); using KernelTestParams = SobelKernelTestParams; typename KernelTestParams::InputType src[1] = {}; typename KernelTestParams::OutputType dst[1]; - size_t validSize = 2; EXPECT_EQ( INTRINSICCV_ERROR_RANGE, @@ -261,12 +269,6 @@ TYPED_TEST(Sobel, OversizeImageVertical) { sobel_3x3_vertical()(src, sizeof(src), dst, sizeof(dst), INTRINSICCV_MAX_IMAGE_PIXELS, INTRINSICCV_MAX_IMAGE_PIXELS, 1)); - EXPECT_EQ(INTRINSICCV_ERROR_ALLOCATION, - sobel_3x3_vertical()(src, sizeof(src), dst, sizeof(dst), - INTRINSICCV_MAX_IMAGE_PIXELS / 2, - validSize, - INTRINSICCV_MAXIMUM_CHANNEL_COUNT)); - MockMallocToFail::disable(); } TYPED_TEST(Sobel, ChannelNumber) { diff --git a/test/api/test_split.cpp b/test/api/test_split.cpp index 3e750b23e..51c2221b2 100644 --- a/test/api/test_split.cpp +++ b/test/api/test_split.cpp @@ -7,6 +7,7 @@ #include "framework/array.h" #include "framework/utils.h" #include "intrinsiccv/intrinsiccv.h" +#include "test_config.h" template class SplitTest final { diff --git a/test/api/test_threshold_binary.cpp b/test/api/test_threshold_binary.cpp index 50205ff75..a645849ef 100644 --- a/test/api/test_threshold_binary.cpp +++ b/test/api/test_threshold_binary.cpp @@ -6,6 +6,7 @@ #include "framework/operation.h" #include "intrinsiccv/intrinsiccv.h" +#include "test_config.h" #define INTRINSICCV_THRESHOLD_BINARY(type, suffix) \ INTRINSICCV_API(threshold_binary, intrinsiccv_threshold_binary_##suffix, type) diff --git a/test/api/test_transpose.cpp b/test/api/test_transpose.cpp index e2fe7740f..ddbcc8fff 100644 --- a/test/api/test_transpose.cpp +++ b/test/api/test_transpose.cpp @@ -7,6 +7,7 @@ #include "framework/array.h" #include "framework/generator.h" #include "intrinsiccv/intrinsiccv.h" +#include "test_config.h" template class TestTranspose final { diff --git a/test/api/test_yuv_to_rgb.cpp b/test/api/test_yuv_to_rgb.cpp index 32cbf48c3..b462c8ce1 100644 --- a/test/api/test_yuv_to_rgb.cpp +++ b/test/api/test_yuv_to_rgb.cpp @@ -8,6 +8,7 @@ #include "framework/utils.h" #include "intrinsiccv/intrinsiccv.h" #include "intrinsiccv/utils.h" +#include "test_config.h" class YuvTest final { public: diff --git a/test/test_config.h.in b/test/test_config.h.in new file mode 100644 index 000000000..8b91f4d50 --- /dev/null +++ b/test/test_config.h.in @@ -0,0 +1,12 @@ +// SPDX-FileCopyrightText: 2024 Arm Limited and/or its affiliates +// +// SPDX-License-Identifier: Apache-2.0 + +#ifndef INTRINSICCV_TEST_CONFIG_H +#define INTRINSICCV_TEST_CONFIG_H + +// Main test configuration switches. + +#cmakedefine INTRINSICCV_ALLOCATION_TESTS + +#endif // INTRINSICCV_TEST_CONFIG_H -- GitLab From 53d0c9a3c877f002a8daf39bb75ccb8d2a2095f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Igor=20Podgain=C3=B5i?= Date: Tue, 12 Mar 2024 12:00:42 +0100 Subject: [PATCH 4/7] Fix for OpenCV adapter --- adapters/opencv/intrinsiccv_hal.cpp | 4 ++-- intrinsiccv/include/intrinsiccv/dispatch.h | 2 +- intrinsiccv/src/conversions/rgb_to_rgb_api.cpp | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/adapters/opencv/intrinsiccv_hal.cpp b/adapters/opencv/intrinsiccv_hal.cpp index 4e2f2af04..dacc42e41 100644 --- a/adapters/opencv/intrinsiccv_hal.cpp +++ b/adapters/opencv/intrinsiccv_hal.cpp @@ -251,7 +251,7 @@ int gaussian_blur(const uchar *src_data, size_t src_step, uchar *dst_data, return CV_HAL_ERROR_NOT_IMPLEMENTED; } - decltype(intrinsiccv_gaussian_blur_3x3_u8) *impl{nullptr}; + decltype(intrinsiccv_gaussian_blur_3x3_u8) impl{nullptr}; if ((ksize_width == 3) && (ksize_height == 3) && (width >= 3) && (height >= 3)) { impl = intrinsiccv_gaussian_blur_3x3_u8; @@ -289,7 +289,7 @@ int gaussian_blur(const uchar *src_data, size_t src_step, uchar *dst_data, struct MorphologyParams { intrinsiccv_morphology_context_t *context; - decltype(intrinsiccv_dilate_u8) *impl; + decltype(intrinsiccv_dilate_u8) impl; }; int morphology_init(cvhalFilter2D **cvcontext, int operation, int src_type, diff --git a/intrinsiccv/include/intrinsiccv/dispatch.h b/intrinsiccv/include/intrinsiccv/dispatch.h index 27473cb1d..2589538d9 100644 --- a/intrinsiccv/include/intrinsiccv/dispatch.h +++ b/intrinsiccv/include/intrinsiccv/dispatch.h @@ -73,7 +73,7 @@ static inline bool hwcaps_has_sme2(HwCaps hwcaps) { // Creates a multiversioned C API with a resolver for it #define INTRINSICCV_MULTIVERSION_C_API(api_name, neon_impl, sve2_impl, \ sme2_impl, ...) \ - decltype(neon_impl) *api_name##_resolver() { \ + static decltype(neon_impl) *api_name##_resolver() { \ GET_HWCAPS_OR_FAIL(neon_impl); \ INTRINSICCV_SME2_RESOLVE(sme2_impl); \ INTRINSICCV_SVE2_RESOLVE(sve2_impl); \ diff --git a/intrinsiccv/src/conversions/rgb_to_rgb_api.cpp b/intrinsiccv/src/conversions/rgb_to_rgb_api.cpp index 81efd3735..e9eb93521 100644 --- a/intrinsiccv/src/conversions/rgb_to_rgb_api.cpp +++ b/intrinsiccv/src/conversions/rgb_to_rgb_api.cpp @@ -25,7 +25,7 @@ INTRINSICCV_DEFINE_C_API(intrinsiccv_rgba_to_rgb_u8, rgba_to_rgb_u8); extern "C" { -intrinsiccv_error_t intrinsiccv_rgb_to_rgb_u8_impl( +static intrinsiccv_error_t intrinsiccv_rgb_to_rgb_u8_impl( const uint8_t *src, size_t src_stride, uint8_t *dst, size_t dst_stride, size_t width, size_t height) { CHECK_POINTER_AND_STRIDE(src, src_stride); @@ -42,7 +42,7 @@ intrinsiccv_error_t intrinsiccv_rgb_to_rgb_u8_impl( decltype(intrinsiccv_rgb_to_rgb_u8_impl) *intrinsiccv_rgb_to_rgb_u8 = intrinsiccv_rgb_to_rgb_u8_impl; -intrinsiccv_error_t intrinsiccv_rgba_to_rgba_u8_impl( +static intrinsiccv_error_t intrinsiccv_rgba_to_rgba_u8_impl( const uint8_t *src, size_t src_stride, uint8_t *dst, size_t dst_stride, size_t width, size_t height) { CHECK_POINTER_AND_STRIDE(src, src_stride); -- GitLab From b66de73c8a92d5e50dba25e00296cbf57ddcab48 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Igor=20Podgain=C3=B5i?= Date: Tue, 12 Mar 2024 13:30:05 +0100 Subject: [PATCH 5/7] Hide function pointers from Doxygen --- Doxyfile | 3 ++- intrinsiccv/include/intrinsiccv/intrinsiccv.h | 5 +++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/Doxyfile b/Doxyfile index f6f966ddc..4746ceae8 100644 --- a/Doxyfile +++ b/Doxyfile @@ -17,5 +17,6 @@ HTML_TIMESTAMP = YES GENERATE_LATEX = NO MACRO_EXPANSION = YES DIRECTORY_GRAPH = NO -PREDEFINED = __aarch64__= +PREDEFINED = __aarch64__= \ + DOXYGEN TYPEDEF_HIDES_STRUCT = YES diff --git a/intrinsiccv/include/intrinsiccv/intrinsiccv.h b/intrinsiccv/include/intrinsiccv/intrinsiccv.h index d594797f1..fdf0f2af1 100644 --- a/intrinsiccv/include/intrinsiccv/intrinsiccv.h +++ b/intrinsiccv/include/intrinsiccv/intrinsiccv.h @@ -48,8 +48,13 @@ extern "C" { #endif // __cplusplus +#ifdef DOXYGEN +#define INTRINSICCV_API_DECLARATION(name, ...) \ + intrinsiccv_error_t name(__VA_ARGS__) +#else #define INTRINSICCV_API_DECLARATION(name, ...) \ extern intrinsiccv_error_t (*name)(__VA_ARGS__) +#endif #define INTRINSICCV_BINARY_OP(name, type) \ INTRINSICCV_API_DECLARATION(name, const type *src_a, size_t src_a_stride, \ -- GitLab From ca1c385205fa086d993209bbe05cc9b9adc3f9d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Igor=20Podgain=C3=B5i?= Date: Wed, 13 Mar 2024 16:49:04 +0100 Subject: [PATCH 6/7] Simplify HwCaps resolving logic --- intrinsiccv/include/intrinsiccv/dispatch.h | 73 +++++++++++----------- 1 file changed, 38 insertions(+), 35 deletions(-) diff --git a/intrinsiccv/include/intrinsiccv/dispatch.h b/intrinsiccv/include/intrinsiccv/dispatch.h index 2589538d9..c5c86b817 100644 --- a/intrinsiccv/include/intrinsiccv/dispatch.h +++ b/intrinsiccv/include/intrinsiccv/dispatch.h @@ -5,7 +5,7 @@ #ifndef INTRINSICCV_DISPATCH_H #define INTRINSICCV_DISPATCH_H -#ifdef __linux__ +#if INTRINSICCV_HAVE_SVE2 || INTRINSICCV_HAVE_SME2 #include #endif @@ -23,65 +23,68 @@ struct HwCaps final { HwCapTy hwcap2; }; -#ifdef __linux__ +#if INTRINSICCV_ALWAYS_ENABLE_SVE2 +#define INTRINSICCV_SVE2_IMPL_IF(func) func +#else +#define INTRINSICCV_SVE2_IMPL_IF(func) nullptr +#endif + +#if INTRINSICCV_HAVE_SVE2 || INTRINSICCV_HAVE_SME2 static inline HwCaps get_hwcaps() { return HwCaps{getauxval(AT_HWCAP), getauxval(AT_HWCAP2)}; } -#define GET_HWCAPS_OR_FAIL(x) [[maybe_unused]] HwCaps hwcaps = get_hwcaps() -#else -#define GET_HWCAPS_OR_FAIL(fallback_impl) return fallback_impl -#endif +#ifdef INTRINSICCV_HAVE_SVE2 static inline bool hwcaps_has_sve2(HwCaps hwcaps) { return hwcaps.hwcap2 & (1 << 1); } -static inline bool hwcaps_has_sme2(HwCaps hwcaps) { - // Actually checks for SME, not SME2, but this will be changed to check for - // SME2 in future. - const int kSMEBit = 23; - return hwcaps.hwcap2 & (1UL << kSMEBit); -} - -#if INTRINSICCV_ALWAYS_ENABLE_SVE2 -#define INTRINSICCV_SVE2_IMPL_IF(func) func -#else -#define INTRINSICCV_SVE2_IMPL_IF(func) nullptr -#endif - -#ifdef INTRINSICCV_HAVE_SVE2 #define INTRINSICCV_SVE2_RESOLVE(sve2_impl) \ if (!std::is_null_pointer_v && \ hwcaps_has_sve2(hwcaps)) { \ return sve2_impl; \ } - #else -#define INTRINSICCV_SVE2_RESOLVE(sve2_impl) +#define INTRINSICCV_SVE2_RESOLVE(x) #endif #ifdef INTRINSICCV_HAVE_SME2 +static inline bool hwcaps_has_sme2(HwCaps hwcaps) { + // Actually checks for SME, not SME2, but this will be changed to check for + // SME2 in future. + const int kSMEBit = 23; + return hwcaps.hwcap2 & (1UL << kSMEBit); +} + #define INTRINSICCV_SME2_RESOLVE(sme2_impl) \ if (!std::is_null_pointer_v && \ hwcaps_has_sme2(hwcaps)) { \ return sme2_impl; \ } #else -#define INTRINSICCV_SME2_RESOLVE(sme2_impl) +#define INTRINSICCV_SME2_RESOLVE(x) +#endif + +#define INTRINSICCV_DECLARE_RESOLVER(api_name, neon_impl, sve2_impl, \ + sme2_impl) \ + static decltype(neon_impl) *api_name##_resolver() { \ + [[maybe_unused]] HwCaps hwcaps = get_hwcaps(); \ + INTRINSICCV_SME2_RESOLVE(sme2_impl); \ + INTRINSICCV_SVE2_RESOLVE(sve2_impl); \ + return neon_impl; \ + } +#else +#define INTRINSICCV_DECLARE_RESOLVER(api_name, neon_impl, sve2_impl, \ + sme2_impl) \ + static decltype(neon_impl) *api_name##_resolver() { return neon_impl; } #endif -// Creates a multiversioned C API with a resolver for it -#define INTRINSICCV_MULTIVERSION_C_API(api_name, neon_impl, sve2_impl, \ - sme2_impl, ...) \ - static decltype(neon_impl) *api_name##_resolver() { \ - GET_HWCAPS_OR_FAIL(neon_impl); \ - INTRINSICCV_SME2_RESOLVE(sme2_impl); \ - INTRINSICCV_SVE2_RESOLVE(sve2_impl); \ - return neon_impl; \ - } \ - \ - extern "C" { \ - decltype(neon_impl) *api_name = api_name##_resolver(); \ +#define INTRINSICCV_MULTIVERSION_C_API(api_name, neon_impl, sve2_impl, \ + sme2_impl, ...) \ + INTRINSICCV_DECLARE_RESOLVER(api_name, neon_impl, sve2_impl, sme2_impl) \ + \ + extern "C" { \ + decltype(neon_impl) *api_name = api_name##_resolver(); \ } } // namespace intrinsiccv -- GitLab From ef9a21c25536e38ab972dd0e98bbffd29f8d22f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Igor=20Podgain=C3=B5i?= Date: Thu, 14 Mar 2024 16:04:33 +0100 Subject: [PATCH 7/7] Remove __VA_ARGS__ from INTRINSICCV_MULTIVERSION_C_API --- intrinsiccv/include/intrinsiccv/dispatch.h | 2 +- intrinsiccv/src/analysis/min_max_api.cpp | 6 ++---- intrinsiccv/src/arithmetics/absdiff_api.cpp | 3 +-- .../src/arithmetics/add_abs_with_threshold_api.cpp | 14 ++++++-------- intrinsiccv/src/arithmetics/add_api.cpp | 3 +-- intrinsiccv/src/arithmetics/multiply_api.cpp | 3 +-- intrinsiccv/src/arithmetics/scale_api.cpp | 7 +++---- intrinsiccv/src/arithmetics/sub_api.cpp | 3 +-- intrinsiccv/src/arithmetics/threshold_api.cpp | 11 +++++------ intrinsiccv/src/arithmetics/transpose_api.cpp | 4 +--- intrinsiccv/src/conversions/gray_to_rgb_api.cpp | 11 +++++------ intrinsiccv/src/conversions/merge_api.cpp | 3 +-- intrinsiccv/src/conversions/rgb_to_rgb_api.cpp | 11 +++++------ intrinsiccv/src/conversions/split_api.cpp | 6 +----- intrinsiccv/src/conversions/yuv_to_rgb_api.cpp | 9 ++++----- intrinsiccv/src/filters/gaussian_blur_api.cpp | 11 ++--------- intrinsiccv/src/filters/sobel_api.cpp | 12 +++++------- intrinsiccv/src/morphology/morphology_api.cpp | 12 +++++------- intrinsiccv/src/resize/resize_api.cpp | 4 +--- 19 files changed, 51 insertions(+), 84 deletions(-) diff --git a/intrinsiccv/include/intrinsiccv/dispatch.h b/intrinsiccv/include/intrinsiccv/dispatch.h index c5c86b817..5ccea8fbf 100644 --- a/intrinsiccv/include/intrinsiccv/dispatch.h +++ b/intrinsiccv/include/intrinsiccv/dispatch.h @@ -80,7 +80,7 @@ static inline bool hwcaps_has_sme2(HwCaps hwcaps) { #endif #define INTRINSICCV_MULTIVERSION_C_API(api_name, neon_impl, sve2_impl, \ - sme2_impl, ...) \ + sme2_impl) \ INTRINSICCV_DECLARE_RESOLVER(api_name, neon_impl, sve2_impl, sme2_impl) \ \ extern "C" { \ diff --git a/intrinsiccv/src/analysis/min_max_api.cpp b/intrinsiccv/src/analysis/min_max_api.cpp index 1c79bcd17..389f7236f 100644 --- a/intrinsiccv/src/analysis/min_max_api.cpp +++ b/intrinsiccv/src/analysis/min_max_api.cpp @@ -27,8 +27,7 @@ namespace sme2 {} // namespace sme2 #define INTRINSICCV_DEFINE_MINMAX_API(name, type) \ INTRINSICCV_MULTIVERSION_C_API(name, intrinsiccv::neon::min_max, \ - nullptr, nullptr, const type *, size_t, \ - size_t, size_t, type *, type *) + nullptr, nullptr) INTRINSICCV_DEFINE_MINMAX_API(intrinsiccv_min_max_u8, uint8_t); INTRINSICCV_DEFINE_MINMAX_API(intrinsiccv_min_max_s8, int8_t); @@ -38,8 +37,7 @@ INTRINSICCV_DEFINE_MINMAX_API(intrinsiccv_min_max_s32, int32_t); #define INTRINSICCV_DEFINE_MINMAXLOC_API(name, type) \ INTRINSICCV_MULTIVERSION_C_API(name, intrinsiccv::neon::min_max_loc, \ - nullptr, nullptr, const type *, size_t, \ - size_t, size_t, size_t *, size_t *) + nullptr, nullptr) INTRINSICCV_DEFINE_MINMAXLOC_API(intrinsiccv_min_max_loc_u8, uint8_t); diff --git a/intrinsiccv/src/arithmetics/absdiff_api.cpp b/intrinsiccv/src/arithmetics/absdiff_api.cpp index 7f1d40ef4..4c54344e9 100644 --- a/intrinsiccv/src/arithmetics/absdiff_api.cpp +++ b/intrinsiccv/src/arithmetics/absdiff_api.cpp @@ -41,8 +41,7 @@ intrinsiccv_error_t saturating_absdiff(const T *src_a, size_t src_a_stride, INTRINSICCV_MULTIVERSION_C_API( \ name, intrinsiccv::neon::saturating_absdiff, \ INTRINSICCV_SVE2_IMPL_IF(intrinsiccv::sve2::saturating_absdiff), \ - intrinsiccv::sme2::saturating_absdiff, const type *, size_t, \ - const type *, size_t, type *, size_t, size_t, size_t) + intrinsiccv::sme2::saturating_absdiff) INTRINSICCV_DEFINE_C_API(intrinsiccv_saturating_absdiff_u8, uint8_t); INTRINSICCV_DEFINE_C_API(intrinsiccv_saturating_absdiff_s8, int8_t); diff --git a/intrinsiccv/src/arithmetics/add_abs_with_threshold_api.cpp b/intrinsiccv/src/arithmetics/add_abs_with_threshold_api.cpp index e4c24b563..247073431 100644 --- a/intrinsiccv/src/arithmetics/add_abs_with_threshold_api.cpp +++ b/intrinsiccv/src/arithmetics/add_abs_with_threshold_api.cpp @@ -32,14 +32,12 @@ intrinsiccv_error_t saturating_add_abs_with_threshold( } // namespace sme2 -#define INTRINSICCV_DEFINE_C_API(name, type) \ - INTRINSICCV_MULTIVERSION_C_API( \ - name, intrinsiccv::neon::saturating_add_abs_with_threshold, \ - INTRINSICCV_SVE2_IMPL_IF( \ - intrinsiccv::sve2::saturating_add_abs_with_threshold), \ - intrinsiccv::sme2::saturating_add_abs_with_threshold, \ - const type *, size_t, const type *, size_t, type *, size_t, size_t, \ - size_t, type) +#define INTRINSICCV_DEFINE_C_API(name, type) \ + INTRINSICCV_MULTIVERSION_C_API( \ + name, intrinsiccv::neon::saturating_add_abs_with_threshold, \ + INTRINSICCV_SVE2_IMPL_IF( \ + intrinsiccv::sve2::saturating_add_abs_with_threshold), \ + intrinsiccv::sme2::saturating_add_abs_with_threshold) INTRINSICCV_DEFINE_C_API(intrinsiccv_saturating_add_abs_with_threshold_s16, int16_t); diff --git a/intrinsiccv/src/arithmetics/add_api.cpp b/intrinsiccv/src/arithmetics/add_api.cpp index 9461b4e87..a900dd031 100644 --- a/intrinsiccv/src/arithmetics/add_api.cpp +++ b/intrinsiccv/src/arithmetics/add_api.cpp @@ -41,8 +41,7 @@ intrinsiccv_error_t saturating_add(const T *src_a, size_t src_a_stride, INTRINSICCV_MULTIVERSION_C_API( \ name, intrinsiccv::neon::saturating_add, \ INTRINSICCV_SVE2_IMPL_IF(intrinsiccv::sve2::saturating_add), \ - intrinsiccv::sme2::saturating_add, const type *, size_t, \ - const type *, size_t, type *, size_t, size_t, size_t) + intrinsiccv::sme2::saturating_add) INTRINSICCV_DEFINE_C_API(intrinsiccv_saturating_add_s8, int8_t); INTRINSICCV_DEFINE_C_API(intrinsiccv_saturating_add_u8, uint8_t); diff --git a/intrinsiccv/src/arithmetics/multiply_api.cpp b/intrinsiccv/src/arithmetics/multiply_api.cpp index 7367ff599..5514f6f7c 100644 --- a/intrinsiccv/src/arithmetics/multiply_api.cpp +++ b/intrinsiccv/src/arithmetics/multiply_api.cpp @@ -42,8 +42,7 @@ intrinsiccv_error_t saturating_multiply(const T *src_a, size_t src_a_stride, INTRINSICCV_MULTIVERSION_C_API( \ name, intrinsiccv::neon::saturating_multiply, \ INTRINSICCV_SVE2_IMPL_IF(intrinsiccv::sve2::saturating_multiply), \ - nullptr, const type *, size_t, const type *, size_t, type *, size_t, \ - size_t, size_t, double) + nullptr) INTRINSICCV_DEFINE_C_API(intrinsiccv_saturating_multiply_u8, uint8_t); INTRINSICCV_DEFINE_C_API(intrinsiccv_saturating_multiply_s8, int8_t); diff --git a/intrinsiccv/src/arithmetics/scale_api.cpp b/intrinsiccv/src/arithmetics/scale_api.cpp index 40479a543..3241bb0f8 100644 --- a/intrinsiccv/src/arithmetics/scale_api.cpp +++ b/intrinsiccv/src/arithmetics/scale_api.cpp @@ -20,10 +20,9 @@ namespace sve2 {} // namespace sve2 namespace sme2 {} // namespace sme2 -#define INTRINSICCV_DEFINE_SCALE_API(name, type) \ - INTRINSICCV_MULTIVERSION_C_API(name, intrinsiccv::neon::scale, \ - nullptr, nullptr, const type *, size_t, \ - type *, size_t, size_t, size_t, float, float) +#define INTRINSICCV_DEFINE_SCALE_API(name, type) \ + INTRINSICCV_MULTIVERSION_C_API(name, intrinsiccv::neon::scale, \ + nullptr, nullptr) INTRINSICCV_DEFINE_SCALE_API(intrinsiccv_scale_u8, uint8_t); // INTRINSICCV_DEFINE_SCALE_API(intrinsiccv_scale_s8, int8_t); diff --git a/intrinsiccv/src/arithmetics/sub_api.cpp b/intrinsiccv/src/arithmetics/sub_api.cpp index 30fc22ad7..2b5fbac51 100644 --- a/intrinsiccv/src/arithmetics/sub_api.cpp +++ b/intrinsiccv/src/arithmetics/sub_api.cpp @@ -40,8 +40,7 @@ intrinsiccv_error_t saturating_sub(const T *src_a, size_t src_a_stride, INTRINSICCV_MULTIVERSION_C_API( \ name, intrinsiccv::neon::saturating_sub, \ INTRINSICCV_SVE2_IMPL_IF(intrinsiccv::sve2::saturating_sub), \ - intrinsiccv::sme2::saturating_sub, const type *, size_t, \ - const type *, size_t, type *, size_t, size_t, size_t) + intrinsiccv::sme2::saturating_sub) INTRINSICCV_DEFINE_C_API(intrinsiccv_saturating_sub_s8, int8_t); INTRINSICCV_DEFINE_C_API(intrinsiccv_saturating_sub_u8, uint8_t); diff --git a/intrinsiccv/src/arithmetics/threshold_api.cpp b/intrinsiccv/src/arithmetics/threshold_api.cpp index 51d36abbd..f9e962d06 100644 --- a/intrinsiccv/src/arithmetics/threshold_api.cpp +++ b/intrinsiccv/src/arithmetics/threshold_api.cpp @@ -28,12 +28,11 @@ intrinsiccv_error_t threshold_binary(const T *src, size_t src_stride, T *dst, size_t height, T threshold, T value); } // namespace sme2 -#define INTRINSICCV_DEFINE_C_API(name, type) \ - INTRINSICCV_MULTIVERSION_C_API( \ - name, intrinsiccv::neon::threshold_binary, \ - INTRINSICCV_SVE2_IMPL_IF(intrinsiccv::sve2::threshold_binary), \ - intrinsiccv::sme2::threshold_binary, const type *, size_t, type *, \ - size_t, size_t, size_t, type, type) +#define INTRINSICCV_DEFINE_C_API(name, type) \ + INTRINSICCV_MULTIVERSION_C_API( \ + name, intrinsiccv::neon::threshold_binary, \ + INTRINSICCV_SVE2_IMPL_IF(intrinsiccv::sve2::threshold_binary), \ + intrinsiccv::sme2::threshold_binary) INTRINSICCV_DEFINE_C_API(intrinsiccv_threshold_binary_u8, uint8_t); diff --git a/intrinsiccv/src/arithmetics/transpose_api.cpp b/intrinsiccv/src/arithmetics/transpose_api.cpp index 5611c31e9..208e5832f 100644 --- a/intrinsiccv/src/arithmetics/transpose_api.cpp +++ b/intrinsiccv/src/arithmetics/transpose_api.cpp @@ -9,8 +9,6 @@ namespace intrinsiccv { INTRINSICCV_MULTIVERSION_C_API(intrinsiccv_transpose, - intrinsiccv::neon::transpose, nullptr, nullptr, - const void *, size_t, void *, size_t, size_t, - size_t, size_t); + intrinsiccv::neon::transpose, nullptr, nullptr); } // namespace intrinsiccv diff --git a/intrinsiccv/src/conversions/gray_to_rgb_api.cpp b/intrinsiccv/src/conversions/gray_to_rgb_api.cpp index 2466a0b4a..f4573d8f7 100644 --- a/intrinsiccv/src/conversions/gray_to_rgb_api.cpp +++ b/intrinsiccv/src/conversions/gray_to_rgb_api.cpp @@ -8,12 +8,11 @@ namespace intrinsiccv { -#define INTRINSICCV_DEFINE_C_API(name, partialname) \ - INTRINSICCV_MULTIVERSION_C_API( \ - name, intrinsiccv::neon::partialname, \ - INTRINSICCV_SVE2_IMPL_IF(intrinsiccv::sve2::partialname), \ - intrinsiccv::sme2::partialname, const uint8_t *src, size_t src_stride, \ - uint8_t *dst, size_t dst_stride, size_t width, size_t height) +#define INTRINSICCV_DEFINE_C_API(name, partialname) \ + INTRINSICCV_MULTIVERSION_C_API( \ + name, intrinsiccv::neon::partialname, \ + INTRINSICCV_SVE2_IMPL_IF(intrinsiccv::sve2::partialname), \ + intrinsiccv::sme2::partialname) INTRINSICCV_DEFINE_C_API(intrinsiccv_gray_to_rgb_u8, gray_to_rgb_u8); INTRINSICCV_DEFINE_C_API(intrinsiccv_gray_to_rgba_u8, gray_to_rgba_u8); diff --git a/intrinsiccv/src/conversions/merge_api.cpp b/intrinsiccv/src/conversions/merge_api.cpp index 5c66e7863..7af61c3c0 100644 --- a/intrinsiccv/src/conversions/merge_api.cpp +++ b/intrinsiccv/src/conversions/merge_api.cpp @@ -9,7 +9,6 @@ namespace intrinsiccv { INTRINSICCV_MULTIVERSION_C_API(intrinsiccv_merge, intrinsiccv::neon::merge, - nullptr, nullptr, const void **, const size_t *, - void *, size_t, size_t, size_t, size_t, size_t); + nullptr, nullptr); } // namespace intrinsiccv diff --git a/intrinsiccv/src/conversions/rgb_to_rgb_api.cpp b/intrinsiccv/src/conversions/rgb_to_rgb_api.cpp index e9eb93521..4d3ec4874 100644 --- a/intrinsiccv/src/conversions/rgb_to_rgb_api.cpp +++ b/intrinsiccv/src/conversions/rgb_to_rgb_api.cpp @@ -9,12 +9,11 @@ namespace intrinsiccv { -#define INTRINSICCV_DEFINE_C_API(name, partialname) \ - INTRINSICCV_MULTIVERSION_C_API( \ - name, intrinsiccv::neon::partialname, \ - INTRINSICCV_SVE2_IMPL_IF(intrinsiccv::sve2::partialname), \ - intrinsiccv::sme2::partialname, const uint8_t *src, size_t src_stride, \ - uint8_t *dst, size_t dst_stride, size_t width, size_t height) +#define INTRINSICCV_DEFINE_C_API(name, partialname) \ + INTRINSICCV_MULTIVERSION_C_API( \ + name, intrinsiccv::neon::partialname, \ + INTRINSICCV_SVE2_IMPL_IF(intrinsiccv::sve2::partialname), \ + intrinsiccv::sme2::partialname) INTRINSICCV_DEFINE_C_API(intrinsiccv_rgb_to_bgr_u8, rgb_to_bgr_u8); INTRINSICCV_DEFINE_C_API(intrinsiccv_rgba_to_bgra_u8, rgba_to_bgra_u8); diff --git a/intrinsiccv/src/conversions/split_api.cpp b/intrinsiccv/src/conversions/split_api.cpp index 6673fba22..968667bb2 100644 --- a/intrinsiccv/src/conversions/split_api.cpp +++ b/intrinsiccv/src/conversions/split_api.cpp @@ -9,10 +9,6 @@ namespace intrinsiccv { INTRINSICCV_MULTIVERSION_C_API(intrinsiccv_split, intrinsiccv::neon::split, - nullptr, nullptr, const void *src_data, - size_t src_stride, void **dst_data, - const size_t *dst_strides, size_t width, - size_t height, size_t channels, - size_t element_size); + nullptr, nullptr); } // namespace intrinsiccv diff --git a/intrinsiccv/src/conversions/yuv_to_rgb_api.cpp b/intrinsiccv/src/conversions/yuv_to_rgb_api.cpp index f315641eb..ff6a63f61 100644 --- a/intrinsiccv/src/conversions/yuv_to_rgb_api.cpp +++ b/intrinsiccv/src/conversions/yuv_to_rgb_api.cpp @@ -8,11 +8,10 @@ namespace intrinsiccv { -#define INTRINSICCV_DEFINE_C_API(name, partialname) \ - INTRINSICCV_MULTIVERSION_C_API( \ - name, intrinsiccv::neon::partialname, intrinsiccv::sve2::partialname, \ - intrinsiccv::sme2::partialname, const uint8_t *, size_t, \ - const uint8_t *, size_t, uint8_t *, size_t, size_t, size_t, bool) +#define INTRINSICCV_DEFINE_C_API(name, partialname) \ + INTRINSICCV_MULTIVERSION_C_API(name, intrinsiccv::neon::partialname, \ + intrinsiccv::sve2::partialname, \ + intrinsiccv::sme2::partialname) INTRINSICCV_DEFINE_C_API(intrinsiccv_yuv_sp_to_rgb_u8, yuv_sp_to_rgb_u8); INTRINSICCV_DEFINE_C_API(intrinsiccv_yuv_sp_to_bgr_u8, yuv_sp_to_bgr_u8); diff --git a/intrinsiccv/src/filters/gaussian_blur_api.cpp b/intrinsiccv/src/filters/gaussian_blur_api.cpp index 7ef7e9725..fd9e2b6ba 100644 --- a/intrinsiccv/src/filters/gaussian_blur_api.cpp +++ b/intrinsiccv/src/filters/gaussian_blur_api.cpp @@ -54,18 +54,11 @@ intrinsiccv_error_t intrinsiccv_filter_release( INTRINSICCV_MULTIVERSION_C_API(intrinsiccv_gaussian_blur_3x3_u8, intrinsiccv::neon::gaussian_blur_3x3_u8, nullptr, - nullptr, const uint8_t *src, size_t src_stride, - uint8_t *dst, size_t dst_stride, size_t width, - size_t height, size_t channels, - intrinsiccv_border_type_t border_type, - intrinsiccv_filter_context_t *context); + nullptr); INTRINSICCV_MULTIVERSION_C_API( intrinsiccv_gaussian_blur_5x5_u8, intrinsiccv::neon::gaussian_blur_5x5_u8, INTRINSICCV_SVE2_IMPL_IF(intrinsiccv::sve2::gaussian_blur_5x5_u8), - intrinsiccv::sme2::gaussian_blur_5x5_u8, const uint8_t *src, - size_t src_stride, uint8_t *dst, size_t dst_stride, size_t width, - size_t height, size_t channels, intrinsiccv_border_type_t border_type, - intrinsiccv_filter_context_t *context); + intrinsiccv::sme2::gaussian_blur_5x5_u8); } // namespace intrinsiccv diff --git a/intrinsiccv/src/filters/sobel_api.cpp b/intrinsiccv/src/filters/sobel_api.cpp index 6a74ee2cd..509262324 100644 --- a/intrinsiccv/src/filters/sobel_api.cpp +++ b/intrinsiccv/src/filters/sobel_api.cpp @@ -8,13 +8,11 @@ namespace intrinsiccv { -#define INTRINSICCV_DEFINE_C_API(name, partialname) \ - INTRINSICCV_MULTIVERSION_C_API( \ - name, intrinsiccv::neon::partialname, \ - INTRINSICCV_SVE2_IMPL_IF(intrinsiccv::sve2::partialname), \ - intrinsiccv::sme2::partialname, const uint8_t *src, size_t src_stride, \ - int16_t *dst, size_t dst_stride, size_t width, size_t height, \ - size_t channels) +#define INTRINSICCV_DEFINE_C_API(name, partialname) \ + INTRINSICCV_MULTIVERSION_C_API( \ + name, intrinsiccv::neon::partialname, \ + INTRINSICCV_SVE2_IMPL_IF(intrinsiccv::sve2::partialname), \ + intrinsiccv::sme2::partialname) INTRINSICCV_DEFINE_C_API(intrinsiccv_sobel_3x3_horizontal_s16_u8, sobel_3x3_horizontal_s16_u8); diff --git a/intrinsiccv/src/morphology/morphology_api.cpp b/intrinsiccv/src/morphology/morphology_api.cpp index 19e9922f3..0b351f592 100644 --- a/intrinsiccv/src/morphology/morphology_api.cpp +++ b/intrinsiccv/src/morphology/morphology_api.cpp @@ -104,13 +104,11 @@ intrinsiccv_error_t intrinsiccv_morphology_release( } // extern "C" -#define INTRINSICCV_DEFINE_C_API(name, tname, type) \ - INTRINSICCV_MULTIVERSION_C_API( \ - name, intrinsiccv::neon::tname, \ - INTRINSICCV_SVE2_IMPL_IF(intrinsiccv::sve2::tname), \ - intrinsiccv::sme2::tname, const type *src, size_t src_stride, \ - type *dst, size_t dst_stride, size_t width, size_t height, \ - intrinsiccv_morphology_context_t *) +#define INTRINSICCV_DEFINE_C_API(name, tname, type) \ + INTRINSICCV_MULTIVERSION_C_API( \ + name, intrinsiccv::neon::tname, \ + INTRINSICCV_SVE2_IMPL_IF(intrinsiccv::sve2::tname), \ + intrinsiccv::sme2::tname) INTRINSICCV_DEFINE_C_API(intrinsiccv_dilate_u8, dilate, uint8_t); INTRINSICCV_DEFINE_C_API(intrinsiccv_erode_u8, erode, uint8_t); diff --git a/intrinsiccv/src/resize/resize_api.cpp b/intrinsiccv/src/resize/resize_api.cpp index 3ffad7a5c..461f9e95d 100644 --- a/intrinsiccv/src/resize/resize_api.cpp +++ b/intrinsiccv/src/resize/resize_api.cpp @@ -11,8 +11,6 @@ namespace intrinsiccv { INTRINSICCV_MULTIVERSION_C_API( intrinsiccv_resize_to_quarter_u8, intrinsiccv::neon::resize_to_quarter_u8, INTRINSICCV_SVE2_IMPL_IF(intrinsiccv::sve2::resize_to_quarter_u8), - intrinsiccv::sme2::resize_to_quarter_u8, const uint8_t *src, - size_t src_stride, size_t src_width, size_t src_height, uint8_t *dst, - size_t dst_stride, size_t dst_width, size_t dst_height); + intrinsiccv::sme2::resize_to_quarter_u8); } // namespace intrinsiccv -- GitLab