Skip to content

Commit fd99641

Browse files
committed
cuda_add_library
1 parent 5f94ad5 commit fd99641

File tree

4 files changed

+153
-90
lines changed

4 files changed

+153
-90
lines changed

dlib/CMakeLists.txt

Lines changed: 147 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -649,13 +649,144 @@ if (NOT TARGET dlib)
649649

650650

651651
if (DLIB_USE_CUDA)
652-
find_package(CUDAToolkit 9.1)
653-
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake_utils)
654-
find_package(CUDNN)
655-
find_package(OpenMP)
656-
set(openmp_libraries ${OpenMP_CXX_FLAGS})
652+
find_package(CUDAToolkit QUIET)
657653

658-
if (CUDAToolkit_FOUND AND CUDNN_FOUND AND OPENMP_FOUND)
654+
if (CUDA_VERSION VERSION_GREATER 9.1 AND CMAKE_VERSION VERSION_LESS 3.12.2)
655+
# This bit of weirdness is to work around a bug in cmake
656+
list(REMOVE_ITEM CUDA_CUBLAS_LIBRARIES "CUDA_cublas_device_LIBRARY-NOTFOUND")
657+
endif()
658+
659+
660+
if (CUDAToolkit_FOUND AND MSVC AND NOT TARGET CUDA::cublas AND "${CMAKE_SIZEOF_VOID_P}" EQUAL "4")
661+
message(WARNING "You have CUDA installed, but we can't use it unless you put visual studio in 64bit mode.")
662+
set(CUDA_FOUND 0)
663+
endif()
664+
665+
if (CUDAToolkit_FOUND)
666+
667+
# There is some bug in cmake that causes it to mess up the
668+
# -std=c++11 option if you let it propagate it to nvcc in some
669+
# cases. So instead we disable this and manually include
670+
# things from CMAKE_CXX_FLAGS in the CUDA_NVCC_FLAGS list below.
671+
if (APPLE)
672+
set(CUDA_PROPAGATE_HOST_FLAGS OFF)
673+
# Grab all the -D flags from CMAKE_CXX_FLAGS so we can pass them
674+
# to nvcc.
675+
string(REGEX MATCHALL "-D[^ ]*" FLAGS_FOR_NVCC "${CMAKE_CXX_FLAGS}")
676+
677+
# Check if we are being built as part of a pybind11 module.
678+
if (COMMAND pybind11_add_module)
679+
# Don't export unnecessary symbols.
680+
list(APPEND FLAGS_FOR_NVCC "-Xcompiler=-fvisibility=hidden")
681+
endif()
682+
endif()
683+
684+
set(CUDA_HOST_COMPILATION_CPP ON)
685+
string(REPLACE "," ";" DLIB_CUDA_COMPUTE_CAPABILITIES ${DLIB_USE_CUDA_COMPUTE_CAPABILITIES})
686+
foreach(CAP ${DLIB_CUDA_COMPUTE_CAPABILITIES})
687+
list(APPEND CUDA_NVCC_FLAGS "-gencode arch=compute_${CAP},code=[sm_${CAP},compute_${CAP}]")
688+
endforeach()
689+
# Note that we add __STRICT_ANSI__ to avoid freaking out nvcc with gcc specific
690+
# magic in the standard C++ header files (since nvcc uses gcc headers on linux).
691+
list(APPEND CUDA_NVCC_FLAGS "-D__STRICT_ANSI__;-D_MWAITXINTRIN_H_INCLUDED;-D_FORCE_INLINES;${FLAGS_FOR_NVCC}")
692+
list(APPEND CUDA_NVCC_FLAGS ${active_preprocessor_switches})
693+
if (NOT DLIB_IN_PROJECT_BUILD)
694+
LIST(APPEND CUDA_NVCC_FLAGS -DDLIB__CMAKE_GENERATED_A_CONFIG_H_FILE)
695+
endif()
696+
if (NOT MSVC)
697+
list(APPEND CUDA_NVCC_FLAGS "-std=c++14")
698+
endif()
699+
if (CMAKE_POSITION_INDEPENDENT_CODE)
700+
# sometimes this setting isn't propagated to NVCC, which then causes the
701+
# compile to fail. So make sure it's propagated.
702+
if (NOT MSVC) # Visual studio doesn't have -fPIC so don't do it in that case.
703+
list(APPEND CUDA_NVCC_FLAGS "-Xcompiler -fPIC")
704+
endif()
705+
endif()
706+
707+
include(cmake_utils/test_for_cudnn/find_cudnn.txt)
708+
709+
include(CheckLanguage)
710+
check_language(CUDA)
711+
set(cuda_compiler_found OFF)
712+
if (CMAKE_CUDA_COMPILER)
713+
set(cuda_compiler_found ON)
714+
else()
715+
message(STATUS " *** Cannot find CUDA compiler. If you are on windows using Visual Studio, make sure to install 'Visual Studio Integration' in the cuda installer.")
716+
endif()
717+
718+
if (cudnn AND cudnn_include AND cuda_compiler_found AND NOT DEFINED cuda_test_compile_worked AND NOT DEFINED cudnn_test_compile_worked)
719+
# make sure cuda is really working by doing a test compile
720+
enable_language(CUDA)
721+
message(STATUS "Building a CUDA test project to see if your compiler is compatible with CUDA...")
722+
723+
set(CUDA_TEST_CMAKE_FLAGS
724+
"-DCMAKE_PREFIX_PATH=${CMAKE_PREFIX_PATH}"
725+
"-DCMAKE_INCLUDE_PATH=${CMAKE_INCLUDE_PATH}"
726+
"-DCMAKE_LIBRARY_PATH=${CMAKE_LIBRARY_PATH}")
727+
728+
if (NOT MSVC) # see https://github.com/davisking/dlib/issues/363
729+
list(APPEND CUDA_TEST_CMAKE_FLAGS "-DCUDA_HOST_COMPILER=${CUDA_HOST_COMPILER}")
730+
endif()
731+
732+
try_compile(cuda_test_compile_worked
733+
${PROJECT_BINARY_DIR}/cuda_test_build
734+
${PROJECT_SOURCE_DIR}/cmake_utils/test_for_cuda cuda_test
735+
CMAKE_FLAGS ${CUDA_TEST_CMAKE_FLAGS}
736+
OUTPUT_VARIABLE try_compile_output_message
737+
)
738+
if (NOT cuda_test_compile_worked)
739+
string(REPLACE "\n" "\n *** " try_compile_output_message "${try_compile_output_message}")
740+
message(STATUS "*****************************************************************************************************************")
741+
message(STATUS "*** CUDA was found but your compiler failed to compile a simple CUDA program so dlib isn't going to use CUDA. ")
742+
message(STATUS "*** The output of the failed CUDA test compile is shown below: ")
743+
message(STATUS "*** ")
744+
message(STATUS "*** ${try_compile_output_message}")
745+
message(STATUS "*****************************************************************************************************************")
746+
else()
747+
message(STATUS "Building a cuDNN test project to check if you have the right version of cuDNN installed...")
748+
try_compile(cudnn_test_compile_worked
749+
${PROJECT_BINARY_DIR}/cudnn_test_build
750+
${PROJECT_SOURCE_DIR}/cmake_utils/test_for_cudnn cudnn_test
751+
CMAKE_FLAGS ${CUDA_TEST_CMAKE_FLAGS}
752+
OUTPUT_VARIABLE try_compile_output_message
753+
)
754+
if (NOT cudnn_test_compile_worked)
755+
string(REPLACE "\n" "\n *** " try_compile_output_message "${try_compile_output_message}")
756+
message(STATUS "*****************************************************************************************************")
757+
message(STATUS "*** Found cuDNN, but we failed to compile the dlib/cmake_utils/test_for_cudnn project. ")
758+
message(STATUS "*** You either have an unsupported version of cuDNN or something is wrong with your cudDNN install.")
759+
message(STATUS "*** Since a functional cuDNN is not found DLIB WILL NOT USE CUDA. ")
760+
message(STATUS "*** The output of the failed test_for_cudnn build is: ")
761+
message(STATUS "*** ")
762+
message(STATUS "*** ${try_compile_output_message}")
763+
message(STATUS "*****************************************************************************************************")
764+
endif()
765+
endif()
766+
endif()
767+
# Also find OpenMP since cuSOLVER needs it. Importantly, we only
768+
# look for one to link to if our use of BLAS, specifically the
769+
# Intel MKL, hasn't already decided what to use. This is because
770+
# it makes the MKL bug out if you link to another openmp lib other
771+
# than Intel's when you use the MKL. I'm also not really sure when
772+
# explicit linking to openmp became unnecessary, but for
773+
# sufficiently older versions of cuda it was needed. Then in
774+
# versions of cmake newer than 3.11 linking to openmp started to
775+
# mess up the switches passed to nvcc, so you can't just leave
776+
# these "try to link to openmp" statements here going forward. Fun
777+
# times.
778+
if (CUDA_VERSION VERSION_LESS "9.1" AND NOT openmp_libraries AND NOT MSVC AND NOT XCODE AND NOT APPLE)
779+
find_package(OpenMP)
780+
if (OPENMP_FOUND)
781+
set(openmp_libraries ${OpenMP_CXX_FLAGS})
782+
else()
783+
message(STATUS "*** Didn't find OpenMP, which is required to use CUDA. ***")
784+
set(CUDA_FOUND 0)
785+
endif()
786+
endif()
787+
endif()
788+
789+
if (CUDAToolkit_FOUND AND cudnn AND cuda_test_compile_worked AND cudnn_test_compile_worked AND cudnn_include)
659790
set(source_files ${source_files}
660791
cuda/cuda_dlib.cu
661792
cuda/cudnn_dlibapi.cpp
@@ -665,19 +796,22 @@ if (NOT TARGET dlib)
665796
cuda/cuda_data_ptr.cpp
666797
cuda/gpu_data.cpp
667798
)
799+
list (APPEND dlib_needed_private_libraries CUDA::toolkit)
668800
list (APPEND dlib_needed_private_libraries CUDA::cublas)
669-
list (APPEND dlib_needed_private_libraries ${CUDNN_LIBRARY_PATH})
801+
list (APPEND dlib_needed_private_libraries ${cudnn})
670802
list (APPEND dlib_needed_private_libraries CUDA::curand)
671803
list (APPEND dlib_needed_private_libraries CUDA::cusolver)
672804
list (APPEND dlib_needed_private_libraries CUDA::cudart)
673-
list (APPEND dlib_needed_private_libraries ${openmp_libraries})
805+
if(openmp_libraries)
806+
list (APPEND dlib_needed_private_libraries ${openmp_libraries})
807+
endif()
674808

