From e16382025cdfd008806fd4e4b6d5a7862f963099 Mon Sep 17 00:00:00 2001 From: Savya Sanchi Sharma Date: Thu, 27 Aug 2026 12:01:21 +0530 Subject: [PATCH] Merge pull request #29658 from SavyaSanchi-Sharma:cudnnjit This PR is about Introducing cuDNN JIT support for the DNN Module ### 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 - [ ] There is a reference to the original bug report and related work - [ ] There is accuracy test, performance test and test data in opencv_extra repository, if applicable Patch to opencv_extra has the same branch name. - [ ] The feature is well documented and sample code can be built with the project CMake --- CMakeLists.txt | 8 +++ cmake/FindCUDNNJIT.cmake | 71 +++++++++++++++++++ cmake/OpenCVDetectCUDA.cmake | 28 ++++++++ cmake/OpenCVDetectCUDALanguage.cmake | 14 ++++ cmake/OpenCVMinDepVersions.cmake | 1 + cmake/templates/cvconfig.h.in | 1 + modules/dnn/CMakeLists.txt | 14 ++-- .../INIT_MODULE_SOURCES_opencv_dnn.cmake | 2 +- modules/dnn/src/cuda4dnn/csl/cudnn/cudnn.hpp | 5 ++ 9 files changed, 136 insertions(+), 8 deletions(-) create mode 100644 cmake/FindCUDNNJIT.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index 6cf4ab51fa..d45d86a767 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -204,6 +204,9 @@ OCV_OPTION(WITH_CUBLAS "Include NVidia Cuda Basic Linear Algebra Subprograms (BL OCV_OPTION(WITH_CUDNN "Include NVIDIA CUDA Deep Neural Network (cuDNN) library support" WITH_CUDA VISIBLE_IF WITH_CUDA VERIFY HAVE_CUDNN) +OCV_OPTION(WITH_CUDNNJIT "Include NVIDIA CUDA Deep Neural Network (cuDNN) graph API support with runtime compiled (JIT) engines, used only when WITH_CUDNN is off" OFF + VISIBLE_IF WITH_CUDA + VERIFY HAVE_CUDNNJIT OR HAVE_CUDNN) OCV_OPTION(WITH_NVCUVID "Include NVidia Video Decoding library support" ON VISIBLE_IF WITH_CUDA VERIFY HAVE_NVCUVID) @@ -1912,6 +1915,11 @@ if(WITH_CUDA OR HAVE_CUDA) status(" cuDNN:" HAVE_CUDNN THEN "YES (ver ${CUDNN_VERSION})" ELSE NO) endif() + if(WITH_CUDNNJIT OR HAVE_CUDNNJIT) + status("") + status(" cuDNN JIT:" HAVE_CUDNNJIT THEN "YES (ver ${CUDNN_VERSION})" ELSE NO) +endif() + if(WITH_VULKAN OR HAVE_VULKAN) status("") status(" Vulkan:" HAVE_VULKAN THEN "YES" ELSE "NO") diff --git a/cmake/FindCUDNNJIT.cmake b/cmake/FindCUDNNJIT.cmake new file mode 100644 index 0000000000..19f2d2add4 --- /dev/null +++ b/cmake/FindCUDNNJIT.cmake @@ -0,0 +1,71 @@ +# template taken from https://cmake.org/cmake/help/v3.14/manual/cmake-developer.7.html + +# Distributed under the OSI-approved BSD 3-Clause License. See accompanying +# file Copyright.txt or https://cmake.org/licensing for details. + +if(CUDA_FOUND) + find_cuda_helper_libs(cudnn) + find_cuda_helper_libs(cudnn_graph) + find_cuda_helper_libs(cudnn_engines_runtime_compiled) + set(CUDNN_SHIM_LIBRARY ${CUDA_cudnn_LIBRARY} CACHE FILEPATH "location of the cuDNN dispatch shim library") + set(CUDNN_GRAPH_LIBRARY ${CUDA_cudnn_graph_LIBRARY} CACHE FILEPATH "location of the cuDNN graph library") + set(CUDNN_ENGINES_RTC_LIBRARY ${CUDA_cudnn_engines_runtime_compiled_LIBRARY} CACHE FILEPATH "location of the cuDNN runtime compiled engines library") + unset(CUDA_cudnn_LIBRARY CACHE) + unset(CUDA_cudnn_graph_LIBRARY CACHE) + unset(CUDA_cudnn_engines_runtime_compiled_LIBRARY CACHE) +endif() + +if(CUDNN_GRAPH_LIBRARY) + find_path(CUDNNJIT_INCLUDE_DIR + cudnn_graph.h + PATHS ${CUDA_TOOLKIT_INCLUDE} + DOC "location of cudnn_graph.h" + NO_DEFAULT_PATH + ) + + if(NOT CUDNNJIT_INCLUDE_DIR) + find_path(CUDNNJIT_INCLUDE_DIR + cudnn_graph.h + DOC "location of cudnn_graph.h" + ) + endif() +endif() + +if(CUDNNJIT_INCLUDE_DIR AND EXISTS "${CUDNNJIT_INCLUDE_DIR}/cudnn_version.h") + file(READ "${CUDNNJIT_INCLUDE_DIR}/cudnn_version.h" CUDNN_H_CONTENTS) + + string(REGEX MATCH "define CUDNN_MAJOR ([0-9]+)" _ "${CUDNN_H_CONTENTS}") + set(CUDNN_VERSION_MAJOR ${CMAKE_MATCH_1} CACHE INTERNAL "") + string(REGEX MATCH "define CUDNN_MINOR ([0-9]+)" _ "${CUDNN_H_CONTENTS}") + set(CUDNN_VERSION_MINOR ${CMAKE_MATCH_1} CACHE INTERNAL "") + string(REGEX MATCH "define CUDNN_PATCHLEVEL ([0-9]+)" _ "${CUDNN_H_CONTENTS}") + set(CUDNN_VERSION_PATCH ${CMAKE_MATCH_1} CACHE INTERNAL "") + + set(CUDNN_VERSION "${CUDNN_VERSION_MAJOR}.${CUDNN_VERSION_MINOR}.${CUDNN_VERSION_PATCH}") + + unset(CUDNN_H_CONTENTS) +endif() + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(CUDNNJIT + FOUND_VAR CUDNNJIT_FOUND + REQUIRED_VARS + CUDNN_SHIM_LIBRARY + CUDNN_GRAPH_LIBRARY + CUDNN_ENGINES_RTC_LIBRARY + CUDNNJIT_INCLUDE_DIR + VERSION_VAR CUDNN_VERSION +) + +if(CUDNNJIT_FOUND) + set(CUDNNJIT_LIBRARIES ${CUDNN_SHIM_LIBRARY} ${CUDNN_GRAPH_LIBRARY} ${CUDNN_ENGINES_RTC_LIBRARY}) + set(CUDNNJIT_INCLUDE_DIRS ${CUDNNJIT_INCLUDE_DIR}) +endif() + +mark_as_advanced( + CUDNN_SHIM_LIBRARY + CUDNN_GRAPH_LIBRARY + CUDNN_ENGINES_RTC_LIBRARY + CUDNNJIT_INCLUDE_DIR + CUDNN_VERSION +) diff --git a/cmake/OpenCVDetectCUDA.cmake b/cmake/OpenCVDetectCUDA.cmake index 900922f1b5..e0882011a6 100644 --- a/cmake/OpenCVDetectCUDA.cmake +++ b/cmake/OpenCVDetectCUDA.cmake @@ -65,6 +65,20 @@ if(WITH_CUDNN) endif() endif() +if(WITH_CUDNNJIT) + if(HAVE_CUDNN) + message(STATUS "CUDA: cuDNN found, ignoring WITH_CUDNNJIT. Configure with -DWITH_CUDNN=OFF to use the cuDNN graph API instead.") + else() + set(CMAKE_MODULE_PATH "${OpenCV_SOURCE_DIR}/cmake" ${CMAKE_MODULE_PATH}) + find_host_package(CUDNNJIT "${MIN_VER_CUDNNJIT}") + list(REMOVE_AT CMAKE_MODULE_PATH 0) + + if(CUDNNJIT_FOUND) + set(HAVE_CUDNNJIT 1) + endif() + endif() +endif() + include(cmake/OpenCVDetectCUDAUtils.cmake) if(WITH_NVCUVID OR WITH_NVCUVENC) @@ -195,6 +209,13 @@ if(HAVE_CUDA) endforeach() endif() + if(HAVE_CUDNNJIT) + foreach(p ${CUDNNJIT_LIBRARIES}) + get_filename_component(_tmp ${p} PATH) + list(APPEND CUDA_LIBS_PATH ${_tmp}) + endforeach() + endif() + if(HAVE_CUFFT) foreach(p ${CUDA_cufft_LIBRARY}) get_filename_component(_tmp ${p} PATH) @@ -217,6 +238,10 @@ if(HAVE_CUDA) set(CUDNN_LIBRARIES_ABS ${CUDNN_LIBRARIES}) ocv_convert_to_lib_name(CUDNN_LIBRARIES ${CUDNN_LIBRARIES}) endif() + if(HAVE_CUDNNJIT) + set(CUDNNJIT_LIBRARIES_ABS ${CUDNNJIT_LIBRARIES}) + ocv_convert_to_lib_name(CUDNNJIT_LIBRARIES ${CUDNNJIT_LIBRARIES}) + endif() if(HAVE_CUFFT) set(CUDA_cufft_LIBRARY_ABS ${CUDA_cufft_LIBRARY}) ocv_convert_to_lib_name(CUDA_cufft_LIBRARY ${CUDA_cufft_LIBRARY}) @@ -244,6 +269,9 @@ if(HAVE_CUDA) if(HAVE_CUDNN) set(OPENCV_LINKER_LIBS ${OPENCV_LINKER_LIBS} ${CUDNN_LIBRARIES}) endif() + if(HAVE_CUDNNJIT) + set(OPENCV_LINKER_LIBS ${OPENCV_LINKER_LIBS} ${CUDNNJIT_LIBRARIES}) + endif() if(HAVE_CUFFT) set(OPENCV_LINKER_LIBS ${OPENCV_LINKER_LIBS} ${CUDA_cufft_LIBRARY}) endif() diff --git a/cmake/OpenCVDetectCUDALanguage.cmake b/cmake/OpenCVDetectCUDALanguage.cmake index bc40134180..044972c87e 100644 --- a/cmake/OpenCVDetectCUDALanguage.cmake +++ b/cmake/OpenCVDetectCUDALanguage.cmake @@ -71,6 +71,20 @@ if(WITH_CUDNN) endif() endif() +if(WITH_CUDNNJIT) + if(HAVE_CUDNN) + message(STATUS "CUDA: cuDNN found, ignoring WITH_CUDNNJIT. Configure with -DWITH_CUDNN=OFF to use the cuDNN graph API instead.") + else() + set(CMAKE_MODULE_PATH "${OpenCV_SOURCE_DIR}/cmake" ${CMAKE_MODULE_PATH}) + find_host_package(CUDNNJIT "${MIN_VER_CUDNNJIT}") + list(REMOVE_AT CMAKE_MODULE_PATH 0) + + if(CUDNNJIT_FOUND) + set(HAVE_CUDNNJIT 1) + endif() + endif() +endif() + if(WITH_NVCUVID OR WITH_NVCUVENC) ocv_check_for_nvidia_video_codec_sdk("${CUDAToolkit_LIBRARY_ROOT}") endif() diff --git a/cmake/OpenCVMinDepVersions.cmake b/cmake/OpenCVMinDepVersions.cmake index 4b23dd964b..fee0df38f1 100644 --- a/cmake/OpenCVMinDepVersions.cmake +++ b/cmake/OpenCVMinDepVersions.cmake @@ -4,5 +4,6 @@ if(NOT DEFINED MIN_VER_CMAKE) endif() set(MIN_VER_CUDA 6.5) set(MIN_VER_CUDNN 7.5) +set(MIN_VER_CUDNNJIT 9.0) set(MIN_VER_PYTHON3 3.2) set(MIN_VER_ZLIB 1.2.3) diff --git a/cmake/templates/cvconfig.h.in b/cmake/templates/cvconfig.h.in index 0ce16fdc84..2595d448d2 100644 --- a/cmake/templates/cvconfig.h.in +++ b/cmake/templates/cvconfig.h.in @@ -36,6 +36,7 @@ /* NVIDIA CUDA Deep Neural Network (cuDNN) API*/ #cmakedefine HAVE_CUDNN +#cmakedefine HAVE_CUDNNJIT /* NVIDIA CUDA Fast Fourier Transform (FFT) API*/ #cmakedefine HAVE_CUFFT diff --git a/modules/dnn/CMakeLists.txt b/modules/dnn/CMakeLists.txt index 296a73fc85..eb449aa776 100644 --- a/modules/dnn/CMakeLists.txt +++ b/modules/dnn/CMakeLists.txt @@ -51,19 +51,19 @@ endif() ocv_option(OPENCV_DNN_CUDA "Build with CUDA support" HAVE_CUDA AND HAVE_CUBLAS - AND HAVE_CUDNN + AND (HAVE_CUDNN OR HAVE_CUDNNJIT) ) if(OPENCV_DNN_CUDA) - if(HAVE_CUDA AND HAVE_CUBLAS AND HAVE_CUDNN) + if(HAVE_CUDA AND HAVE_CUBLAS AND (HAVE_CUDNN OR HAVE_CUDNNJIT)) ocv_target_compile_definitions(${the_module} PRIVATE "CV_CUDA4DNN=1") else() if(NOT HAVE_CUDA) message(SEND_ERROR "DNN: CUDA backend requires CUDA Toolkit. Please resolve dependency or disable OPENCV_DNN_CUDA=OFF") elseif(NOT HAVE_CUBLAS) message(SEND_ERROR "DNN: CUDA backend requires cuBLAS. Please resolve dependency or disable OPENCV_DNN_CUDA=OFF") - elseif(NOT HAVE_CUDNN) - message(SEND_ERROR "DNN: CUDA backend requires cuDNN. Please resolve dependency or disable OPENCV_DNN_CUDA=OFF") + elseif(NOT HAVE_CUDNN AND NOT HAVE_CUDNNJIT) + message(SEND_ERROR "DNN: CUDA backend requires cuDNN (WITH_CUDNN) or the cuDNN graph API (WITH_CUDNNJIT). Please resolve dependency or disable OPENCV_DNN_CUDA=OFF") endif() endif() endif() @@ -461,8 +461,8 @@ else() set(sources_options EXCLUDE_OPENCL) endif() -if(OPENCV_DNN_CUDA AND HAVE_CUDA AND HAVE_CUBLAS AND HAVE_CUDNN) - list(APPEND include_dirs ${CUDA_TOOLKIT_INCLUDE} ${CUDNN_INCLUDE_DIRS}) +if(OPENCV_DNN_CUDA AND HAVE_CUDA AND HAVE_CUBLAS AND (HAVE_CUDNN OR HAVE_CUDNNJIT)) + list(APPEND include_dirs ${CUDA_TOOLKIT_INCLUDE} ${CUDNN_INCLUDE_DIRS} ${CUDNNJIT_INCLUDE_DIRS}) set(CC_LIST ${CUDA_ARCH_BIN}) separate_arguments(CC_LIST) foreach(cc ${CC_LIST}) @@ -472,7 +472,7 @@ if(OPENCV_DNN_CUDA AND HAVE_CUDA AND HAVE_CUBLAS AND HAVE_CUDNN) endforeach() unset(CC_LIST) if(ENABLE_CUDA_FIRST_CLASS_LANGUAGE) - list(APPEND libs CUDA::cudart${CUDA_LIB_EXT} ${CUDNN_LIBRARIES} CUDA::cublas${CUDA_LIB_EXT}) + list(APPEND libs CUDA::cudart${CUDA_LIB_EXT} ${CUDNN_LIBRARIES} ${CUDNNJIT_LIBRARIES} CUDA::cublas${CUDA_LIB_EXT}) if(NOT CUDA_VERSION VERSION_LESS 10.1) list(APPEND libs CUDA::cublasLt${CUDA_LIB_EXT}) endif() diff --git a/modules/dnn/cmake/hooks/INIT_MODULE_SOURCES_opencv_dnn.cmake b/modules/dnn/cmake/hooks/INIT_MODULE_SOURCES_opencv_dnn.cmake index a4d6802d11..ad5e5caafc 100644 --- a/modules/dnn/cmake/hooks/INIT_MODULE_SOURCES_opencv_dnn.cmake +++ b/modules/dnn/cmake/hooks/INIT_MODULE_SOURCES_opencv_dnn.cmake @@ -4,7 +4,7 @@ if(NOT (OPENCV_DNN_OPENCL AND HAVE_OPENCL)) ocv_list_filterout(OPENCV_MODULE_${the_module}_HEADERS "/ocl4dnn/") endif() -if(NOT (OPENCV_DNN_CUDA AND HAVE_CUDA AND HAVE_CUBLAS AND HAVE_CUDNN)) +if(NOT (OPENCV_DNN_CUDA AND HAVE_CUDA AND HAVE_CUBLAS AND (HAVE_CUDNN OR HAVE_CUDNNJIT))) message(STATUS "opencv_dnn: filter out cuda4dnn source code") ocv_list_filterout(OPENCV_MODULE_${the_module}_SOURCES "/cuda4dnn/") ocv_list_filterout(OPENCV_MODULE_${the_module}_HEADERS "/cuda4dnn/") diff --git a/modules/dnn/src/cuda4dnn/csl/cudnn/cudnn.hpp b/modules/dnn/src/cuda4dnn/csl/cudnn/cudnn.hpp index 9bd8fcfe3b..cb626ad4be 100644 --- a/modules/dnn/src/cuda4dnn/csl/cudnn/cudnn.hpp +++ b/modules/dnn/src/cuda4dnn/csl/cudnn/cudnn.hpp @@ -7,7 +7,12 @@ #include "../pointer.hpp" +#ifdef HAVE_CUDNN #include +#elif defined(HAVE_CUDNNJIT) +#include +#include +#endif #include #include