Merge pull request #15743 from collinbrake:feature_grammar_fixes_2
[platform/upstream/opencv.git] / cmake / OpenCVDetectCUDA.cmake
1 if(WIN32 AND NOT MSVC)
2   message(STATUS "CUDA compilation is disabled (due to only Visual Studio compiler supported on your platform).")
3   return()
4 endif()
5
6 if(NOT UNIX AND CV_CLANG)
7   message(STATUS "CUDA compilation is disabled (due to Clang unsupported on your platform).")
8   return()
9 endif()
10
11
12 if(((NOT CMAKE_VERSION VERSION_LESS "3.9.0")  # requires https://gitlab.kitware.com/cmake/cmake/merge_requests/663
13       OR OPENCV_CUDA_FORCE_EXTERNAL_CMAKE_MODULE)
14     AND NOT OPENCV_CUDA_FORCE_BUILTIN_CMAKE_MODULE)
15   ocv_update(CUDA_LINK_LIBRARIES_KEYWORD "LINK_PRIVATE")
16   find_host_package(CUDA "${MIN_VER_CUDA}" QUIET)
17 else()
18   # Use OpenCV's patched "FindCUDA" module
19   set(CMAKE_MODULE_PATH "${OpenCV_SOURCE_DIR}/cmake" ${CMAKE_MODULE_PATH})
20
21   if(ANDROID)
22     set(CUDA_TARGET_OS_VARIANT "Android")
23   endif()
24   find_host_package(CUDA "${MIN_VER_CUDA}" QUIET)
25
26   list(REMOVE_AT CMAKE_MODULE_PATH 0)
27 endif()
28
29 if(CUDA_FOUND)
30   set(HAVE_CUDA 1)
31
32   if(WITH_CUFFT)
33     set(HAVE_CUFFT 1)
34   endif()
35
36   if(WITH_CUBLAS)
37     set(HAVE_CUBLAS 1)
38   endif()
39
40   if(WITH_NVCUVID)
41     find_cuda_helper_libs(nvcuvid)
42     if(WIN32)
43       find_cuda_helper_libs(nvcuvenc)
44     endif()
45     if(CUDA_nvcuvid_LIBRARY)
46       set(HAVE_NVCUVID 1)
47     endif()
48     if(CUDA_nvcuvenc_LIBRARY)
49       set(HAVE_NVCUVENC 1)
50     endif()
51   endif()
52
53   message(STATUS "CUDA detected: " ${CUDA_VERSION})
54
55   set(_generations "Fermi" "Kepler" "Maxwell" "Pascal" "Volta" "Turing")
56   if(NOT CMAKE_CROSSCOMPILING)
57     list(APPEND _generations "Auto")
58   endif()
59   set(CUDA_GENERATION "" CACHE STRING "Build CUDA device code only for specific GPU architecture. Leave empty to build for all architectures.")
60   if( CMAKE_VERSION VERSION_GREATER "2.8" )
61     set_property( CACHE CUDA_GENERATION PROPERTY STRINGS "" ${_generations} )
62   endif()
63
64   if(CUDA_GENERATION)
65     if(NOT ";${_generations};" MATCHES ";${CUDA_GENERATION};")
66       string(REPLACE ";" ", " _generations "${_generations}")
67       message(FATAL_ERROR "ERROR: ${_generations} Generations are suppered.")
68     endif()
69     unset(CUDA_ARCH_BIN CACHE)
70     unset(CUDA_ARCH_PTX CACHE)
71   endif()
72
73   set(__cuda_arch_ptx "")
74   if(CUDA_GENERATION STREQUAL "Fermi")
75     set(__cuda_arch_bin "2.0")
76   elseif(CUDA_GENERATION STREQUAL "Kepler")
77     set(__cuda_arch_bin "3.0 3.5 3.7")
78   elseif(CUDA_GENERATION STREQUAL "Maxwell")
79     set(__cuda_arch_bin "5.0 5.2")
80   elseif(CUDA_GENERATION STREQUAL "Pascal")
81     set(__cuda_arch_bin "6.0 6.1")
82   elseif(CUDA_GENERATION STREQUAL "Volta")
83     set(__cuda_arch_bin "7.0")
84   elseif(CUDA_GENERATION STREQUAL "Turing")
85     set(__cuda_arch_bin "7.5")
86   elseif(CUDA_GENERATION STREQUAL "Auto")
87     execute_process( COMMAND "${CUDA_NVCC_EXECUTABLE}" ${CUDA_NVCC_FLAGS} "${OpenCV_SOURCE_DIR}/cmake/checks/OpenCVDetectCudaArch.cu" "--run"
88                      WORKING_DIRECTORY "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/"
89                      RESULT_VARIABLE _nvcc_res OUTPUT_VARIABLE _nvcc_out
90                      ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE)
91     if(NOT _nvcc_res EQUAL 0)
92       message(STATUS "Automatic detection of CUDA generation failed. Going to build for all known architectures.")
93     else()
94       set(__cuda_arch_bin "${_nvcc_out}")
95       string(REPLACE "2.1" "2.1(2.0)" __cuda_arch_bin "${__cuda_arch_bin}")
96     endif()
97   endif()
98
99   if(NOT DEFINED __cuda_arch_bin)
100     if(ARM)
101       set(__cuda_arch_bin "3.2")
102       set(__cuda_arch_ptx "")
103     elseif(AARCH64)
104       execute_process( COMMAND "${CUDA_NVCC_EXECUTABLE}" ${CUDA_NVCC_FLAGS} "${OpenCV_SOURCE_DIR}/cmake/checks/OpenCVDetectCudaArch.cu" "--run"
105                        WORKING_DIRECTORY "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/"
106                        RESULT_VARIABLE _nvcc_res OUTPUT_VARIABLE _nvcc_out
107                        ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE)
108       if(NOT _nvcc_res EQUAL 0)
109         message(STATUS "Automatic detection of CUDA generation failed. Going to build for all known architectures.")
110         set(__cuda_arch_bin "5.3 6.2 7.2")
111       else()
112         set(__cuda_arch_bin "${_nvcc_out}")
113         string(REPLACE "2.1" "2.1(2.0)" __cuda_arch_bin "${__cuda_arch_bin}")
114       endif()
115       set(__cuda_arch_ptx "")
116     else()
117       if(CUDA_VERSION VERSION_LESS "9.0")
118         set(__cuda_arch_bin "2.0 3.0 3.5 3.7 5.0 5.2 6.0 6.1")
119       elseif(CUDA_VERSION VERSION_LESS "10.0")
120         set(__cuda_arch_bin "3.0 3.5 3.7 5.0 5.2 6.0 6.1 7.0")
121       else()
122         set(__cuda_arch_bin "3.0 3.5 3.7 5.0 5.2 6.0 6.1 7.0 7.5")
123       endif()
124     endif()
125   endif()
126
127   set(CUDA_ARCH_BIN ${__cuda_arch_bin} CACHE STRING "Specify 'real' GPU architectures to build binaries for, BIN(PTX) format is supported")
128   set(CUDA_ARCH_PTX ${__cuda_arch_ptx} CACHE STRING "Specify 'virtual' PTX architectures to build PTX intermediate code for")
129
130   string(REGEX REPLACE "\\." "" ARCH_BIN_NO_POINTS "${CUDA_ARCH_BIN}")
131   string(REGEX REPLACE "\\." "" ARCH_PTX_NO_POINTS "${CUDA_ARCH_PTX}")
132
133   # Ckeck if user specified 1.0 compute capability: we don't support it
134   string(REGEX MATCH "1.0" HAS_ARCH_10 "${CUDA_ARCH_BIN} ${CUDA_ARCH_PTX}")
135   set(CUDA_ARCH_BIN_OR_PTX_10 0)
136   if(NOT ${HAS_ARCH_10} STREQUAL "")
137     set(CUDA_ARCH_BIN_OR_PTX_10 1)
138   endif()
139
140   # NVCC flags to be set
141   set(NVCC_FLAGS_EXTRA "")
142
143   # These vars will be passed into the templates
144   set(OPENCV_CUDA_ARCH_BIN "")
145   set(OPENCV_CUDA_ARCH_PTX "")
146   set(OPENCV_CUDA_ARCH_FEATURES "")
147
148   # Tell NVCC to add binaries for the specified GPUs
149   string(REGEX MATCHALL "[0-9()]+" ARCH_LIST "${ARCH_BIN_NO_POINTS}")
150   foreach(ARCH IN LISTS ARCH_LIST)
151     if(ARCH MATCHES "([0-9]+)\\(([0-9]+)\\)")
152       # User explicitly specified PTX for the concrete BIN
153       set(NVCC_FLAGS_EXTRA ${NVCC_FLAGS_EXTRA} -gencode arch=compute_${CMAKE_MATCH_2},code=sm_${CMAKE_MATCH_1})
154       set(OPENCV_CUDA_ARCH_BIN "${OPENCV_CUDA_ARCH_BIN} ${CMAKE_MATCH_1}")
155       set(OPENCV_CUDA_ARCH_FEATURES "${OPENCV_CUDA_ARCH_FEATURES} ${CMAKE_MATCH_2}")
156     else()
157       # User didn't explicitly specify PTX for the concrete BIN, we assume PTX=BIN
158       set(NVCC_FLAGS_EXTRA ${NVCC_FLAGS_EXTRA} -gencode arch=compute_${ARCH},code=sm_${ARCH})
159       set(OPENCV_CUDA_ARCH_BIN "${OPENCV_CUDA_ARCH_BIN} ${ARCH}")
160       set(OPENCV_CUDA_ARCH_FEATURES "${OPENCV_CUDA_ARCH_FEATURES} ${ARCH}")
161     endif()
162   endforeach()
163   set(NVCC_FLAGS_EXTRA ${NVCC_FLAGS_EXTRA} -D_FORCE_INLINES)
164
165   # Tell NVCC to add PTX intermediate code for the specified architectures
166   string(REGEX MATCHALL "[0-9]+" ARCH_LIST "${ARCH_PTX_NO_POINTS}")
167   foreach(ARCH IN LISTS ARCH_LIST)
168     set(NVCC_FLAGS_EXTRA ${NVCC_FLAGS_EXTRA} -gencode arch=compute_${ARCH},code=compute_${ARCH})
169     set(OPENCV_CUDA_ARCH_PTX "${OPENCV_CUDA_ARCH_PTX} ${ARCH}")
170     set(OPENCV_CUDA_ARCH_FEATURES "${OPENCV_CUDA_ARCH_FEATURES} ${ARCH}")
171   endforeach()
172
173   # These vars will be processed in other scripts
174   set(CUDA_NVCC_FLAGS ${CUDA_NVCC_FLAGS} ${NVCC_FLAGS_EXTRA})
175   set(OpenCV_CUDA_CC "${NVCC_FLAGS_EXTRA}")
176
177   if(ANDROID)
178     set(CUDA_NVCC_FLAGS ${CUDA_NVCC_FLAGS} "-Xptxas;-dlcm=ca")
179   endif()
180
181   message(STATUS "CUDA NVCC target flags: ${CUDA_NVCC_FLAGS}")
182
183   OCV_OPTION(CUDA_FAST_MATH "Enable --use_fast_math for CUDA compiler " OFF)
184
185   if(CUDA_FAST_MATH)
186     set(CUDA_NVCC_FLAGS ${CUDA_NVCC_FLAGS} --use_fast_math)
187   endif()
188
189   mark_as_advanced(CUDA_BUILD_CUBIN CUDA_BUILD_EMULATION CUDA_VERBOSE_BUILD CUDA_SDK_ROOT_DIR)
190
191   macro(ocv_cuda_filter_options)
192     foreach(var CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_RELEASE CMAKE_CXX_FLAGS_DEBUG)
193       set(${var}_backup_in_cuda_compile_ "${${var}}")
194
195       if (CV_CLANG)
196         # we remove -Winconsistent-missing-override and -Qunused-arguments
197         # just in case we are compiling CUDA with gcc but OpenCV with clang
198         string(REPLACE "-Winconsistent-missing-override" "" ${var} "${${var}}")
199         string(REPLACE "-Qunused-arguments" "" ${var} "${${var}}")
200       endif()
201
202       # we remove /EHa as it generates warnings under windows
203       string(REPLACE "/EHa" "" ${var} "${${var}}")
204
205       # we remove -ggdb3 flag as it leads to preprocessor errors when compiling CUDA files (CUDA 4.1)
206       string(REPLACE "-ggdb3" "" ${var} "${${var}}")
207
208       # we remove -Wsign-promo as it generates warnings under linux
209       string(REPLACE "-Wsign-promo" "" ${var} "${${var}}")
210
211       # we remove -Wno-sign-promo as it generates warnings under linux
212       string(REPLACE "-Wno-sign-promo" "" ${var} "${${var}}")
213
214       # we remove -Wno-delete-non-virtual-dtor because it's used for C++ compiler
215       # but NVCC uses C compiler by default
216       string(REPLACE "-Wno-delete-non-virtual-dtor" "" ${var} "${${var}}")
217
218       # we remove -frtti because it's used for C++ compiler
219       # but NVCC uses C compiler by default
220       string(REPLACE "-frtti" "" ${var} "${${var}}")
221
222       string(REPLACE "-fvisibility-inlines-hidden" "" ${var} "${${var}}")
223
224       # cc1: warning: command line option '-Wsuggest-override' is valid for C++/ObjC++ but not for C
225       string(REPLACE "-Wsuggest-override" "" ${var} "${${var}}")
226
227       # issue: #11552 (from OpenCVCompilerOptions.cmake)
228       string(REGEX REPLACE "-Wimplicit-fallthrough(=[0-9]+)? " "" ${var} "${${var}}")
229
230       # removal of custom specified options
231       if(OPENCV_CUDA_NVCC_FILTEROUT_OPTIONS)
232         foreach(__flag ${OPENCV_CUDA_NVCC_FILTEROUT_OPTIONS})
233           string(REPLACE "${__flag}" "" ${var} "${${var}}")
234         endforeach()
235       endif()
236     endforeach()
237   endmacro()
238
239   macro(ocv_cuda_compile VAR)
240     ocv_cuda_filter_options()
241
242     if(BUILD_SHARED_LIBS)
243       set(CUDA_NVCC_FLAGS ${CUDA_NVCC_FLAGS} -Xcompiler -DCVAPI_EXPORTS)
244     endif()
245
246     if(UNIX OR APPLE)
247       set(CUDA_NVCC_FLAGS ${CUDA_NVCC_FLAGS} -Xcompiler -fPIC)
248     endif()
249     if(APPLE)
250       set(CUDA_NVCC_FLAGS ${CUDA_NVCC_FLAGS} -Xcompiler -fno-finite-math-only)
251     endif()
252
253     if(CMAKE_CROSSCOMPILING AND (ARM OR AARCH64))
254       set(CUDA_NVCC_FLAGS ${CUDA_NVCC_FLAGS} -Xlinker --unresolved-symbols=ignore-in-shared-libs)
255     endif()
256
257     # disabled because of multiple warnings during building nvcc auto generated files
258     if(CV_GCC AND CMAKE_CXX_COMPILER_VERSION VERSION_GREATER "4.6.0")
259       ocv_warnings_disable(CMAKE_CXX_FLAGS -Wunused-but-set-variable)
260     endif()
261
262     CUDA_COMPILE(${VAR} ${ARGN})
263
264     foreach(var CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_RELEASE CMAKE_CXX_FLAGS_DEBUG)
265       set(${var} "${${var}_backup_in_cuda_compile_}")
266       unset(${var}_backup_in_cuda_compile_)
267     endforeach()
268   endmacro()
269 else()
270   unset(CUDA_ARCH_BIN CACHE)
271   unset(CUDA_ARCH_PTX CACHE)
272 endif()
273
274 if(HAVE_CUDA)
275   set(CUDA_LIBS_PATH "")
276   foreach(p ${CUDA_LIBRARIES} ${CUDA_npp_LIBRARY})
277     get_filename_component(_tmp ${p} PATH)
278     list(APPEND CUDA_LIBS_PATH ${_tmp})
279   endforeach()
280
281   if(HAVE_CUBLAS)
282     foreach(p ${CUDA_cublas_LIBRARY})
283       get_filename_component(_tmp ${p} PATH)
284       list(APPEND CUDA_LIBS_PATH ${_tmp})
285     endforeach()
286   endif()
287
288   if(HAVE_CUFFT)
289     foreach(p ${CUDA_cufft_LIBRARY})
290       get_filename_component(_tmp ${p} PATH)
291       list(APPEND CUDA_LIBS_PATH ${_tmp})
292     endforeach()
293   endif()
294
295   list(REMOVE_DUPLICATES CUDA_LIBS_PATH)
296   link_directories(${CUDA_LIBS_PATH})
297
298   set(CUDA_LIBRARIES_ABS ${CUDA_LIBRARIES})
299   ocv_convert_to_lib_name(CUDA_LIBRARIES ${CUDA_LIBRARIES})
300   set(CUDA_npp_LIBRARY_ABS ${CUDA_npp_LIBRARY})
301   ocv_convert_to_lib_name(CUDA_npp_LIBRARY ${CUDA_npp_LIBRARY})
302   if(HAVE_CUBLAS)
303     set(CUDA_cublas_LIBRARY_ABS ${CUDA_cublas_LIBRARY})
304     ocv_convert_to_lib_name(CUDA_cublas_LIBRARY ${CUDA_cublas_LIBRARY})
305   endif()
306
307   if(HAVE_CUFFT)
308     set(CUDA_cufft_LIBRARY_ABS ${CUDA_cufft_LIBRARY})
309     ocv_convert_to_lib_name(CUDA_cufft_LIBRARY ${CUDA_cufft_LIBRARY})
310   endif()
311 endif()