From df7d437b86b15f194c08616cea32be6725d7ae3a Mon Sep 17 00:00:00 2001 From: Varun Jaiswal <96684656+varun-jaiswal17@users.noreply.github.com> Date: Fri, 20 Mar 2026 11:12:56 +0530 Subject: [PATCH] Merge pull request #28663 from varun-jaiswal17:added-inRange-64double-SIMD Added SIMD support for 64 bit float and fallback for 64 bit int#28663 Merged with : https://github.com/opencv/ci-gha-workflow/pull/299 ### Pull Request Readiness Checklist See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request - [x] I agree to contribute to the project under Apache 2 License. - [x] To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV - [x] The PR is proposed to the proper branch - [x] There is a reference to the original bug report and related work - [x] There is accuracy test, performance test and test data in opencv_extra repository, if applicable Patch to opencv_extra has the same branch name. - [x] The feature is well documented and sample code can be built with the project CMake --- modules/core/src/arithm.cpp | 84 ++++++++++++++++++++++++++++++++++--- 1 file changed, 78 insertions(+), 6 deletions(-) diff --git a/modules/core/src/arithm.cpp b/modules/core/src/arithm.cpp index 0e971802c0..5093141aca 100644 --- a/modules/core/src/arithm.cpp +++ b/modules/core/src/arithm.cpp @@ -1726,9 +1726,11 @@ namespace cv template struct InRange_SIMD { - int operator () (const T *, const T *, const T *, uchar *, int) const + int operator () (const T * src1, const T * src2, const T * src3, uchar * dst, int len) const { - return 0; + for (int x = 0; x < len; x++) + dst[x] = (src2[x] <= src1[x] && src1[x] <= src3[x]) ? 255 : 0; + return len; } }; @@ -1937,6 +1939,76 @@ struct InRange_SIMD } }; +template <> +struct InRange_SIMD +{ + int operator () (const unsigned * src1, const unsigned * src2, const unsigned * src3, + uchar * dst, int len) const + { + int x = 0; + const int width = (int)VTraits::vlanes() * 2; + + for (; x <= len - width; x += width) + { + v_uint32 values1 = vx_load(src1 + x); + v_uint32 low1 = vx_load(src2 + x); + v_uint32 high1 = vx_load(src3 + x); + + v_uint32 values2 = vx_load(src1 + x + VTraits::vlanes()); + v_uint32 low2 = vx_load(src2 + x + VTraits::vlanes()); + v_uint32 high2 = vx_load(src3 + x + VTraits::vlanes()); + + v_pack_store(dst + x, v_reinterpret_as_u16(v_pack(v_and(v_ge(values1, low1), v_ge(high1, values1)), v_and(v_ge(values2, low2), v_ge(high2, values2))))); + } + vx_cleanup(); + return x; + } +}; + +#if CV_SIMD_64F + +template <> +struct InRange_SIMD +{ + int operator () (const double * src1, const double * src2, const double * src3, + uchar * dst, int len) const + { + int x = 0; + const int step = VTraits::vlanes(); + const int width = step * 4; + + for (; x <= len - width; x += width) + { + v_float64 v1 = vx_load(src1 + x); + v_float64 l1 = vx_load(src2 + x); + v_float64 h1 = vx_load(src3 + x); + v_uint64 m1 = v_reinterpret_as_u64(v_and(v_ge(v1, l1), v_ge(h1, v1))); + + v_float64 v2 = vx_load(src1 + x + step); + v_float64 l2 = vx_load(src2 + x + step); + v_float64 h2 = vx_load(src3 + x + step); + v_uint64 m2 = v_reinterpret_as_u64(v_and(v_ge(v2, l2), v_ge(h2, v2))); + + v_float64 v3 = vx_load(src1 + x + step * 2); + v_float64 l3 = vx_load(src2 + x + step * 2); + v_float64 h3 = vx_load(src3 + x + step * 2); + v_uint64 m3 = v_reinterpret_as_u64(v_and(v_ge(v3, l3), v_ge(h3, v3))); + + v_float64 v4 = vx_load(src1 + x + step * 3); + v_float64 l4 = vx_load(src2 + x + step * 3); + v_float64 h4 = vx_load(src3 + x + step * 3); + v_uint64 m4 = v_reinterpret_as_u64(v_and(v_ge(v4, l4), v_ge(h4, v4))); + + + v_pack_store(dst + x, v_pack(v_pack(m1, m2), v_pack(m3, m4))); + } + vx_cleanup(); + return x; + } +}; + +#endif + #endif template @@ -2080,13 +2152,13 @@ static InRangeFunc getInRangeFunc(int depth) (InRangeFunc)GET_OPTIMIZED(inRange16s), (InRangeFunc)GET_OPTIMIZED(inRange32s), (InRangeFunc)GET_OPTIMIZED(inRange32f), - (InRangeFunc)inRange64f, + (InRangeFunc)GET_OPTIMIZED(inRange64f), (InRangeFunc)inRange16f, (InRangeFunc)inRange16bf, 0, - (InRangeFunc)inRange64u, - (InRangeFunc)inRange64s, - (InRangeFunc)inRange32u, + (InRangeFunc)GET_OPTIMIZED(inRange64u), + (InRangeFunc)GET_OPTIMIZED(inRange64s), + (InRangeFunc)GET_OPTIMIZED(inRange32u), 0, };