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