From 89a0302df3b321fad9330ca038592f766a39cda4 Mon Sep 17 00:00:00 2001 From: Juan Hernando Vieites Date: Wed, 3 Aug 2016 13:50:46 +0200 Subject: [PATCH] Some common tricks needed for projects using CUDA. The tricks are necessary to avoid warnings in some cases. --- CHANGES.md | 2 + CommonCUDA.cmake | 92 +++++++++++++++++++++++++++++++++++++++++ CommonFindPackage.cmake | 5 +++ 3 files changed, 99 insertions(+) create mode 100644 CommonCUDA.cmake diff --git a/CHANGES.md b/CHANGES.md index 3b8d917..410fc3e 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,5 +1,7 @@ # git master +* [505](https://github.com/Eyescale/CMake/pull/505): + Added CommonCUDA.cmake with some common configuration checks for CUDA. * [504](https://github.com/Eyescale/CMake/pull/504): * Add support for yum to subproject_install_packages * Make sure that package installation is only attempted if INSTALL_PACKAGES diff --git a/CommonCUDA.cmake b/CommonCUDA.cmake new file mode 100644 index 0000000..6a11155 --- /dev/null +++ b/CommonCUDA.cmake @@ -0,0 +1,92 @@ +# Copyright (c) 2016 Juan.Hernando@epfl.ch + +# Provides two functions for common configuration checks and setup for projects +# using CUDA. +# In particular: +# * find_cuda_compatible_host_compiler() tries to set CUDA_HOST_COMPILER to a +# version compatible with the CUDA version detected. +# * common_cuda_compile_options() sets the default architecture to a minimum +# value that does not cause deprecation warnings with newer version of nvcc. + +function(find_cuda_compatible_host_compiler) + if(NOT CMAKE_COMPILER_IS_GNUCXX) + # Only implemented for gcc + return() + endif() + + set(_host_config "${CUDA_INCLUDE_DIRS}/host_config.h") + + if(NOT EXISTS "${_host_config}") + message(SEND_ERROR "host_config.h CUDA header not found") + return() + endif() + + # Finding the maximum version of gcc supported by the CUDA installation + # detected + + file(STRINGS "${_host_config}" _host_config_content REGEX "#if __GNUC__") + # Different versions of host_config.h differ in how they check if the + # version of gcc is supported. + string(REGEX REPLACE "#if __GNUC__ == ([0-9]) && __GNUC_MINOR__ > ([0-9]+)" + "\\1.\\2" _max_gcc_version_supported ${_host_config_content}) + string(REGEX REPLACE "#if __GNUC__ > ([0-9])" + "\\1" _max_gcc_version_supported ${_max_gcc_version_supported}) + string(REPLACE "." "" _maxgccversionsupported ${_max_gcc_version_supported}) + + if(# Rejecting ccache as the host compiler as this causes errors later on. + CMAKE_C_COMPILER MATCHES ".*/ccache/.*" OR + # Then comparing the highest version supported by the CUDA SDK with the + # version of the default compiler. + ${_max_gcc_version_supported} VERSION_LESS ${GCC_COMPILER_VERSION}) + + if(${GCC_COMPILER_VERSION} VERSION_LESS ${_max_gcc_version_supported}) + set(_max_gcc_version_supported ${GCC_COMPILER_VERSION}) + endif() + + # Finding a suitable compiler + find_program(_gcc_binary gcc-${_max_gcc_version_supported}) + if(NOT _gcc_binary) + # RHEL package mantainers use this naming convention for symbolic links + find_program(_gcc_binary gcc${_maxgccversionsupported}) + endif() + + if(NOT _gcc_binary) + # Trying finally with the default compiler on the path. + # This is needed for example when not using a system level binary. + find_program(_gcc_binary gcc) + execute_process(COMMAND ${_gcc_binary} -dumpversion + OUTPUT_VARIABLE _gcc_version OUTPUT_STRIP_TRAILING_WHITESPACE) + # Reducing the version number to 1 or 2 digits depending on how + # host_config.h checks the version. + if (${_max_gcc_version_supported} MATCHES "[0-9]+\\.[0-9]+") + string(REGEX REPLACE "([0-9])\\.([0-9])(\\.[0-9])?" "\\1.\\2" + _gcc_version "${_gcc_version}") + else() + string(REGEX REPLACE "([0-9])\\.([0-9])(\\.[0-9])?" "\\1" + _gcc_version "${_gcc_version}") + endif() + if(${_gcc_version} VERSION_GREATER ${_max_gcc_version_supported}) + unset(_gcc_binary CACHE) + endif() + endif() + + if(NOT _gcc_binary) + message(WARNING "A version of gcc compatible with CUDA ${CUDA_VERSION} was not found.") + else() + set(CUDA_HOST_COMPILER ${_gcc_binary} PARENT_SCOPE) + endif() + unset(_gcc_binary CACHE) + endif() + +endfunction() + +# CUDA compile flags +function(common_cuda_compile_options) + if(CUDA_VERSION VERSION_LESS 6.0) + set(CUDA_NVCC_FLAGS "${CUDA_NVCC_FLAGS} -arch=sm_11" PARENT_SCOPE) + else() + set(CUDA_NVCC_FLAGS "${CUDA_NVCC_FLAGS} -arch=sm_20" PARENT_SCOPE) + endif() +endfunction() + + diff --git a/CommonFindPackage.cmake b/CommonFindPackage.cmake index 265fb02..89dc855 100644 --- a/CommonFindPackage.cmake +++ b/CommonFindPackage.cmake @@ -34,6 +34,7 @@ include(CommonGraph) include(InstallFiles) +include(CommonCUDA) if(NOT PKGCONFIG_FOUND AND NOT MSVC) find_package(PkgConfig QUIET) @@ -258,6 +259,10 @@ macro(common_find_package_post) include_directories(SYSTEM ${MPI_C_INCLUDE_PATH} ${MPI_CXX_INCLUDE_PATH}) endif() + if(CUDA_FOUND) + find_cuda_compatible_host_compiler() + endif() + set(__configure_msg "Configured ${PROJECT_NAME} [${GIT_STATE}]") if(${PROJECT_NAME}_FIND_PACKAGES_FOUND) set(__configure_msg