From cfebdae08def7e854243b94a69ec8f6f7adfc41f Mon Sep 17 00:00:00 2001 From: Prasadayus <22bcs191@iiitdmj.ac.in> Date: Mon, 7 Sep 2026 18:47:03 +0530 Subject: [PATCH] Resize IPP HAL: atomic status flag and compile-time dispatch tables --- hal/ipp/src/resize_ipp.cpp | 47 ++++++++++++++++++++++++++------------ 1 file changed, 33 insertions(+), 14 deletions(-) diff --git a/hal/ipp/src/resize_ipp.cpp b/hal/ipp/src/resize_ipp.cpp index 8708a4e7ae..9db944c656 100644 --- a/hal/ipp/src/resize_ipp.cpp +++ b/hal/ipp/src/resize_ipp.cpp @@ -11,6 +11,7 @@ #include "iw++/iw.hpp" +#include #include #include @@ -21,7 +22,7 @@ template class ipp_resizeParallelT: public cv::ParallelLoopBody { public: - ipp_resizeParallelT(::ipp::IwiImage &src, ::ipp::IwiImage &dst, bool &ok): + ipp_resizeParallelT(::ipp::IwiImage &src, ::ipp::IwiImage &dst, std::atomic_bool &ok): m_src(src), m_dst(dst), m_ok(ok) {} void Init(IppiInterpolationType inter) @@ -33,7 +34,7 @@ public: void Init(IppiInterpolationType inter, double scaleX, double scaleY) { - double shift = (inter == ippNearest)?-1e-10:-0.5; + double shift = (inter == ippNearest) ? -1e-10 : -0.5; double coeffs[2][3] = { {scaleX, 0, shift+0.5*scaleX}, {0, scaleY, shift+0.5*scaleY} @@ -69,7 +70,7 @@ private: mutable IwiOp iwiOp; - volatile bool &m_ok; + std::atomic_bool &m_ok; ipp_resizeParallelT& operator= (const ipp_resizeParallelT&); }; @@ -86,20 +87,38 @@ int ipp_hal_resize(int src_type, const uchar *src_data, size_t src_step, int src IppDataType ippDataType = ippiGetDataType(depth); IppiInterpolationType ippInter = ippiGetInterpolation(interpolation); - if((int)ippInter < 0) + int interpIdx = interpolation & cv::InterpolationFlags::INTER_MAX; + if((int)ippInter < 0 || interpIdx > 4 || channels > 4) return CV_HAL_ERROR_NOT_IMPLEMENTED; - // Resize which doesn't match OpenCV exactly - if (!cv::ipp::useIPP_NotExact()) - { - if (ippInter == ippNearest || ippInter == ippSuper || (ippDataType == ipp8u && ippInter == ippLinear)) - return CV_HAL_ERROR_NOT_IMPLEMENTED; - } +#if defined(IPP_CALLS_ENFORCED) - if(ippInter != ippLinear && ippDataType == ipp64f) + const char impl[CV_DEPTH_MAX][4][5] = { /* N L C S Z */ + /* 8U */ {{1, 1, 1, 1, 1},{0, 0, 0, 0, 0},{1, 1, 1, 1, 1},{1, 1, 1, 1, 1}}, + /* 8S */ {{0, 0, 0, 0, 0},{0, 0, 0, 0, 0},{0, 0, 0, 0, 0},{0, 0, 0, 0, 0}}, + /* 16U */ {{1, 1, 1, 1, 1},{0, 0, 0, 0, 0},{1, 1, 1, 1, 1},{1, 1, 1, 1, 1}}, + /* 16S */ {{1, 1, 1, 1, 1},{0, 0, 0, 0, 0},{1, 1, 1, 1, 1},{1, 1, 1, 1, 1}}, + /* 32S */ {{0, 0, 0, 0, 0},{0, 0, 0, 0, 0},{0, 0, 0, 0, 0},{0, 0, 0, 0, 0}}, + /* 32F */ {{1, 1, 1, 1, 1},{0, 0, 0, 0, 0},{1, 1, 1, 1, 1},{1, 1, 1, 1, 1}}, + /* 64F */ {{0, 1, 0, 0, 0},{0, 0, 0, 0, 0},{0, 1, 0, 0, 0},{0, 1, 0, 0, 0}}, + /* 16F */ {{0, 0, 0, 0, 0},{0, 0, 0, 0, 0},{0, 0, 0, 0, 0},{0, 0, 0, 0, 0}}}; +#else // IPP_CALLS_ENFORCED is not defined, results are strictly aligned to OpenCV implementation + + const char impl[CV_DEPTH_MAX][4][5] = { /* N L C S Z */ + /* 8U */ {{0, 0, 1, 0, 1},{0, 0, 0, 0, 0},{0, 0, 1, 0, 1},{0, 0, 1, 0, 1}}, + /* 8S */ {{0, 0, 0, 0, 0},{0, 0, 0, 0, 0},{0, 0, 0, 0, 0},{0, 0, 0, 0, 0}}, + /* 16U */ {{0, 1, 1, 0, 1},{0, 0, 0, 0, 0},{0, 1, 1, 0, 1},{0, 1, 1, 0, 1}}, + /* 16S */ {{0, 1, 1, 0, 1},{0, 0, 0, 0, 0},{0, 1, 1, 0, 1},{0, 1, 1, 0, 1}}, + /* 32S */ {{0, 0, 0, 0, 0},{0, 0, 0, 0, 0},{0, 0, 0, 0, 0},{0, 0, 0, 0, 0}}, + /* 32F */ {{0, 1, 1, 0, 1},{0, 0, 0, 0, 0},{0, 1, 1, 0, 1},{0, 1, 1, 0, 1}}, + /* 64F */ {{0, 1, 0, 0, 0},{0, 0, 0, 0, 0},{0, 1, 0, 0, 0},{0, 1, 0, 0, 0}}, + /* 16F */ {{0, 0, 0, 0, 0},{0, 0, 0, 0, 0},{0, 0, 0, 0, 0},{0, 0, 0, 0, 0}}}; +#endif + + if (impl[depth][channels - 1][interpIdx] == 0) return CV_HAL_ERROR_NOT_IMPLEMENTED; -#if IPP_VERSION_X100 < 201801 +#if IPP_VERSION_X100 < 201801 && !defined(IPP_CALLS_ENFORCED) // Degradations on int^2 linear downscale if (ippDataType != ipp64f && ippInter == ippLinear && inv_scale_x < 1 && inv_scale_y < 1) // if downscale { @@ -114,7 +133,7 @@ int ipp_hal_resize(int src_type, const uchar *src_data, size_t src_step, int src #endif bool affine = false; - const double IPP_RESIZE_EPS = (depth == CV_64F)?0:1e-10; + const double IPP_RESIZE_EPS = (depth == CV_64F) ? 0 : 1e-10; double ex = fabs((double)dst_width / src_width - inv_scale_x) / inv_scale_x; double ey = fabs((double)dst_height / src_height - inv_scale_y) / inv_scale_y; @@ -131,7 +150,7 @@ int ipp_hal_resize(int src_type, const uchar *src_data, size_t src_step, int src ::ipp::IwiImage iwSrc(::ipp::IwiSize(src_width, src_height), ippDataType, channels, 0, (void*)src_data, src_step); ::ipp::IwiImage iwDst(::ipp::IwiSize(dst_width, dst_height), ippDataType, channels, 0, (void*)dst_data, dst_step); - bool ok; + std::atomic_bool ok{true}; int threads = ippiSuggestThreadsNum(iwDst, 1+((double)(src_width*src_height)/(dst_width*dst_height))); cv::Range range(0, dst_height); ipp_resizeParallel invokerGeneral(iwSrc, iwDst, ok);