675-
include_directories(${CUDAToolkit_INCLUDE_DIRS} ${CUDNN_INCLUDE_PATH})
809+
include_directories(${cudnn_include})
676810
message(STATUS "Enabling CUDA support for dlib. DLIB WILL USE CUDA, compute capabilities: ${DLIB_CUDA_COMPUTE_CAPABILITIES}")
677811
else()
678812
set(DLIB_USE_CUDA OFF CACHE BOOL ${DLIB_USE_BLAS_STR} FORCE )
679813
toggle_preprocessor_switch(DLIB_USE_CUDA)
680-
if (NOT CUDA_FOUND)
814+
if (NOT CUDAToolkit_FOUND)
681815
message(STATUS "DID NOT FIND CUDA")
682816
endif()
683817
message(STATUS "Disabling CUDA support for dlib. DLIB WILL NOT USE CUDA")
@@ -762,6 +896,9 @@ if (NOT TARGET dlib)
762896
target_compile_options(dlib PRIVATE "-DDLIB_CHECK_FOR_VERSION_MISMATCH=${DLIB_CHECK_FOR_VERSION_MISMATCH}")
763897
endif()
764898

899+
if (DLIB_USE_CUDA)
900+
set_target_properties(dlib PROPERTIES CUDA_ARCHITECTURES ${DLIB_CUDA_COMPUTE_CAPABILITIES})
901+
endif()
765902

