From fe192a610e0b7ca9a75f1732a9989e6a7a0971fb Mon Sep 17 00:00:00 2001 From: Matthias Maier Date: Mon, 14 Aug 2017 17:35:55 -0500 Subject: [PATCH] CMake: Restructure CUDA detection This commit restructures the CUDA detection into its own FindCUDA.cmake module. Further, CUDA support now requires CMake version 3.9 for proper cmake-internal language support. --- cmake/configure/configure_1_cuda.cmake | 110 +++++++++++-------------- cmake/modules/FindCUDA.cmake | 69 ++++++++++++++++ cmake/setup_cached_variables.cmake | 13 ++- cmake/setup_write_config.cmake | 4 + 4 files changed, 135 insertions(+), 61 deletions(-) create mode 100644 cmake/modules/FindCUDA.cmake diff --git a/cmake/configure/configure_1_cuda.cmake b/cmake/configure/configure_1_cuda.cmake index 7814f4f92f..f8b4fd3fb0 100644 --- a/cmake/configure/configure_1_cuda.cmake +++ b/cmake/configure/configure_1_cuda.cmake @@ -24,80 +24,70 @@ SET(DEAL_II_WITH_CUDA FALSE CACHE BOOL "") MACRO(FEATURE_CUDA_FIND_EXTERNAL var) - # - # FIXME Restructure this call into a ./modules/FindCUDA.cmake file and - # use DEAL_II_PACKAGE_HANDLE - # FIND_PACKAGE(CUDA) - MARK_AS_ADVANCED( - CUDA_HOST_COMPILER - CUDA_SDK_ROOT_DIR - CUDA_TOOLKIT_ROOT_DIR - CUDA_USE_STATIC_CUDA_RUNTIME - ) IF(CUDA_FOUND) - + # + # CUDA was found, check whether we can actually use it: + # SET(${var} TRUE) - IF(DEFINED CUDA_DIR) - SET(CUDA_TOOLKIT_ROOT_DIR "${CUDA_DIR}") + # + # CUDA support requires CMake version 3.9 or newer + # + IF(CMAKE_VERSION VERSION_LESS 3.9) + SET(${var} FALSE) + MESSAGE(STATUS "deal.II requires CMake version 3.9, or newer for CUDA support") + SET(CUDA_ADDITIONAL_ERROR_STRING + ${CUDA_ADDITIONAL_ERROR_STRING} + "deal.II requires CMake version 3.9, or newer for CUDA support.\n" + "Reconfigure with a sufficient cmake version." + ) ENDIF() - MESSAGE(STATUS "Configured to use CUDA installation at ${CUDA_TOOLKIT_ROOT_DIR}") - - IF("${CUDA_NVCC_FLAGS}" MATCHES "-arch") - - # Compute Capability specified explicitly. - # Now parse: - - IF("${CUDA_NVCC_FLAGS}" MATCHES "-arch[ ]*sm_([0-9]*)") - SET(CUDA_COMPUTE_CAPABILITY "${CMAKE_MATCH_1}") - ELSEIF("${CUDA_NVCC_FLAGS}" MATCHES "-arch=sm_([0-9]*)") - SET(CUDA_COMPUTE_CAPABILITY "${CMAKE_MATCH_1}") - ELSE() - STRING(REGEX MATCH "(-arch[ ]*[^ ]*)" match "${CUDA_NVCC_FLAGS}") - MESSAGE(STATUS "Ill-formed Compute Capability specified.") - SET(CUDA_ADDITIONAL_ERROR_STRING - ${CUDA_ADDITIONAL_ERROR_STRING} - "An ill-formed Compute Capability was passed in CUDA_NVCC_FLAGS: ${match}\n" - "deal.II requires at least Compute Capability 3.5\n" - "which is used as default is nothing is specified." - ) - SET(${var} FALSE) - ENDIF() - - - IF("${CUDA_COMPUTE_CAPABILITY}" LESS "35") - MESSAGE(STATUS "Too low CUDA Compute Capability specified -- deal.II requires at least 3.5 ") - SET(CUDA_ADDITIONAL_ERROR_STRING - ${CUDA_ADDITIONAL_ERROR_STRING} - "Too low CUDA Compute Capability specified: ${CUDA_COMPUTE_CAPABILITY}\n" - "deal.II requires at least Compute Capability 3.5\n" - "which is used as default is nothing is specified." - ) - SET(${var} FALSE) - ENDIF() + + IF("${DEAL_II_CUDA_FLAGS}" MATCHES "-arch[ ]*sm_([0-9]*)") + SET(CUDA_COMPUTE_CAPABILITY "${CMAKE_MATCH_1}") + ELSEIF("${DEAL_II_CUDA_FLAGS}" MATCHES "-arch=sm_([0-9]*)") + SET(CUDA_COMPUTE_CAPABILITY "${CMAKE_MATCH_1}") + ELSE() + # + # Assume a cuda compute capability of 35 + # + SET(CUDA_COMPUTE_CAPABILITY "35") + ADD_FLAGS(DEAL_II_CUDA_FLAGS "-arch=sm_35") + ENDIF() + + IF("${CUDA_COMPUTE_CAPABILITY}" LESS "35") + MESSAGE(STATUS "Too low CUDA Compute Capability specified -- deal.II requires at least 3.5 ") + SET(CUDA_ADDITIONAL_ERROR_STRING + ${CUDA_ADDITIONAL_ERROR_STRING} + "Too low CUDA Compute Capability specified: ${CUDA_COMPUTE_CAPABILITY}\n" + "deal.II requires at least Compute Capability 3.5\n" + "which is used as default if nothing is specified." + ) + SET(${var} FALSE) ENDIF() + ENDIF() +ENDMACRO() - # Configuration was successful - IF(${var}) - IF( NOT DEFINED CUDA_COMPUTE_CAPABILITY) - # Set to use compute capability 3.5 by default - SET(CUDA_COMPUTE_CAPABILITY "35") - SET(CUDA_NVCC_FLAGS ${CUDA_NVCC_FLAGS} -arch=sm_35) - ENDIF() +MACRO(FEATURE_CUDA_CONFIGURE_EXTERNAL) - # Export further definitions - STRING(SUBSTRING "${CUDA_COMPUTE_CAPABILITY}" 0 1 CUDA_COMPUTE_CAPABILITY_MAJOR) - STRING(SUBSTRING "${CUDA_COMPUTE_CAPABILITY}" 1 1 CUDA_COMPUTE_CAPABILITY_MINOR) - SET(CUDA_ATTACH_VS_BUILD_RULE_TO_CUDA_FILE FALSE) + ENABLE_LANGUAGE(CUDA) - ENDIF() - ENDIF() + # + # Set up cuda flags: + # + ADD_FLAGS(DEAL_II_CUDA_FLAGS "${DEAL_II_CXX_VERSION_FLAG}") + # + # Export definitions: + # + STRING(SUBSTRING "${CUDA_COMPUTE_CAPABILITY}" 0 1 CUDA_COMPUTE_CAPABILITY_MAJOR) + STRING(SUBSTRING "${CUDA_COMPUTE_CAPABILITY}" 1 1 CUDA_COMPUTE_CAPABILITY_MINOR) ENDMACRO() + MACRO(FEATURE_CUDA_ERROR_MESSAGE) MESSAGE(FATAL_ERROR "\n" "Could not find any suitable cuda library!\n" diff --git a/cmake/modules/FindCUDA.cmake b/cmake/modules/FindCUDA.cmake new file mode 100644 index 0000000000..4a30f6f3fa --- /dev/null +++ b/cmake/modules/FindCUDA.cmake @@ -0,0 +1,69 @@ +## --------------------------------------------------------------------- +## +## Copyright (C) 2014 - 2016 by the deal.II authors +## +## This file is part of the deal.II library. +## +## The deal.II library is free software; you can use it, redistribute +## it, and/or modify it under the terms of the GNU Lesser General +## Public License as published by the Free Software Foundation; either +## version 2.1 of the License, or (at your option) any later version. +## The full text of the license can be found in the file LICENSE at +## the top level of the deal.II distribution. +## +## --------------------------------------------------------------------- + +# +# Try to find cuda +# +# This module exports: +# +# CUDA_FOUND +# CUDA_LIBRARIES +# CUDA_INCLUDE_DIRS +# CUDA_VERSION +# CUDA_VERSION_MAJOR +# CUDA_VERSION_MINOR +# + +SET(CUDA_DIR "" CACHE PATH "An optional hint to a CUDA installation") +SET_IF_EMPTY(CUDA_DIR "$ENV{CUDA_DIR}") + +IF(NOT "${CUDA_DIR}" STREQUAL "") + SET(CUDA_TOOLKIT_ROOT_DIR "${CUDA_DIR}") +ENDIF() + +# temporarily disable ${CMAKE_SOURCE_DIR}/cmake/modules for module lookup +LIST(REMOVE_ITEM CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/modules/) +FIND_PACKAGE(CUDA) +LIST(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/modules/) + +IF(CUDA_FOUND) + MESSAGE(STATUS "Configured to use CUDA installation at ${CUDA_TOOLKIT_ROOT_DIR}") +ENDIF() + +SET(_cuda_libraries ${CUDA_LIBRARIES}) +SET(_cuda_include_dirs ${CUDA_INCLUDE_DIRS}) +DEAL_II_PACKAGE_HANDLE(CUDA + LIBRARIES REQUIRED _cuda_libraries + INCLUDE_DIRS REQUIRED _cuda_include_dirs + USER_INCLUDE_DIRS REQUIRED _cuda_include_dirs + CLEAR + CUDA_cublas_device_LIBRARY + CUDA_cublas_LIBRARY + CUDA_cudadevrt_LIBRARY + CUDA_cudart_static_LIBRARY + CUDA_cufft_LIBRARY + CUDA_cupti_LIBRARY + CUDA_curand_LIBRARY + CUDA_cusolver_LIBRARY + CUDA_cusparse_LIBRARY + CUDA_HOST_COMPILER + CUDA_nppc_LIBRARY + CUDA_nppi_LIBRARY + CUDA_npps_LIBRARY + CUDA_rt_LIBRARY + CUDA_SDK_ROOT_DIR + CUDA_TOOLKIT_ROOT_DIR + CUDA_USE_STATIC_CUDA_RUNTIME + ) diff --git a/cmake/setup_cached_variables.cmake b/cmake/setup_cached_variables.cmake index 43cfbf5822..b92d67d4d6 100644 --- a/cmake/setup_cached_variables.cmake +++ b/cmake/setup_cached_variables.cmake @@ -223,6 +223,11 @@ SET(DEAL_II_REMOVED_FLAGS CMAKE_Fortran_FLAGS_DEBUG CMAKE_Fortran_FLAGS_MINSIZEREL CMAKE_Fortran_FLAGS_RELWITHDEBINFO + CMAKE_CUDA_FLAGS + CMAKE_CUDA_FLAGS_RELEASE + CMAKE_CUDA_FLAGS_DEBUG + CMAKE_CUDA_FLAGS_MINSIZEREL + CMAKE_CUDA_FLAGS_RELWITHDEBINFO CMAKE_SHARED_LINKER_FLAGS CMAKE_SHARED_LINKER_FLAGS_DEBUG CMAKE_SHARED_LINKER_FLAGS_MINSIZEREL @@ -244,6 +249,9 @@ ENDFOREACH() # SET(DEAL_II_USED_FLAGS + DEAL_II_CUDA_FLAGS + DEAL_II_CUDA_FLAGS_DEBUG + DEAL_II_CUDA_FLAGS_RELEASE DEAL_II_CXX_FLAGS DEAL_II_CXX_FLAGS_DEBUG DEAL_II_CXX_FLAGS_RELEASE @@ -273,7 +281,10 @@ ENDFOREACH() # Translate CMake specific variables to deal.II naming: # -FOREACH(_flag CXX_FLAGS CXX_FLAGS_RELEASE CXX_FLAGS_DEBUG) +FOREACH(_flag + CUDA_FLAGS CUDA_FLAGS_RELEASE CUDA_FLAGS_DEBUG + CXX_FLAGS CXX_FLAGS_RELEASE CXX_FLAGS_DEBUG + ) IF(NOT "${CMAKE_${_flag}}" STREQUAL "") MESSAGE(STATUS "Prepending \${CMAKE_${_flag}} to \${DEAL_II_${_flag}}" diff --git a/cmake/setup_write_config.cmake b/cmake/setup_write_config.cmake index 425c9b627c..d832f6e885 100644 --- a/cmake/setup_write_config.cmake +++ b/cmake/setup_write_config.cmake @@ -210,7 +210,11 @@ FOREACH(_feature ${_deal_ii_features_sorted}) _detailed("# OMPI_VERSION = ${OMPI_VERSION}\n") ENDIF() IF(_feature MATCHES "CUDA" AND DEFINED CUDA_COMPUTE_CAPABILITY) + _detailed("# CMAKE_CUDA_COMPILER = ${CMAKE_CUDA_COMPILER}\n") _detailed("# CUDA_COMPUTE_CAPABILITY = ${CUDA_COMPUTE_CAPABILITY_MAJOR}.${CUDA_COMPUTE_CAPABILITY_MINOR}\n") + _detailed("# DEAL_II_CUDA_FLAGS = ${DEAL_II_CUDA_FLAGS}\n") + _detailed("# DEAL_II_CUDA_FLAGS_RELEASE = ${DEAL_II_CUDA_FLAGS_RELEASE}\n") + _detailed("# DEAL_II_CUDA_FLAGS_DEBUG = ${DEAL_II_CUDA_FLAGS_DEBUG}\n") ENDIF() -- 2.39.5