OpenCVDetectCUDA.cmake 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581
  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(CUDA_FOUND)
  28. unset(CUDA_nvcuvenc_LIBRARY CACHE)
  29. set(HAVE_CUDA 1)
  30. if(NOT CUDA_VERSION VERSION_LESS 11.0)
  31. # CUDA 11.0 removes nppicom
  32. ocv_list_filterout(CUDA_nppi_LIBRARY "nppicom")
  33. ocv_list_filterout(CUDA_npp_LIBRARY "nppicom")
  34. endif()
  35. if(WITH_CUFFT)
  36. set(HAVE_CUFFT 1)
  37. endif()
  38. if(WITH_CUBLAS)
  39. set(HAVE_CUBLAS 1)
  40. endif()
  41. if(WITH_CUDNN)
  42. set(CMAKE_MODULE_PATH "${OpenCV_SOURCE_DIR}/cmake" ${CMAKE_MODULE_PATH})
  43. find_host_package(CUDNN "${MIN_VER_CUDNN}")
  44. list(REMOVE_AT CMAKE_MODULE_PATH 0)
  45. if(CUDNN_FOUND)
  46. set(HAVE_CUDNN 1)
  47. endif()
  48. endif()
  49. if(WITH_NVCUVID OR WITH_NVCUVENC)
  50. macro(ocv_cuda_SEARCH_NVCUVID_HEADER _filename _result)
  51. # place header file under CUDA_TOOLKIT_TARGET_DIR or CUDA_TOOLKIT_ROOT_DIR
  52. find_path(_header_result
  53. ${_filename}
  54. PATHS "${CUDA_TOOLKIT_TARGET_DIR}" "${CUDA_TOOLKIT_ROOT_DIR}"
  55. ENV CUDA_PATH
  56. ENV CUDA_INC_PATH
  57. PATH_SUFFIXES include
  58. NO_DEFAULT_PATH
  59. )
  60. if("x${_header_result}" STREQUAL "x_header_result-NOTFOUND")
  61. set(${_result} 0)
  62. else()
  63. set(${_result} 1)
  64. endif()
  65. unset(_header_result CACHE)
  66. endmacro()
  67. if(WITH_NVCUVID)
  68. ocv_cuda_SEARCH_NVCUVID_HEADER("nvcuvid.h" HAVE_NVCUVID_HEADER)
  69. ocv_cuda_SEARCH_NVCUVID_HEADER("dynlink_nvcuvid.h" HAVE_DYNLINK_NVCUVID_HEADER)
  70. find_cuda_helper_libs(nvcuvid)
  71. if(CUDA_nvcuvid_LIBRARY AND (${HAVE_NVCUVID_HEADER} OR ${HAVE_DYNLINK_NVCUVID_HEADER}))
  72. # make sure to have both header and library before enabling
  73. set(HAVE_NVCUVID 1)
  74. endif()
  75. endif()
  76. if(WITH_NVCUVENC)
  77. ocv_cuda_SEARCH_NVCUVID_HEADER("nvEncodeAPI.h" HAVE_NVCUVENC_HEADER)
  78. if(WIN32)
  79. find_cuda_helper_libs(nvencodeapi)
  80. else()
  81. find_cuda_helper_libs(nvidia-encode)
  82. endif()
  83. if((CUDA_nvencodeapi_LIBRARY OR CUDA_nvidia-encode_LIBRARY) AND ${HAVE_NVCUVENC_HEADER})
  84. set(HAVE_NVCUVENC 1)
  85. endif()
  86. endif()
  87. endif()
  88. message(STATUS "CUDA detected: " ${CUDA_VERSION})
  89. OCV_OPTION(CUDA_ENABLE_DEPRECATED_GENERATION "Enable deprecated generations in the list" OFF)
  90. set(_generations "Maxwell" "Pascal" "Volta" "Turing" "Ampere" "Lovelace" "Hopper")
  91. if(CUDA_ENABLE_DEPRECATED_GENERATION)
  92. set(_generations "Fermi" "${_generations}")
  93. set(_generations "Kepler" "${_generations}")
  94. endif()
  95. set(_arch_fermi "2.0")
  96. set(_arch_kepler "3.0;3.5;3.7")
  97. set(_arch_maxwell "5.0;5.2")
  98. set(_arch_pascal "6.0;6.1")
  99. set(_arch_volta "7.0")
  100. set(_arch_turing "7.5")
  101. set(_arch_ampere "8.0;8.6")
  102. set(_arch_lovelace "8.9")
  103. set(_arch_hopper "9.0")
  104. if(NOT CMAKE_CROSSCOMPILING)
  105. list(APPEND _generations "Auto")
  106. endif()
  107. set(CUDA_GENERATION "" CACHE STRING "Build CUDA device code only for specific GPU architecture. Leave empty to build for all architectures.")
  108. if( CMAKE_VERSION VERSION_GREATER "2.8" )
  109. set_property( CACHE CUDA_GENERATION PROPERTY STRINGS "" ${_generations} )
  110. endif()
  111. if(CUDA_GENERATION)
  112. if(NOT ";${_generations};" MATCHES ";${CUDA_GENERATION};")
  113. string(REPLACE ";" ", " _generations "${_generations}")
  114. message(FATAL_ERROR "ERROR: ${_generations} Generations are supported.")
  115. endif()
  116. unset(CUDA_ARCH_BIN CACHE)
  117. unset(CUDA_ARCH_PTX CACHE)
  118. endif()
  119. if(OPENCV_CUDA_DETECTION_NVCC_FLAGS MATCHES "-ccbin")
  120. # already specified by user
  121. elseif(CUDA_HOST_COMPILER AND EXISTS "${CUDA_HOST_COMPILER}")
  122. get_filename_component(c_compiler_realpath "${CMAKE_C_COMPILER}" REALPATH)
  123. # C compiler doesn't work with --run option, forcing C++ compiler instead
  124. if(CUDA_HOST_COMPILER STREQUAL c_compiler_realpath OR CUDA_HOST_COMPILER STREQUAL CMAKE_C_COMPILER)
  125. if(DEFINED CMAKE_CXX_COMPILER)
  126. get_filename_component(cxx_compiler_realpath "${CMAKE_CXX_COMPILER}" REALPATH)
  127. LIST(APPEND OPENCV_CUDA_DETECTION_NVCC_FLAGS -ccbin "${cxx_compiler_realpath}")
  128. else()
  129. message(STATUS "CUDA: CMAKE_CXX_COMPILER is not available. You may need to specify CUDA_HOST_COMPILER.")
  130. endif()
  131. else()
  132. LIST(APPEND OPENCV_CUDA_DETECTION_NVCC_FLAGS -ccbin "${CUDA_HOST_COMPILER}")
  133. endif()
  134. elseif(WIN32 AND CMAKE_LINKER) # Workaround for VS cl.exe not being in the env. path
  135. get_filename_component(host_compiler_bindir ${CMAKE_LINKER} DIRECTORY)
  136. LIST(APPEND OPENCV_CUDA_DETECTION_NVCC_FLAGS -ccbin "${host_compiler_bindir}")
  137. else()
  138. if(CUDA_HOST_COMPILER)
  139. message(STATUS "CUDA: CUDA_HOST_COMPILER='${CUDA_HOST_COMPILER}' is not valid, autodetection may not work. Specify OPENCV_CUDA_DETECTION_NVCC_FLAGS with -ccbin option for fix that")
  140. endif()
  141. endif()
  142. macro(ocv_filter_available_architecture result_list)
  143. set(__cache_key_check "${ARGN} : ${CUDA_NVCC_EXECUTABLE} ${OPENCV_CUDA_DETECTION_NVCC_FLAGS}")
  144. if(DEFINED OPENCV_CACHE_CUDA_SUPPORTED_CC AND OPENCV_CACHE_CUDA_SUPPORTED_CC_check STREQUAL __cache_key_check)
  145. set(${result_list} "${OPENCV_CACHE_CUDA_SUPPORTED_CC}")
  146. else()
  147. set(CC_LIST ${ARGN})
  148. foreach(target_arch ${CC_LIST})
  149. string(REPLACE "." "" target_arch_short "${target_arch}")
  150. set(NVCC_OPTION "-gencode;arch=compute_${target_arch_short},code=sm_${target_arch_short}")
  151. set(_cmd "${CUDA_NVCC_EXECUTABLE}" ${OPENCV_CUDA_DETECTION_NVCC_FLAGS} ${NVCC_OPTION} "${OpenCV_SOURCE_DIR}/cmake/checks/OpenCVDetectCudaArch.cu" --compile)
  152. execute_process(
  153. COMMAND ${_cmd}
  154. WORKING_DIRECTORY "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/"
  155. RESULT_VARIABLE _nvcc_res
  156. OUTPUT_VARIABLE _nvcc_out
  157. ERROR_VARIABLE _nvcc_err
  158. #ERROR_QUIET
  159. OUTPUT_STRIP_TRAILING_WHITESPACE
  160. )
  161. if(OPENCV_CMAKE_CUDA_DEBUG)
  162. message(WARNING "COMMAND: ${_cmd}")
  163. message(STATUS "Result: ${_nvcc_res}")
  164. message(STATUS "Out: ${_nvcc_out}")
  165. message(STATUS "Err: ${_nvcc_err}")
  166. endif()
  167. if(_nvcc_res EQUAL 0)
  168. LIST(APPEND ${result_list} "${target_arch}")
  169. endif()
  170. endforeach()
  171. string(STRIP "${${result_list}}" ${result_list})
  172. if(" ${${result_list}}" STREQUAL " ")
  173. message(WARNING "CUDA: Autodetection arch list is empty. Please enable OPENCV_CMAKE_CUDA_DEBUG=1 and check/specify OPENCV_CUDA_DETECTION_NVCC_FLAGS variable")
  174. endif()
  175. # cache detected values
  176. set(OPENCV_CACHE_CUDA_SUPPORTED_CC ${${result_list}} CACHE INTERNAL "")
  177. set(OPENCV_CACHE_CUDA_SUPPORTED_CC_check "${__cache_key_check}" CACHE INTERNAL "")
  178. endif()
  179. endmacro()
  180. macro(ocv_detect_native_cuda_arch status output)
  181. set(OPENCV_CUDA_DETECT_ARCHS_COMMAND "${CUDA_NVCC_EXECUTABLE}" ${OPENCV_CUDA_DETECTION_NVCC_FLAGS} "${OpenCV_SOURCE_DIR}/cmake/checks/OpenCVDetectCudaArch.cu" "--run")
  182. set(__cache_key_check "${OPENCV_CUDA_DETECT_ARCHS_COMMAND}")
  183. if(DEFINED OPENCV_CACHE_CUDA_ACTIVE_CC AND OPENCV_CACHE_CUDA_ACTIVE_CC_check STREQUAL __cache_key_check)
  184. set(${output} "${OPENCV_CACHE_CUDA_ACTIVE_CC}")
  185. set(${status} 0)
  186. else()
  187. execute_process(
  188. COMMAND ${OPENCV_CUDA_DETECT_ARCHS_COMMAND}
  189. WORKING_DIRECTORY "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/"
  190. RESULT_VARIABLE ${status}
  191. OUTPUT_VARIABLE _nvcc_out
  192. ERROR_VARIABLE _nvcc_err
  193. ERROR_QUIET
  194. OUTPUT_STRIP_TRAILING_WHITESPACE
  195. )
  196. if(OPENCV_CMAKE_CUDA_DEBUG)
  197. message(WARNING "COMMAND: ${OPENCV_CUDA_DETECT_ARCHS_COMMAND}")
  198. message(STATUS "Result: ${${status}}")
  199. message(STATUS "Out: ${_nvcc_out}")
  200. message(STATUS "Err: ${_nvcc_err}")
  201. endif()
  202. string(REGEX REPLACE ".*\n" "" ${output} "${_nvcc_out}") #Strip leading warning messages, if any
  203. if(${status} EQUAL 0)
  204. # cache detected values
  205. set(OPENCV_CACHE_CUDA_ACTIVE_CC ${${output}} CACHE INTERNAL "")
  206. set(OPENCV_CACHE_CUDA_ACTIVE_CC_check "${__cache_key_check}" CACHE INTERNAL "")
  207. endif()
  208. endif()
  209. endmacro()
  210. set(__cuda_arch_ptx "")
  211. if(CUDA_GENERATION STREQUAL "Fermi")
  212. set(__cuda_arch_bin ${_arch_fermi})
  213. elseif(CUDA_GENERATION STREQUAL "Kepler")
  214. set(__cuda_arch_bin ${_arch_kepler})
  215. elseif(CUDA_GENERATION STREQUAL "Maxwell")
  216. set(__cuda_arch_bin ${_arch_maxwell})
  217. elseif(CUDA_GENERATION STREQUAL "Pascal")
  218. set(__cuda_arch_bin ${_arch_pascal})
  219. elseif(CUDA_GENERATION STREQUAL "Volta")
  220. set(__cuda_arch_bin ${_arch_volta})
  221. elseif(CUDA_GENERATION STREQUAL "Turing")
  222. set(__cuda_arch_bin ${_arch_turing})
  223. elseif(CUDA_GENERATION STREQUAL "Ampere")
  224. set(__cuda_arch_bin ${_arch_ampere})
  225. elseif(CUDA_GENERATION STREQUAL "Lovelace")
  226. set(__cuda_arch_bin ${_arch_lovelace})
  227. elseif(CUDA_GENERATION STREQUAL "Hopper")
  228. set(__cuda_arch_bin ${_arch_hopper})
  229. elseif(CUDA_GENERATION STREQUAL "Auto")
  230. ocv_detect_native_cuda_arch(_nvcc_res _nvcc_out)
  231. if(NOT _nvcc_res EQUAL 0)
  232. message(STATUS "Automatic detection of CUDA generation failed. Going to build for all known architectures.")
  233. else()
  234. string(REGEX MATCHALL "[0-9]+\\.[0-9]" __cuda_arch_bin "${_nvcc_out}")
  235. endif()
  236. elseif(CUDA_ARCH_BIN)
  237. message(STATUS "CUDA: Using CUDA_ARCH_BIN=${CUDA_ARCH_BIN}")
  238. set(__cuda_arch_bin ${CUDA_ARCH_BIN})
  239. endif()
  240. if(NOT DEFINED __cuda_arch_bin)
  241. if(ARM)
  242. set(__cuda_arch_bin "3.2")
  243. set(__cuda_arch_ptx "")
  244. elseif(AARCH64)
  245. if(NOT CMAKE_CROSSCOMPILING)
  246. ocv_detect_native_cuda_arch(_nvcc_res _nvcc_out)
  247. else()
  248. set(_nvcc_res -1) # emulate error, see below
  249. endif()
  250. if(NOT _nvcc_res EQUAL 0)
  251. message(STATUS "Automatic detection of CUDA generation failed. Going to build for all known architectures.")
  252. # TX1 (5.3) TX2 (6.2) Xavier (7.2) V100 (7.0) Orin (8.7)
  253. ocv_filter_available_architecture(__cuda_arch_bin
  254. 5.3
  255. 6.2
  256. 7.2
  257. 7.0
  258. 8.7
  259. )
  260. else()
  261. set(__cuda_arch_bin "${_nvcc_out}")
  262. endif()
  263. set(__cuda_arch_ptx "")
  264. else()
  265. ocv_filter_available_architecture(__cuda_arch_bin
  266. ${_arch_fermi}
  267. ${_arch_kepler}
  268. ${_arch_maxwell}
  269. ${_arch_pascal}
  270. ${_arch_volta}
  271. ${_arch_turing}
  272. ${_arch_ampere}
  273. ${_arch_lovelace}
  274. ${_arch_hopper}
  275. )
  276. endif()
  277. endif()
  278. set(CUDA_ARCH_BIN ${__cuda_arch_bin} CACHE STRING "Specify 'real' GPU architectures to build binaries for, BIN(PTX) format is supported")
  279. set(CUDA_ARCH_PTX ${__cuda_arch_ptx} CACHE STRING "Specify 'virtual' PTX architectures to build PTX intermediate code for")
  280. string(REGEX REPLACE "\\." "" ARCH_BIN_NO_POINTS "${CUDA_ARCH_BIN}")
  281. string(REGEX REPLACE "\\." "" ARCH_PTX_NO_POINTS "${CUDA_ARCH_PTX}")
  282. # Check if user specified 1.0/2.1 compute capability: we don't support it
  283. macro(ocv_wipeout_deprecated_cc target_cc)
  284. if(" ${CUDA_ARCH_BIN} ${CUDA_ARCH_PTX}" MATCHES " ${target_cc}")
  285. message(SEND_ERROR "CUDA: ${target_cc} compute capability is not supported - exclude it from ARCH/PTX list and re-run CMake")
  286. endif()
  287. endmacro()
  288. ocv_wipeout_deprecated_cc("1.0")
  289. ocv_wipeout_deprecated_cc("2.1")
  290. # NVCC flags to be set
  291. set(NVCC_FLAGS_EXTRA "")
  292. # These vars will be passed into the templates
  293. set(OPENCV_CUDA_ARCH_BIN "")
  294. set(OPENCV_CUDA_ARCH_PTX "")
  295. set(OPENCV_CUDA_ARCH_FEATURES "")
  296. # Tell NVCC to add binaries for the specified GPUs
  297. string(REGEX MATCHALL "[0-9()]+" ARCH_LIST "${ARCH_BIN_NO_POINTS}")
  298. foreach(ARCH IN LISTS ARCH_LIST)
  299. if(ARCH MATCHES "([0-9]+)\\(([0-9]+)\\)")
  300. # User explicitly specified PTX for the concrete BIN
  301. set(NVCC_FLAGS_EXTRA ${NVCC_FLAGS_EXTRA} -gencode arch=compute_${CMAKE_MATCH_2},code=sm_${CMAKE_MATCH_1})
  302. set(OPENCV_CUDA_ARCH_BIN "${OPENCV_CUDA_ARCH_BIN} ${CMAKE_MATCH_1}")
  303. set(OPENCV_CUDA_ARCH_FEATURES "${OPENCV_CUDA_ARCH_FEATURES} ${CMAKE_MATCH_2}")
  304. else()
  305. # User didn't explicitly specify PTX for the concrete BIN, we assume PTX=BIN
  306. set(NVCC_FLAGS_EXTRA ${NVCC_FLAGS_EXTRA} -gencode arch=compute_${ARCH},code=sm_${ARCH})
  307. set(OPENCV_CUDA_ARCH_BIN "${OPENCV_CUDA_ARCH_BIN} ${ARCH}")
  308. set(OPENCV_CUDA_ARCH_FEATURES "${OPENCV_CUDA_ARCH_FEATURES} ${ARCH}")
  309. endif()
  310. endforeach()
  311. set(NVCC_FLAGS_EXTRA ${NVCC_FLAGS_EXTRA} -D_FORCE_INLINES)
  312. # Tell NVCC to add PTX intermediate code for the specified architectures
  313. string(REGEX MATCHALL "[0-9]+" ARCH_LIST "${ARCH_PTX_NO_POINTS}")
  314. foreach(ARCH IN LISTS ARCH_LIST)
  315. set(NVCC_FLAGS_EXTRA ${NVCC_FLAGS_EXTRA} -gencode arch=compute_${ARCH},code=compute_${ARCH})
  316. set(OPENCV_CUDA_ARCH_PTX "${OPENCV_CUDA_ARCH_PTX} ${ARCH}")
  317. set(OPENCV_CUDA_ARCH_FEATURES "${OPENCV_CUDA_ARCH_FEATURES} ${ARCH}")
  318. endforeach()
  319. # These vars will be processed in other scripts
  320. set(CUDA_NVCC_FLAGS ${CUDA_NVCC_FLAGS} ${NVCC_FLAGS_EXTRA})
  321. set(OpenCV_CUDA_CC "${NVCC_FLAGS_EXTRA}")
  322. if(ANDROID)
  323. set(CUDA_NVCC_FLAGS ${CUDA_NVCC_FLAGS} "-Xptxas;-dlcm=ca")
  324. endif()
  325. message(STATUS "CUDA NVCC target flags: ${CUDA_NVCC_FLAGS}")
  326. OCV_OPTION(CUDA_FAST_MATH "Enable --use_fast_math for CUDA compiler " OFF)
  327. if(CUDA_FAST_MATH)
  328. set(CUDA_NVCC_FLAGS ${CUDA_NVCC_FLAGS} --use_fast_math)
  329. endif()
  330. OCV_OPTION(CUDA_ENABLE_DELAYLOAD "Enable delayed loading of CUDA DLLs" OFF VISIBLE_IF MSVC)
  331. mark_as_advanced(CUDA_BUILD_CUBIN CUDA_BUILD_EMULATION CUDA_VERBOSE_BUILD CUDA_SDK_ROOT_DIR)
  332. macro(ocv_cuda_filter_options)
  333. foreach(var CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_RELEASE CMAKE_CXX_FLAGS_DEBUG)
  334. set(${var}_backup_in_cuda_compile_ "${${var}}")
  335. if (CV_CLANG)
  336. # we remove -Winconsistent-missing-override and -Qunused-arguments
  337. # just in case we are compiling CUDA with gcc but OpenCV with clang
  338. string(REPLACE "-Winconsistent-missing-override" "" ${var} "${${var}}")
  339. string(REPLACE "-Qunused-arguments" "" ${var} "${${var}}")
  340. endif()
  341. # we remove /EHa as it generates warnings under windows
  342. string(REPLACE "/EHa" "" ${var} "${${var}}")
  343. # we remove -ggdb3 flag as it leads to preprocessor errors when compiling CUDA files (CUDA 4.1)
  344. string(REPLACE "-ggdb3" "" ${var} "${${var}}")
  345. # we remove -Wsign-promo as it generates warnings under linux
  346. string(REPLACE "-Wsign-promo" "" ${var} "${${var}}")
  347. # we remove -Wno-sign-promo as it generates warnings under linux
  348. string(REPLACE "-Wno-sign-promo" "" ${var} "${${var}}")
  349. # we remove -Wno-delete-non-virtual-dtor because it's used for C++ compiler
  350. # but NVCC uses C compiler by default
  351. string(REPLACE "-Wno-delete-non-virtual-dtor" "" ${var} "${${var}}")
  352. # we remove -frtti because it's used for C++ compiler
  353. # but NVCC uses C compiler by default
  354. string(REPLACE "-frtti" "" ${var} "${${var}}")
  355. string(REPLACE "-fvisibility-inlines-hidden" "" ${var} "${${var}}")
  356. # cc1: warning: command line option '-Wsuggest-override' is valid for C++/ObjC++ but not for C
  357. string(REPLACE "-Wsuggest-override" "" ${var} "${${var}}")
  358. # issue: #11552 (from OpenCVCompilerOptions.cmake)
  359. string(REGEX REPLACE "-Wimplicit-fallthrough(=[0-9]+)? " "" ${var} "${${var}}")
  360. # removal of custom specified options
  361. if(OPENCV_CUDA_NVCC_FILTEROUT_OPTIONS)
  362. foreach(__flag ${OPENCV_CUDA_NVCC_FILTEROUT_OPTIONS})
  363. string(REPLACE "${__flag}" "" ${var} "${${var}}")
  364. endforeach()
  365. endif()
  366. endforeach()
  367. endmacro()
  368. macro(ocv_cuda_compile VAR)
  369. ocv_cuda_filter_options()
  370. if(BUILD_SHARED_LIBS)
  371. set(CUDA_NVCC_FLAGS ${CUDA_NVCC_FLAGS} -Xcompiler -DCVAPI_EXPORTS)
  372. endif()
  373. if(UNIX OR APPLE)
  374. set(CUDA_NVCC_FLAGS ${CUDA_NVCC_FLAGS} -Xcompiler -fPIC)
  375. if(NOT " ${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_RELEASE} ${CMAKE_CXX_FLAGS_DEBUG} ${CUDA_NVCC_FLAGS}" MATCHES "-std=")
  376. if(CUDA_VERSION VERSION_LESS "11.0")
  377. list(APPEND CUDA_NVCC_FLAGS "--std=c++11")
  378. else()
  379. list(APPEND CUDA_NVCC_FLAGS "--std=c++14")
  380. endif()
  381. endif()
  382. endif()
  383. if(APPLE)
  384. set(CUDA_NVCC_FLAGS ${CUDA_NVCC_FLAGS} -Xcompiler -fno-finite-math-only)
  385. endif()
  386. if(WIN32 AND NOT (CUDA_VERSION VERSION_LESS "11.2"))
  387. set(CUDA_NVCC_FLAGS ${CUDA_NVCC_FLAGS} -Xcudafe --display_error_number --diag-suppress 1394,1388)
  388. endif()
  389. if(CMAKE_CROSSCOMPILING AND (ARM OR AARCH64))
  390. set(CUDA_NVCC_FLAGS ${CUDA_NVCC_FLAGS} -Xlinker --unresolved-symbols=ignore-in-shared-libs)
  391. endif()
  392. # disabled because of multiple warnings during building nvcc auto generated files
  393. if(CV_GCC AND CMAKE_CXX_COMPILER_VERSION VERSION_GREATER "4.6.0")
  394. ocv_warnings_disable(CMAKE_CXX_FLAGS -Wunused-but-set-variable)
  395. endif()
  396. CUDA_COMPILE(${VAR} ${ARGN})
  397. foreach(var CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_RELEASE CMAKE_CXX_FLAGS_DEBUG)
  398. set(${var} "${${var}_backup_in_cuda_compile_}")
  399. unset(${var}_backup_in_cuda_compile_)
  400. endforeach()
  401. endmacro()
  402. else()
  403. unset(CUDA_ARCH_BIN CACHE)
  404. unset(CUDA_ARCH_PTX CACHE)
  405. endif()
  406. if(HAVE_CUDA)
  407. set(CUDA_LIBS_PATH "")
  408. foreach(p ${CUDA_LIBRARIES} ${CUDA_npp_LIBRARY})
  409. get_filename_component(_tmp ${p} PATH)
  410. list(APPEND CUDA_LIBS_PATH ${_tmp})
  411. endforeach()
  412. if(HAVE_CUBLAS)
  413. foreach(p ${CUDA_cublas_LIBRARY})
  414. get_filename_component(_tmp ${p} PATH)
  415. list(APPEND CUDA_LIBS_PATH ${_tmp})
  416. endforeach()
  417. endif()
  418. if(HAVE_CUDNN)
  419. foreach(p ${CUDNN_LIBRARIES})
  420. get_filename_component(_tmp ${p} PATH)
  421. list(APPEND CUDA_LIBS_PATH ${_tmp})
  422. endforeach()
  423. endif()
  424. if(HAVE_CUFFT)
  425. foreach(p ${CUDA_cufft_LIBRARY})
  426. get_filename_component(_tmp ${p} PATH)
  427. list(APPEND CUDA_LIBS_PATH ${_tmp})
  428. endforeach()
  429. endif()
  430. list(REMOVE_DUPLICATES CUDA_LIBS_PATH)
  431. link_directories(${CUDA_LIBS_PATH})
  432. set(CUDA_LIBRARIES_ABS ${CUDA_LIBRARIES})
  433. ocv_convert_to_lib_name(CUDA_LIBRARIES ${CUDA_LIBRARIES})
  434. set(CUDA_npp_LIBRARY_ABS ${CUDA_npp_LIBRARY})
  435. ocv_convert_to_lib_name(CUDA_npp_LIBRARY ${CUDA_npp_LIBRARY})
  436. if(HAVE_CUBLAS)
  437. set(CUDA_cublas_LIBRARY_ABS ${CUDA_cublas_LIBRARY})
  438. ocv_convert_to_lib_name(CUDA_cublas_LIBRARY ${CUDA_cublas_LIBRARY})
  439. endif()
  440. if(HAVE_CUDNN)
  441. set(CUDNN_LIBRARIES_ABS ${CUDNN_LIBRARIES})
  442. ocv_convert_to_lib_name(CUDNN_LIBRARIES ${CUDNN_LIBRARIES})
  443. endif()
  444. if(HAVE_CUFFT)
  445. set(CUDA_cufft_LIBRARY_ABS ${CUDA_cufft_LIBRARY})
  446. ocv_convert_to_lib_name(CUDA_cufft_LIBRARY ${CUDA_cufft_LIBRARY})
  447. endif()
  448. if(CMAKE_GENERATOR MATCHES "Visual Studio"
  449. AND NOT OPENCV_SKIP_CUDA_CMAKE_SUPPRESS_REGENERATION
  450. )
  451. 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.")
  452. set(CMAKE_SUPPRESS_REGENERATION ON)
  453. endif()
  454. endif()
  455. # ----------------------------------------------------------------------------
  456. # Add CUDA libraries (needed for apps/tools, samples)
  457. # ----------------------------------------------------------------------------
  458. if(HAVE_CUDA)
  459. # details: https://github.com/NVIDIA/nvidia-docker/issues/775
  460. if(" ${CUDA_CUDA_LIBRARY}" MATCHES "/stubs/libcuda.so" AND NOT OPENCV_SKIP_CUDA_STUB_WORKAROUND)
  461. set(CUDA_STUB_ENABLED_LINK_WORKAROUND 1)
  462. if(EXISTS "${CUDA_CUDA_LIBRARY}" AND NOT OPENCV_SKIP_CUDA_STUB_WORKAROUND_RPATH_LINK)
  463. set(CUDA_STUB_TARGET_PATH "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/")
  464. execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink "${CUDA_CUDA_LIBRARY}" "${CUDA_STUB_TARGET_PATH}/libcuda.so.1"
  465. RESULT_VARIABLE CUDA_STUB_SYMLINK_RESULT)
  466. if(NOT CUDA_STUB_SYMLINK_RESULT EQUAL 0)
  467. execute_process(COMMAND ${CMAKE_COMMAND} -E copy_if_different "${CUDA_CUDA_LIBRARY}" "${CUDA_STUB_TARGET_PATH}/libcuda.so.1"
  468. RESULT_VARIABLE CUDA_STUB_COPY_RESULT)
  469. if(NOT CUDA_STUB_COPY_RESULT EQUAL 0)
  470. set(CUDA_STUB_ENABLED_LINK_WORKAROUND 0)
  471. endif()
  472. endif()
  473. if(CUDA_STUB_ENABLED_LINK_WORKAROUND)
  474. set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-rpath-link,\"${CUDA_STUB_TARGET_PATH}\"")
  475. endif()
  476. else()
  477. set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--allow-shlib-undefined")
  478. endif()
  479. if(NOT CUDA_STUB_ENABLED_LINK_WORKAROUND)
  480. message(WARNING "CUDA: workaround for stubs/libcuda.so.1 is not applied")
  481. endif()
  482. endif()
  483. set(OPENCV_LINKER_LIBS ${OPENCV_LINKER_LIBS} ${CUDA_LIBRARIES} ${CUDA_npp_LIBRARY})
  484. if(HAVE_CUBLAS)
  485. set(OPENCV_LINKER_LIBS ${OPENCV_LINKER_LIBS} ${CUDA_cublas_LIBRARY})
  486. endif()
  487. if(HAVE_CUDNN)
  488. set(OPENCV_LINKER_LIBS ${OPENCV_LINKER_LIBS} ${CUDNN_LIBRARIES})
  489. endif()
  490. if(HAVE_CUFFT)
  491. set(OPENCV_LINKER_LIBS ${OPENCV_LINKER_LIBS} ${CUDA_cufft_LIBRARY})
  492. endif()
  493. foreach(p ${CUDA_LIBS_PATH})
  494. if(MSVC AND CMAKE_GENERATOR MATCHES "Ninja|JOM")
  495. set(OPENCV_LINKER_LIBS ${OPENCV_LINKER_LIBS} ${CMAKE_LIBRARY_PATH_FLAG}"${p}")
  496. else()
  497. set(OPENCV_LINKER_LIBS ${OPENCV_LINKER_LIBS} ${CMAKE_LIBRARY_PATH_FLAG}${p})
  498. endif()
  499. endforeach()
  500. if(MSVC AND CUDA_ENABLE_DELAYLOAD)
  501. set(DELAYFLAGS "delayimp.lib")
  502. file(GLOB CUDA_DLLS "${CUDA_TOOLKIT_ROOT_DIR}/bin/*.dll")
  503. foreach(d ${CUDA_DLLS})
  504. cmake_path(GET "d" FILENAME DLL_NAME)
  505. if(NOT ${DLL_NAME} MATCHES "cudart")
  506. set(DELAYFLAGS "${DELAYFLAGS} /DELAYLOAD:${DLL_NAME}")
  507. endif()
  508. endforeach()
  509. set(DELAYFLAGS "${DELAYFLAGS} /DELAYLOAD:nvcuda.dll /DELAYLOAD:nvml.dll /IGNORE:4199")
  510. set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${DELAYFLAGS}")
  511. set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} ${DELAYFLAGS}")
  512. set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${DELAYFLAGS}")
  513. endif()
  514. endif()