766903
# Allow the unit tests to ask us to compile the all/source.cpp file just to make sure it compiles.
767904
if (DLIB_TEST_COMPILE_ALL_SOURCE_CPP)

dlib/cmake_utils/findCUDNN.cmake

Lines changed: 0 additions & 76 deletions
This file was deleted.

dlib/cmake_utils/test_for_cuda/CMakeLists.txt

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,9 @@ add_definitions(-DDLIB_USE_CUDA)
77

88
# Override the FindCUDA.cmake setting to avoid duplication of host flags if using a toolchain:
99
option(CUDA_PROPAGATE_HOST_FLAGS "Propage C/CXX_FLAGS and friends to the host compiler via -Xcompile" OFF)
10-
find_package(CUDA 7.5 REQUIRED)
10+
find_package(CUDAToolkit 7.5 REQUIRED)
1111
set(CUDA_HOST_COMPILATION_CPP ON)
1212
list(APPEND CUDA_NVCC_FLAGS "-arch=sm_50;-std=c++14;-D__STRICT_ANSI__;-D_MWAITXINTRIN_H_INCLUDED;-D_FORCE_INLINES")
1313

14-
cuda_add_library(cuda_test STATIC cuda_test.cu )
14+
enable_language(CUDA)
15+
add_library(cuda_test STATIC cuda_test.cu )

dlib/cmake_utils/test_for_cudnn/CMakeLists.txt

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ project(cudnn_test)
44

55
# Override the FindCUDA.cmake setting to avoid duplication of host flags if using a toolchain:
66
option(CUDA_PROPAGATE_HOST_FLAGS "Propage C/CXX_FLAGS and friends to the host compiler via -Xcompile" OFF)
7-
find_package(CUDA 7.5 REQUIRED)
7+
find_package(CUDAToolkit 7.5 REQUIRED)
88
set(CUDA_HOST_COMPILATION_CPP ON)
99
list(APPEND CUDA_NVCC_FLAGS "-arch=sm_50;-std=c++14;-D__STRICT_ANSI__")
1010
add_definitions(-DDLIB_USE_CUDA)
@@ -13,6 +13,7 @@ include(find_cudnn.txt)
1313

1414
if (cudnn_include AND cudnn)
1515
include_directories(${cudnn_include})
16-
cuda_add_library(cudnn_test STATIC ../../cuda/cudnn_dlibapi.cpp ${cudnn} )
16+
enable_language(CUDA)
17+
add_library(cudnn_test STATIC ../../cuda/cudnn_dlibapi.cpp ${cudnn} )
1718
target_compile_features(cudnn_test PUBLIC cxx_std_14)
1819
endif()

0 commit comments

Comments
 (0)