diff --git a/hal/ipp/CMakeLists.txt b/hal/ipp/CMakeLists.txt index 4774cf55fb..c83182df12 100644 --- a/hal/ipp/CMakeLists.txt +++ b/hal/ipp/CMakeLists.txt @@ -46,6 +46,13 @@ if(WITH_IPP_CALLS_ENFORCED) message("WITH_IPP_CALLS_ENFORCED=${WITH_IPP_CALLS_ENFORCED}: enforced IPP calls are enabled in IPP HAL") endif() +# Enable cv::instr tracing of IPP calls inside the HAL so they show up in the +# instrumentation trace / IPP weight. Reuses the engine exported from +# opencv_core (symbols resolved at link time as ipphal is archived into core). +if(ENABLE_INSTRUMENTATION) + target_compile_definitions(ipphal PRIVATE ENABLE_INSTRUMENTATION) +endif() + target_include_directories(ipphal PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/include") ocv_warnings_disable(CMAKE_CXX_FLAGS -Wno-suggest-override) diff --git a/hal/ipp/include/ipp_utils.hpp b/hal/ipp/include/ipp_utils.hpp index 3edef486df..ff512332fd 100644 --- a/hal/ipp/include/ipp_utils.hpp +++ b/hal/ipp/include/ipp_utils.hpp @@ -1,6 +1,7 @@ // This file is part of OpenCV project. // It is subject to the license terms in the LICENSE file found in the top-level directory // of this distribution and at http://opencv.org/license.html +// Copyright (C) 2026, Intel Corporation, all rights reserved. #ifndef __IPP_HAL_UTILS_HPP__ #define __IPP_HAL_UTILS_HPP__ @@ -23,7 +24,22 @@ # include "ipp.h" #endif +// IPP call instrumentation for the standalone IPP HAL. +// +// The HAL is built as a separate static library that does not include the +// internal core/private.hpp, so by default its IPP calls never appear in the +// cv::instr trace (reported IPP weight = 0%). When the parent build enables +// ENABLE_INSTRUMENTATION, the shared instrumentation.private.hpp provides the +// exact same CV_INSTRUMENT_FUN_IPP macro used by core (backed by symbols exported +// from libopencv_core, resolved at link time), so HAL IPP calls are traced +// identically to in-module ones. Otherwise the no-op passthrough is used. +#if !defined(CV_INSTRUMENT_FUN_IPP) +#if defined(ENABLE_INSTRUMENTATION) +#include "opencv2/core/utils/instrumentation.private.hpp" +#else #define CV_INSTRUMENT_FUN_IPP(FUN, ...) ((FUN)(__VA_ARGS__)) +#endif // defined(ENABLE_INSTRUMENTATION) +#endif // !defined(CV_INSTRUMENT_FUN_IPP) #define CV_HAL_CHECK_USE_IPP() if(!cv::ipp::useIPP()) return CV_HAL_ERROR_NOT_IMPLEMENTED; diff --git a/modules/core/include/opencv2/core/private.hpp b/modules/core/include/opencv2/core/private.hpp index 769fb9f605..f171a4d429 100644 --- a/modules/core/include/opencv2/core/private.hpp +++ b/modules/core/include/opencv2/core/private.hpp @@ -690,23 +690,13 @@ public: TLSData tlsStruct; }; -class CV_EXPORTS IntrumentationRegion -{ -public: - IntrumentationRegion(const char* funName, const char* fileName, int lineNum, void *retAddress, bool alwaysExpand, TYPE instrType = TYPE_GENERAL, IMPL implType = IMPL_PLAIN); - ~IntrumentationRegion(); - -private: - bool m_disabled; // region status - uint64 m_regionTicks; -}; - CV_EXPORTS InstrStruct& getInstrumentStruct(); InstrTLSStruct& getInstrumentTLSStruct(); -CV_EXPORTS InstrNode* getCurrentNode(); } } +#include "opencv2/core/utils/instrumentation.private.hpp" + #ifdef _WIN32 #define CV_INSTRUMENT_GET_RETURN_ADDRESS _ReturnAddress() #else @@ -718,45 +708,6 @@ CV_EXPORTS InstrNode* getCurrentNode(); #define CV_INSTRUMENT_REGION_CUSTOM_META(NAME, ALWAYS_EXPAND, TYPE, IMPL)\ void *CVAUX_CONCAT(__curr_address__, __LINE__) = [&]() {return CV_INSTRUMENT_GET_RETURN_ADDRESS;}();\ ::cv::instr::IntrumentationRegion CVAUX_CONCAT(__instr_region__, __LINE__) (NAME, __FILE__, __LINE__, CVAUX_CONCAT(__curr_address__, __LINE__), false, ::cv::instr::TYPE_GENERAL, ::cv::instr::IMPL_PLAIN); -// Instrument functions with non-void return type -#define CV_INSTRUMENT_FUN_RT_META(TYPE, IMPL, ERROR_COND, FUN, ...) ([&]()\ -{\ - if(::cv::instr::useInstrumentation()){\ - ::cv::instr::IntrumentationRegion __instr__(#FUN, __FILE__, __LINE__, NULL, false, TYPE, IMPL);\ - try{\ - auto instrStatus = ((FUN)(__VA_ARGS__));\ - if(ERROR_COND){\ - ::cv::instr::getCurrentNode()->m_payload.m_funError = true;\ - CV_INSTRUMENT_MARK_META(IMPL, #FUN " - BadExit");\ - }\ - return instrStatus;\ - }catch(...){\ - ::cv::instr::getCurrentNode()->m_payload.m_funError = true;\ - CV_INSTRUMENT_MARK_META(IMPL, #FUN " - BadExit");\ - throw;\ - }\ - }else{\ - return ((FUN)(__VA_ARGS__));\ - }\ -}()) -// Instrument functions with void return type -#define CV_INSTRUMENT_FUN_RV_META(TYPE, IMPL, FUN, ...) ([&]()\ -{\ - if(::cv::instr::useInstrumentation()){\ - ::cv::instr::IntrumentationRegion __instr__(#FUN, __FILE__, __LINE__, NULL, false, TYPE, IMPL);\ - try{\ - (FUN)(__VA_ARGS__);\ - }catch(...){\ - ::cv::instr::getCurrentNode()->m_payload.m_funError = true;\ - CV_INSTRUMENT_MARK_META(IMPL, #FUN "- BadExit");\ - throw;\ - }\ - }else{\ - (FUN)(__VA_ARGS__);\ - }\ -}()) -// Instrumentation information marker -#define CV_INSTRUMENT_MARK_META(IMPL, NAME, ...) {::cv::instr::IntrumentationRegion __instr_mark__(NAME, __FILE__, __LINE__, NULL, false, ::cv::instr::TYPE_MARKER, IMPL);} ///// General instrumentation // General OpenCV region instrumentation macro @@ -769,10 +720,6 @@ CV_EXPORTS InstrNode* getCurrentNode(); ///// IPP instrumentation // Wrapper region instrumentation macro #define CV_INSTRUMENT_REGION_IPP(); CV_INSTRUMENT_REGION_META(__FUNCTION__, false, ::cv::instr::TYPE_WRAPPER, ::cv::instr::IMPL_IPP) -// Function instrumentation macro -#define CV_INSTRUMENT_FUN_IPP(FUN, ...) CV_INSTRUMENT_FUN_RT_META(::cv::instr::TYPE_FUN, ::cv::instr::IMPL_IPP, instrStatus < 0, FUN, __VA_ARGS__) -// Diagnostic markers -#define CV_INSTRUMENT_MARK_IPP(NAME) CV_INSTRUMENT_MARK_META(::cv::instr::IMPL_IPP, NAME) ///// OpenCL instrumentation // Wrapper region instrumentation macro diff --git a/modules/core/include/opencv2/core/utils/instrumentation.private.hpp b/modules/core/include/opencv2/core/utils/instrumentation.private.hpp new file mode 100644 index 0000000000..012b83cf30 --- /dev/null +++ b/modules/core/include/opencv2/core/utils/instrumentation.private.hpp @@ -0,0 +1,88 @@ +// This file is part of OpenCV project. +// It is subject to the license terms in the LICENSE file found in the top-level directory +// of this distribution and at http://opencv.org/license.html. +// Copyright (C) 2026, Intel Corporation, all rights reserved. + +#ifndef OPENCV_CORE_UTILS_INSTRUMENTATION_PRIVATE_HPP +#define OPENCV_CORE_UTILS_INSTRUMENTATION_PRIVATE_HPP + +#include "opencv2/core/utils/instrumentation.hpp" + +// Region-based function-instrumentation primitives. +// +// Only meaningful when the build was configured with ENABLE_INSTRUMENTATION; +// otherwise this header contributes nothing and each includer provides its own +// no-op fallbacks. The IntrumentationRegion / getCurrentNode() definitions are +// compiled into and exported (CV_EXPORTS) from the core library, so the HAL only +// needs these declarations and resolves the symbols at link time. + +#ifdef ENABLE_INSTRUMENTATION + +namespace cv { namespace instr { + +// Scoped region: records one instrumentation node on construction and closes it +// on destruction. Defined in modules/core/src/system.cpp. +class CV_EXPORTS IntrumentationRegion +{ +public: + IntrumentationRegion(const char* funName, const char* fileName, int lineNum, void *retAddress, + bool alwaysExpand, TYPE instrType = TYPE_GENERAL, IMPL implType = IMPL_PLAIN); + ~IntrumentationRegion(); + +private: + bool m_disabled; // region status + uint64 m_regionTicks; +}; + +CV_EXPORTS InstrNode* getCurrentNode(); + +}} // namespace cv::instr + +// Instrumentation information marker +#define CV_INSTRUMENT_MARK_META(IMPL, NAME, ...) {::cv::instr::IntrumentationRegion __instr_mark__(NAME, __FILE__, __LINE__, NULL, false, ::cv::instr::TYPE_MARKER, IMPL);} + +// Instrument functions with non-void return type +#define CV_INSTRUMENT_FUN_RT_META(TYPE, IMPL, ERROR_COND, FUN, ...) ([&]() \ +{ \ + if(::cv::instr::useInstrumentation()){ \ + ::cv::instr::IntrumentationRegion __instr__(#FUN, __FILE__, __LINE__, NULL, false, TYPE, IMPL); \ + try{ \ + auto instrStatus = ((FUN)(__VA_ARGS__)); \ + if(ERROR_COND){ \ + ::cv::instr::getCurrentNode()->m_payload.m_funError = true; \ + CV_INSTRUMENT_MARK_META(IMPL, #FUN " - BadExit"); \ + } \ + return instrStatus; \ + }catch(...){ \ + ::cv::instr::getCurrentNode()->m_payload.m_funError = true; \ + CV_INSTRUMENT_MARK_META(IMPL, #FUN " - BadExit"); \ + throw; \ + } \ + }else{ \ + return ((FUN)(__VA_ARGS__)); \ + } \ +}()) +// Instrument functions with void return type +#define CV_INSTRUMENT_FUN_RV_META(TYPE, IMPL, FUN, ...) ([&]() \ +{ \ + if(::cv::instr::useInstrumentation()){ \ + ::cv::instr::IntrumentationRegion __instr__(#FUN, __FILE__, __LINE__, NULL, false, TYPE, IMPL); \ + try{ \ + (FUN)(__VA_ARGS__); \ + }catch(...){ \ + ::cv::instr::getCurrentNode()->m_payload.m_funError = true; \ + CV_INSTRUMENT_MARK_META(IMPL, #FUN " - BadExit"); \ + throw; \ + } \ + }else{ \ + (FUN)(__VA_ARGS__); \ + } \ +}()) + +// IPP function instrumentation macros +#define CV_INSTRUMENT_FUN_IPP(FUN, ...) CV_INSTRUMENT_FUN_RT_META(::cv::instr::TYPE_FUN, ::cv::instr::IMPL_IPP, instrStatus < 0, FUN, __VA_ARGS__) +#define CV_INSTRUMENT_MARK_IPP(NAME) CV_INSTRUMENT_MARK_META(::cv::instr::IMPL_IPP, NAME) + +#endif // ENABLE_INSTRUMENTATION + +#endif // OPENCV_CORE_UTILS_INSTRUMENTATION_PRIVATE_HPP