OpenCVDetectCUDA.cmake 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255
  1. if((WIN32 AND NOT MSVC) OR OPENCV_CMAKE_FORCE_CUDA)
  2. message(STATUS "CUDA: Compilation is disabled (due to only Visual Studio compiler supported on your platform).")
  3. return()
  4. endif()
  5. if((NOT UNIX AND CV_CLANG) OR OPENCV_CMAKE_FORCE_CUDA)
  6. message(STATUS "CUDA: Compilation is disabled (due to Clang unsupported on your platform).")
  7. return()
  8. endif()
  9. #set(OPENCV_CMAKE_CUDA_DEBUG 1)
  10. if(CUDA_TOOLKIT_ROOT_DIR)
  11. set(CUDA_TOOLKIT_TARGET_DIR ${CUDA_TOOLKIT_ROOT_DIR})
  12. endif()
  13. if(((NOT CMAKE_VERSION VERSION_LESS "3.9.0") # requires https://gitlab.kitware.com/cmake/cmake/merge_requests/663
  14. OR OPENCV_CUDA_FORCE_EXTERNAL_CMAKE_MODULE)
  15. AND NOT OPENCV_CUDA_FORCE_BUILTIN_CMAKE_MODULE)
  16. ocv_update(CUDA_LINK_LIBRARIES_KEYWORD "PRIVATE")
  17. find_host_package(CUDA "${MIN_VER_CUDA}" QUIET)
  18. else()
  19. # Use OpenCV's patched "FindCUDA" module
  20. set(CMAKE_MODULE_PATH "${OpenCV_SOURCE_DIR}/cmake" ${CMAKE_MODULE_PATH})
  21. if(ANDROID)
  22. set(CUDA_TARGET_OS_VARIANT "Android")
  23. endif()
  24. find_host_package(CUDA "${MIN_VER_CUDA}" QUIET)
  25. list(REMOVE_AT CMAKE_MODULE_PATH 0)
  26. endif()
  27. if(NOT CUDA_FOUND)
  28. unset(CUDA_ARCH_BIN CACHE)
  29. unset(CUDA_ARCH_PTX CACHE)
  30. return()
  31. endif()
  32. unset(CUDA_nvcuvenc_LIBRARY CACHE)
  33. set(HAVE_CUDA 1)
  34. if(NOT CUDA_VERSION VERSION_LESS 11.0)
  35. # CUDA 11.0 removes nppicom
  36. ocv_list_filterout(CUDA_nppi_LIBRARY "nppicom")
  37. ocv_list_filterout(CUDA_npp_LIBRARY "nppicom")
  38. endif()
  39. if(WITH_CUFFT)
  40. set(HAVE_CUFFT 1)
  41. endif()
  42. if(WITH_CUBLAS)
  43. set(HAVE_CUBLAS 1)
  44. endif()
  45. if(WITH_CUDNN)
  46. set(CMAKE_MODULE_PATH "${OpenCV_SOURCE_DIR}/cmake" ${CMAKE_MODULE_PATH})
  47. find_host_package(CUDNN "${MIN_VER_CUDNN}")
  48. list(REMOVE_AT CMAKE_MODULE_PATH 0)
  49. if(CUDNN_FOUND)
  50. set(HAVE_CUDNN 1)
  51. endif()
  52. endif()
  53. include(cmake/OpenCVDetectCUDAUtils.cmake)
  54. if(WITH_NVCUVID OR WITH_NVCUVENC)
  55. set(cuda_toolkit_dirs "${CUDA_TOOLKIT_TARGET_DIR}" "${CUDA_TOOLKIT_ROOT_DIR}")
  56. ocv_check_for_nvidia_video_codec_sdk("${cuda_toolkit_dirs}")
  57. endif()
  58. message(STATUS "CUDA detected: " ${CUDA_VERSION})
  59. ocv_set_cuda_detection_nvcc_flags(CUDA_HOST_COMPILER)
  60. ocv_set_cuda_arch_bin_and_ptx(${CUDA_NVCC_EXECUTABLE})
  61. # NVCC flags to be set
  62. set(NVCC_FLAGS_EXTRA "")
  63. # These vars will be passed into the templates
  64. set(OPENCV_CUDA_ARCH_BIN "")
  65. set(OPENCV_CUDA_ARCH_PTX "")
  66. set(OPENCV_CUDA_ARCH_FEATURES "")
  67. # Tell NVCC to add binaries for the specified GPUs
  68. string(REGEX MATCHALL "[0-9()]+" ARCH_LIST "${ARCH_BIN_NO_POINTS}")
  69. foreach(ARCH IN LISTS ARCH_LIST)
  70. if(ARCH MATCHES "([0-9]+)\\(([0-9]+)\\)")
  71. # User explicitly specified PTX for the concrete BIN
  72. set(NVCC_FLAGS_EXTRA ${NVCC_FLAGS_EXTRA} -gencode arch=compute_${CMAKE_MATCH_2},code=sm_${CMAKE_MATCH_1})
  73. set(OPENCV_CUDA_ARCH_BIN "${OPENCV_CUDA_ARCH_BIN} ${CMAKE_MATCH_1}")
  74. set(OPENCV_CUDA_ARCH_FEATURES "${OPENCV_CUDA_ARCH_FEATURES} ${CMAKE_MATCH_2}")
  75. else()
  76. # User didn't explicitly specify PTX for the concrete BIN, we assume PTX=BIN
  77. set(NVCC_FLAGS_EXTRA ${NVCC_FLAGS_EXTRA} -gencode arch=compute_${ARCH},code=sm_${ARCH})
  78. set(OPENCV_CUDA_ARCH_BIN "${OPENCV_CUDA_ARCH_BIN} ${ARCH}")
  79. set(OPENCV_CUDA_ARCH_FEATURES "${OPENCV_CUDA_ARCH_FEATURES} ${ARCH}")
  80. endif()
  81. endforeach()
  82. set(NVCC_FLAGS_EXTRA ${NVCC_FLAGS_EXTRA} -D_FORCE_INLINES)
  83. # Tell NVCC to add PTX intermediate code for the specified architectures
  84. string(REGEX MATCHALL "[0-9]+" ARCH_LIST "${ARCH_PTX_NO_POINTS}")
  85. foreach(ARCH IN LISTS ARCH_LIST)
  86. set(NVCC_FLAGS_EXTRA ${NVCC_FLAGS_EXTRA} -gencode arch=compute_${ARCH},code=compute_${ARCH})
  87. set(OPENCV_CUDA_ARCH_PTX "${OPENCV_CUDA_ARCH_PTX} ${ARCH}")
  88. set(OPENCV_CUDA_ARCH_FEATURES "${OPENCV_CUDA_ARCH_FEATURES} ${ARCH}")
  89. endforeach()
  90. # These vars will be processed in other scripts
  91. set(CUDA_NVCC_FLAGS ${CUDA_NVCC_FLAGS} ${NVCC_FLAGS_EXTRA})
  92. set(OpenCV_CUDA_CC "${NVCC_FLAGS_EXTRA}")
  93. if(ANDROID)
  94. set(CUDA_NVCC_FLAGS ${CUDA_NVCC_FLAGS} "-Xptxas;-dlcm=ca")
  95. endif()
  96. ocv_set_nvcc_threads_for_vs()
  97. message(STATUS "CUDA: NVCC target flags ${CUDA_NVCC_FLAGS}")
  98. OCV_OPTION(CUDA_FAST_MATH "Enable --use_fast_math for CUDA compiler " OFF)
  99. if(CUDA_FAST_MATH)
  100. set(CUDA_NVCC_FLAGS ${CUDA_NVCC_FLAGS} --use_fast_math)
  101. endif()
  102. OCV_OPTION(CUDA_ENABLE_DELAYLOAD "Enable delayed loading of CUDA DLLs" OFF VISIBLE_IF MSVC)
  103. mark_as_advanced(CUDA_BUILD_CUBIN CUDA_BUILD_EMULATION CUDA_VERBOSE_BUILD CUDA_SDK_ROOT_DIR)
  104. macro(ocv_check_windows_crt_linkage)
  105. # The new MSVC runtime abstraction is only useable if CUDA is a first class language
  106. if(WIN32 AND POLICY CMP0091)
  107. cmake_policy(GET CMP0091 MSVC_RUNTIME_SET_BY_ABSTRACTION)
  108. if(MSVC_RUNTIME_SET_BY_ABSTRACTION STREQUAL "NEW")
  109. if(NOT BUILD_SHARED_LIBS AND BUILD_WITH_STATIC_CRT)
  110. set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MT")
  111. set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MTd")
  112. else()
  113. set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MD")
  114. set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MDd")
  115. endif()
  116. endif()
  117. endif()
  118. endmacro()
  119. macro(ocv_cuda_compile VAR)
  120. ocv_cuda_filter_options()
  121. ocv_check_windows_crt_linkage()
  122. ocv_nvcc_flags()
  123. if(NOT " ${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_RELEASE} ${CMAKE_CXX_FLAGS_DEBUG} ${CUDA_NVCC_FLAGS}" MATCHES "-std=")
  124. if(CUDA_VERSION VERSION_LESS "11.0")
  125. # Windows version does not support --std option
  126. if(UNIX OR APPLE)
  127. list(APPEND CUDA_NVCC_FLAGS "--std=c++11")
  128. endif()
  129. elseif(CUDA_VERSION VERSION_LESS "12.8")
  130. list(APPEND CUDA_NVCC_FLAGS "--std=c++14")
  131. elseif(CUDA_VERSION VERSION_GREATER_EQUAL "12.8")
  132. list(APPEND CUDA_NVCC_FLAGS "--std=c++17")
  133. endif()
  134. endif()
  135. CUDA_COMPILE(${VAR} ${ARGN})
  136. foreach(var CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_RELEASE CMAKE_CXX_FLAGS_DEBUG)
  137. set(${var} "${${var}_backup_in_cuda_compile_}")
  138. unset(${var}_backup_in_cuda_compile_)
  139. endforeach()
  140. endmacro()
  141. if(HAVE_CUDA)
  142. set(CUDA_LIBS_PATH "")
  143. foreach(p ${CUDA_LIBRARIES} ${CUDA_npp_LIBRARY})
  144. get_filename_component(_tmp ${p} PATH)
  145. list(APPEND CUDA_LIBS_PATH ${_tmp})
  146. endforeach()
  147. if(HAVE_CUBLAS)
  148. foreach(p ${CUDA_cublas_LIBRARY})
  149. get_filename_component(_tmp ${p} PATH)
  150. list(APPEND CUDA_LIBS_PATH ${_tmp})
  151. endforeach()
  152. endif()
  153. if(HAVE_CUDNN)
  154. foreach(p ${CUDNN_LIBRARIES})
  155. get_filename_component(_tmp ${p} PATH)
  156. list(APPEND CUDA_LIBS_PATH ${_tmp})
  157. endforeach()
  158. endif()
  159. if(HAVE_CUFFT)
  160. foreach(p ${CUDA_cufft_LIBRARY})
  161. get_filename_component(_tmp ${p} PATH)
  162. list(APPEND CUDA_LIBS_PATH ${_tmp})
  163. endforeach()
  164. endif()
  165. list(REMOVE_DUPLICATES CUDA_LIBS_PATH)
  166. link_directories(${CUDA_LIBS_PATH})
  167. set(CUDA_LIBRARIES_ABS ${CUDA_LIBRARIES})
  168. ocv_convert_to_lib_name(CUDA_LIBRARIES ${CUDA_LIBRARIES})
  169. set(CUDA_npp_LIBRARY_ABS ${CUDA_npp_LIBRARY})
  170. ocv_convert_to_lib_name(CUDA_npp_LIBRARY ${CUDA_npp_LIBRARY})
  171. if(HAVE_CUBLAS)
  172. set(CUDA_cublas_LIBRARY_ABS ${CUDA_cublas_LIBRARY})
  173. ocv_convert_to_lib_name(CUDA_cublas_LIBRARY ${CUDA_cublas_LIBRARY})
  174. endif()
  175. if(HAVE_CUDNN)
  176. set(CUDNN_LIBRARIES_ABS ${CUDNN_LIBRARIES})
  177. ocv_convert_to_lib_name(CUDNN_LIBRARIES ${CUDNN_LIBRARIES})
  178. endif()
  179. if(HAVE_CUFFT)
  180. set(CUDA_cufft_LIBRARY_ABS ${CUDA_cufft_LIBRARY})
  181. ocv_convert_to_lib_name(CUDA_cufft_LIBRARY ${CUDA_cufft_LIBRARY})
  182. endif()
  183. if(CMAKE_GENERATOR MATCHES "Visual Studio"
  184. AND NOT OPENCV_SKIP_CUDA_CMAKE_SUPPRESS_REGENERATION
  185. )
  186. message(STATUS "CUDA: MSVS generator is detected. Disabling CMake re-run checks (CMAKE_SUPPRESS_REGENERATION=ON). You need to run CMake manually if updates are required.")
  187. set(CMAKE_SUPPRESS_REGENERATION ON)
  188. endif()
  189. endif()
  190. if(HAVE_CUDA)
  191. ocv_apply_cuda_stub_workaround("${CUDA_CUDA_LIBRARY}")
  192. ocv_check_cuda_delayed_load("${CUDA_TOOLKIT_ROOT_DIR}")
  193. # ----------------------------------------------------------------------------
  194. # Add CUDA libraries (needed for apps/tools, samples)
  195. # ----------------------------------------------------------------------------
  196. set(OPENCV_LINKER_LIBS ${OPENCV_LINKER_LIBS} ${CUDA_LIBRARIES} ${CUDA_npp_LIBRARY})
  197. if(HAVE_CUBLAS)
  198. set(OPENCV_LINKER_LIBS ${OPENCV_LINKER_LIBS} ${CUDA_cublas_LIBRARY})
  199. endif()
  200. if(HAVE_CUDNN)
  201. set(OPENCV_LINKER_LIBS ${OPENCV_LINKER_LIBS} ${CUDNN_LIBRARIES})
  202. endif()
  203. if(HAVE_CUFFT)
  204. set(OPENCV_LINKER_LIBS ${OPENCV_LINKER_LIBS} ${CUDA_cufft_LIBRARY})
  205. endif()
  206. foreach(p ${CUDA_LIBS_PATH})
  207. if(MSVC AND CMAKE_GENERATOR MATCHES "Ninja|JOM")
  208. set(OPENCV_LINKER_LIBS ${OPENCV_LINKER_LIBS} ${CMAKE_LIBRARY_PATH_FLAG}"${p}")
  209. else()
  210. set(OPENCV_LINKER_LIBS ${OPENCV_LINKER_LIBS} ${CMAKE_LIBRARY_PATH_FLAG}${p})
  211. endif()
  212. endforeach()
  213. endif()