From 711de9aef6d900ffd52d8b540161945fa405c684 Mon Sep 17 00:00:00 2001 From: Brad King Date: Mon, 18 Sep 2023 14:39:17 -0400 Subject: cmGeneratorTarget: Clarify local variable names for device architectures --- Source/cmGeneratorTarget.cxx | 41 ++++++++++++++++++++--------------------- 1 file changed, 20 insertions(+), 21 deletions(-) diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx index 764618e..0eb3851 100644 --- a/Source/cmGeneratorTarget.cxx +++ b/Source/cmGeneratorTarget.cxx @@ -3390,9 +3390,9 @@ void cmGeneratorTarget::AddCUDAArchitectureFlags(cmBuildStep compileOrLink, const std::string& config, std::string& flags) const { - std::string property = this->GetSafeProperty("CUDA_ARCHITECTURES"); + std::string arch = this->GetSafeProperty("CUDA_ARCHITECTURES"); - if (property.empty()) { + if (arch.empty()) { switch (this->GetPolicyStatusCMP0104()) { case cmPolicies::WARN: if (!this->LocalGenerator->GetCMakeInstance()->GetIsInTryCompile()) { @@ -3414,7 +3414,7 @@ void cmGeneratorTarget::AddCUDAArchitectureFlags(cmBuildStep compileOrLink, } // If CUDA_ARCHITECTURES is false we don't add any architectures. - if (cmIsOff(property)) { + if (cmIsOff(arch)) { return; } @@ -3423,23 +3423,22 @@ void cmGeneratorTarget::AddCUDAArchitectureFlags(cmBuildStep compileOrLink, const bool ipoEnabled = this->IsIPOEnabled("CUDA", config); // Check for special modes: `all`, `all-major`. - if (property == "all" || property == "all-major") { + if (arch == "all" || arch == "all-major") { if (compiler == "NVIDIA" && cmSystemTools::VersionCompare( cmSystemTools::OP_GREATER_EQUAL, this->Makefile->GetDefinition("CMAKE_CUDA_COMPILER_VERSION"), "11.5")) { - flags = cmStrCat(flags, " -arch=", property); + flags = cmStrCat(flags, " -arch=", arch); return; } - if (property == "all") { - property = - *this->Makefile->GetDefinition("CMAKE_CUDA_ARCHITECTURES_ALL"); - } else if (property == "all-major") { - property = + if (arch == "all") { + arch = *this->Makefile->GetDefinition("CMAKE_CUDA_ARCHITECTURES_ALL"); + } else if (arch == "all-major") { + arch = *this->Makefile->GetDefinition("CMAKE_CUDA_ARCHITECTURES_ALL_MAJOR"); } - } else if (property == "native") { + } else if (arch == "native") { cmValue native = this->Makefile->GetDefinition("CMAKE_CUDA_ARCHITECTURES_NATIVE"); if (native.IsEmpty()) { @@ -3452,10 +3451,10 @@ void cmGeneratorTarget::AddCUDAArchitectureFlags(cmBuildStep compileOrLink, cmSystemTools::OP_GREATER_EQUAL, this->Makefile->GetDefinition("CMAKE_CUDA_COMPILER_VERSION"), "11.6")) { - flags = cmStrCat(flags, " -arch=", property); + flags = cmStrCat(flags, " -arch=", arch); return; } - property = *native; + arch = *native; } struct CudaArchitecture @@ -3467,7 +3466,7 @@ void cmGeneratorTarget::AddCUDAArchitectureFlags(cmBuildStep compileOrLink, std::vector architectures; { - cmList options(property); + cmList options(arch); for (auto& option : options) { CudaArchitecture architecture; @@ -3549,10 +3548,10 @@ void cmGeneratorTarget::AddCUDAArchitectureFlags(cmBuildStep compileOrLink, void cmGeneratorTarget::AddISPCTargetFlags(std::string& flags) const { - const std::string& property = this->GetSafeProperty("ISPC_INSTRUCTION_SETS"); + const std::string& arch = this->GetSafeProperty("ISPC_INSTRUCTION_SETS"); // If ISPC_TARGET is false we don't add any architectures. - if (cmIsOff(property)) { + if (cmIsOff(arch)) { return; } @@ -3560,7 +3559,7 @@ void cmGeneratorTarget::AddISPCTargetFlags(std::string& flags) const this->Makefile->GetSafeDefinition("CMAKE_ISPC_COMPILER_ID"); if (compiler == "Intel") { - cmList targets(property); + cmList targets(arch); if (!targets.empty()) { flags += cmStrCat(" --target=", cmWrap("", targets, "", ",")); } @@ -3569,20 +3568,20 @@ void cmGeneratorTarget::AddISPCTargetFlags(std::string& flags) const void cmGeneratorTarget::AddHIPArchitectureFlags(std::string& flags) const { - const std::string& property = this->GetSafeProperty("HIP_ARCHITECTURES"); + const std::string& arch = this->GetSafeProperty("HIP_ARCHITECTURES"); - if (property.empty()) { + if (arch.empty()) { this->Makefile->IssueMessage(MessageType::FATAL_ERROR, "HIP_ARCHITECTURES is empty for target \"" + this->GetName() + "\"."); } // If HIP_ARCHITECTURES is false we don't add any architectures. - if (cmIsOff(property)) { + if (cmIsOff(arch)) { return; } - cmList options(property); + cmList options(arch); for (std::string& option : options) { flags += " --offload-arch=" + option; -- cgit v0.12 From 72efbeadae4b99db0d26802d95771873873151db Mon Sep 17 00:00:00 2001 From: Brad King Date: Thu, 14 Sep 2023 10:39:24 -0400 Subject: CUDA: Simplify CMAKE_GENERATOR references for determining compiler --- Modules/CMakeDetermineCUDACompiler.cmake | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Modules/CMakeDetermineCUDACompiler.cmake b/Modules/CMakeDetermineCUDACompiler.cmake index 53c5f78..de765d7 100644 --- a/Modules/CMakeDetermineCUDACompiler.cmake +++ b/Modules/CMakeDetermineCUDACompiler.cmake @@ -4,13 +4,13 @@ include(${CMAKE_ROOT}/Modules/CMakeDetermineCompiler.cmake) include(${CMAKE_ROOT}/Modules/CMakeParseImplicitLinkInfo.cmake) -if( NOT ( ("${CMAKE_GENERATOR}" MATCHES "Make") OR - ("${CMAKE_GENERATOR}" MATCHES "Ninja") OR - ("${CMAKE_GENERATOR}" MATCHES "Visual Studio (1|[9][0-9])") ) ) +if(NOT ((CMAKE_GENERATOR MATCHES "Make") OR + (CMAKE_GENERATOR MATCHES "Ninja") OR + (CMAKE_GENERATOR MATCHES "Visual Studio (1|[9][0-9])"))) message(FATAL_ERROR "CUDA language not currently supported by \"${CMAKE_GENERATOR}\" generator") endif() -if(${CMAKE_GENERATOR} MATCHES "Visual Studio") +if(CMAKE_GENERATOR MATCHES "Visual Studio") if(DEFINED ENV{CUDAHOSTCXX} OR DEFINED CMAKE_CUDA_HOST_COMPILER) message(WARNING "Visual Studio does not support specifying CUDAHOSTCXX or CMAKE_CUDA_HOST_COMPILER. Using the C++ compiler provided by Visual Studio.") endif() @@ -62,7 +62,7 @@ if(NOT CMAKE_CUDA_COMPILER_ID_RUN) include(${CMAKE_ROOT}/Modules/CMakeDetermineCompilerId.cmake) - if(${CMAKE_GENERATOR} MATCHES "Visual Studio") + if(CMAKE_GENERATOR MATCHES "Visual Studio") # We will not know CMAKE_CUDA_COMPILER until the main compiler id step # below extracts it, but we do know that the compiler id will be NVIDIA. set(CMAKE_CUDA_COMPILER_ID "NVIDIA") @@ -306,7 +306,7 @@ if(NOT CMAKE_CUDA_COMPILER_ID_RUN) CMAKE_DETERMINE_COMPILER_ID(CUDA CUDAFLAGS CMakeCUDACompilerId.cu) - if(${CMAKE_GENERATOR} MATCHES "Visual Studio") + if(CMAKE_GENERATOR MATCHES "Visual Studio") # Now that we have the path to nvcc, we can compute the toolkit root. get_filename_component(CMAKE_CUDA_COMPILER_TOOLKIT_ROOT "${CMAKE_CUDA_COMPILER}" DIRECTORY) get_filename_component(CMAKE_CUDA_COMPILER_TOOLKIT_ROOT "${CMAKE_CUDA_COMPILER_TOOLKIT_ROOT}" DIRECTORY) @@ -331,7 +331,7 @@ if(MSVC_CUDA_ARCHITECTURE_ID) "set(MSVC_CUDA_ARCHITECTURE_ID ${MSVC_CUDA_ARCHITECTURE_ID})") endif() -if(${CMAKE_GENERATOR} MATCHES "Visual Studio") +if(CMAKE_GENERATOR MATCHES "Visual Studio") set(CMAKE_CUDA_HOST_LINK_LAUNCHER "${CMAKE_LINKER}") set(CMAKE_CUDA_HOST_IMPLICIT_LINK_LIBRARIES "") set(CMAKE_CUDA_HOST_IMPLICIT_LINK_DIRECTORIES "") -- cgit v0.12 From 8a966debe30324c38d5ab91adaeec10c0d6cafd3 Mon Sep 17 00:00:00 2001 From: Brad King Date: Thu, 14 Sep 2023 10:40:21 -0400 Subject: CUDA: Combine consecutive blocks using same condition for determining compiler --- Modules/CMakeDetermineCUDACompiler.cmake | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/Modules/CMakeDetermineCUDACompiler.cmake b/Modules/CMakeDetermineCUDACompiler.cmake index de765d7..a5008e1 100644 --- a/Modules/CMakeDetermineCUDACompiler.cmake +++ b/Modules/CMakeDetermineCUDACompiler.cmake @@ -236,11 +236,9 @@ if(NOT CMAKE_CUDA_COMPILER_ID_RUN) else() set(CMAKE_CUDA_COMPILER_TOOLKIT_LIBRARY_ROOT "${CMAKE_CUDA_COMPILER_TOOLKIT_ROOT}") endif() - endif() - # For regular nvcc we the toolkit version is the same as the compiler version and we can parse it from the vendor test output. - # For Clang we need to invoke nvcc to get version output. - if(NOT CMAKE_GENERATOR MATCHES "Visual Studio") + # For regular nvcc we the toolkit version is the same as the compiler version and we can parse it from the vendor test output. + # For Clang we need to invoke nvcc to get version output. if(CMAKE_CUDA_COMPILER_ID STREQUAL "Clang") execute_process(COMMAND ${_CUDA_NVCC_EXECUTABLE} "--version" OUTPUT_VARIABLE CMAKE_CUDA_COMPILER_ID_OUTPUT) endif() -- cgit v0.12 From 69a5ef7cc0011e9c9782a9f0294dced465702e3b Mon Sep 17 00:00:00 2001 From: Brad King Date: Thu, 14 Sep 2023 11:18:47 -0400 Subject: CUDA: Simplify isolation of work variables for determining compiler Unset variables as soon as we are done with them. Rename one work variable to a private name. --- Modules/CMakeDetermineCUDACompiler.cmake | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/Modules/CMakeDetermineCUDACompiler.cmake b/Modules/CMakeDetermineCUDACompiler.cmake index a5008e1..d1edec5 100644 --- a/Modules/CMakeDetermineCUDACompiler.cmake +++ b/Modules/CMakeDetermineCUDACompiler.cmake @@ -98,12 +98,14 @@ if(NOT CMAKE_CUDA_COMPILER_ID_RUN) ENV CUDA_PATH PATH_SUFFIXES bin NO_DEFAULT_PATH + NO_CACHE ) # If we didn't find NVCC, then try the default paths. find_program(_CUDA_NVCC_EXECUTABLE NAMES nvcc nvcc.exe PATH_SUFFIXES bin + NO_CACHE ) # If the user specified CUDAToolkit_ROOT but nvcc could not be found, this is an error. @@ -168,6 +170,7 @@ if(NOT CMAKE_CUDA_COMPILER_ID_RUN) NAMES nvcc nvcc.exe PATHS ${search_paths} PATH_SUFFIXES bin + NO_CACHE ) # We are done with these variables now, cleanup. @@ -200,7 +203,7 @@ if(NOT CMAKE_CUDA_COMPILER_ID_RUN) #We require the path to end in `/nvvm/libdevice' if(_CUDA_NVVMIR_LIBRARY_DIR MATCHES "nvvm/libdevice$") get_filename_component(_CUDA_NVVMIR_LIBRARY_DIR "${_CUDA_NVVMIR_LIBRARY_DIR}/../.." ABSOLUTE) - set(CMAKE_CUDA_COMPILER_LIBRARY_ROOT_FROM_NVVMIR_LIBRARY_DIR "${_CUDA_NVVMIR_LIBRARY_DIR}") + set(_CUDA_COMPILER_LIBRARY_ROOT_FROM_NVVMIR_LIBRARY_DIR "${_CUDA_NVVMIR_LIBRARY_DIR}") endif() unset(_CUDA_NVVMIR_LIBRARY_DIR) @@ -215,8 +218,8 @@ if(NOT CMAKE_CUDA_COMPILER_ID_RUN) # We first check for a non-scattered installation to prefer it over a scattered installation. # CMAKE_CUDA_COMPILER_LIBRARY_ROOT contains the device library. - if(DEFINED CMAKE_CUDA_COMPILER_LIBRARY_ROOT_FROM_NVVMIR_LIBRARY_DIR) - set(CMAKE_CUDA_COMPILER_LIBRARY_ROOT "${CMAKE_CUDA_COMPILER_LIBRARY_ROOT_FROM_NVVMIR_LIBRARY_DIR}") + if(DEFINED _CUDA_COMPILER_LIBRARY_ROOT_FROM_NVVMIR_LIBRARY_DIR) + set(CMAKE_CUDA_COMPILER_LIBRARY_ROOT "${_CUDA_COMPILER_LIBRARY_ROOT_FROM_NVVMIR_LIBRARY_DIR}") elseif(EXISTS "${CMAKE_CUDA_COMPILER_TOOLKIT_ROOT}/nvvm/libdevice") set(CMAKE_CUDA_COMPILER_LIBRARY_ROOT "${CMAKE_CUDA_COMPILER_TOOLKIT_ROOT}") elseif(CMAKE_SYSROOT_LINK AND EXISTS "${CMAKE_SYSROOT_LINK}/usr/lib/cuda/nvvm/libdevice") @@ -226,7 +229,7 @@ if(NOT CMAKE_CUDA_COMPILER_ID_RUN) else() message(FATAL_ERROR "Couldn't find CUDA library root.") endif() - unset(CMAKE_CUDA_COMPILER_LIBRARY_ROOT_FROM_NVVMIR_LIBRARY_DIR) + unset(_CUDA_COMPILER_LIBRARY_ROOT_FROM_NVVMIR_LIBRARY_DIR) # CMAKE_CUDA_COMPILER_TOOLKIT_LIBRARY_ROOT contains the linking stubs necessary for device linking and other low-level library files. if(CMAKE_SYSROOT_LINK AND EXISTS "${CMAKE_SYSROOT_LINK}/usr/lib/nvidia-cuda-toolkit/bin/crt/link.stub") @@ -246,6 +249,9 @@ if(NOT CMAKE_CUDA_COMPILER_ID_RUN) if(CMAKE_CUDA_COMPILER_ID_OUTPUT MATCHES [=[V([0-9]+\.[0-9]+\.[0-9]+)]=]) set(CMAKE_CUDA_COMPILER_TOOLKIT_VERSION "${CMAKE_MATCH_1}") endif() + + # Don't leak variables unnecessarily to user code. + unset(_CUDA_NVCC_EXECUTABLE) endif() set(CMAKE_CUDA_COMPILER_ID_FLAGS_ALWAYS "-v") @@ -409,6 +415,12 @@ elseif(CMAKE_CUDA_COMPILER_ID STREQUAL "Clang") set(CMAKE_CUDA_HOST_IMPLICIT_LINK_DIRECTORIES "${_CUDA_LIBRARY_DIR}") set(CMAKE_CUDA_HOST_IMPLICIT_LINK_LIBRARIES "") set(CMAKE_CUDA_HOST_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES "") + + # Don't leak variables unnecessarily to user code. + unset(_CUDA_INCLUDE_DIR) + unset(_CUDA_LIBRARY_DIR) + unset(_CUDA_TARGET_DIR) + unset(_CUDA_TARGET_NAME) elseif(CMAKE_CUDA_COMPILER_ID STREQUAL "NVIDIA") set(_nvcc_log "") string(REPLACE "\r" "" _nvcc_output_orig "${CMAKE_CUDA_COMPILER_PRODUCED_OUTPUT}") @@ -609,13 +621,6 @@ configure_file(${CMAKE_ROOT}/Modules/CMakeCUDACompiler.cmake.in @ONLY ) -# Don't leak variables unnecessarily to user code. -unset(_CUDA_INCLUDE_DIR CACHE) -unset(_CUDA_NVCC_EXECUTABLE CACHE) -unset(_CUDA_LIBRARY_DIR) -unset(_CUDA_TARGET_DIR) -unset(_CUDA_TARGET_NAME) - unset(architectures_detected) set(CMAKE_CUDA_COMPILER_ENV_VAR "CUDACXX") -- cgit v0.12 From 7b2aec0fefe09b96583f8efc3f3df37a6caf15ce Mon Sep 17 00:00:00 2001 From: Brad King Date: Mon, 18 Sep 2023 13:07:06 -0400 Subject: CUDA: Clarify logic detecting compiler default CUDA architectures Improve variable names and comments. Remove a comment missed by commit c267ed205a (CUDA: Defer architecture testing to the compiler testing step, 2022-04-25, v3.24.0-rc1~222^2) about architecture verification. --- Modules/CMakeDetermineCUDACompiler.cmake | 29 +++++++++++++---------------- 1 file changed, 13 insertions(+), 16 deletions(-) diff --git a/Modules/CMakeDetermineCUDACompiler.cmake b/Modules/CMakeDetermineCUDACompiler.cmake index d1edec5..734b039 100644 --- a/Modules/CMakeDetermineCUDACompiler.cmake +++ b/Modules/CMakeDetermineCUDACompiler.cmake @@ -355,11 +355,12 @@ if(CMAKE_GENERATOR MATCHES "Visual Studio") set(_SET_CMAKE_CUDA_RUNTIME_LIBRARY_DEFAULT "set(CMAKE_CUDA_RUNTIME_LIBRARY_DEFAULT \"${CMAKE_CUDA_RUNTIME_LIBRARY_DEFAULT}\")") elseif(CMAKE_CUDA_COMPILER_ID STREQUAL "Clang") - string(REGEX MATCHALL "-target-cpu sm_([0-9]+)" target_cpus "${CMAKE_CUDA_COMPILER_PRODUCED_OUTPUT}") + string(REGEX MATCHALL "-target-cpu sm_([0-9]+)" _clang_target_cpus "${CMAKE_CUDA_COMPILER_PRODUCED_OUTPUT}") - foreach(cpu ${target_cpus}) - string(REGEX MATCH "-target-cpu sm_([0-9]+)" dont_care "${cpu}") - list(APPEND architectures_detected "${CMAKE_MATCH_1}") + foreach(_clang_target_cpu ${_clang_target_cpus}) + if(_clang_target_cpu MATCHES "-target-cpu sm_([0-9]+)") + list(APPEND CMAKE_CUDA_ARCHITECTURES_DEFAULT "${CMAKE_MATCH_1}") + endif() endforeach() # Find target directory when crosscompiling. @@ -593,27 +594,25 @@ if(CMAKE_CUDA_COMPILER_ID STREQUAL "NVIDIA") "Failed to detect CUDA nvcc include information:\n${_nvcc_log}\n\n") endif() - string(REGEX MATCHALL "-arch compute_([0-9]+)" target_cpus "${CMAKE_CUDA_COMPILER_PRODUCED_OUTPUT}") - - foreach(cpu ${target_cpus}) - string(REGEX MATCH "-arch compute_([0-9]+)" dont_care "${cpu}") - list(APPEND architectures_detected "${CMAKE_MATCH_1}") + string(REGEX MATCHALL "-arch compute_([0-9]+)" _nvcc_target_cpus "${CMAKE_CUDA_COMPILER_PRODUCED_OUTPUT}") + foreach(_nvcc_target_cpu ${_nvcc_target_cpus}) + if(_nvcc_target_cpu MATCHES "-arch compute_([0-9]+)") + list(APPEND CMAKE_CUDA_ARCHITECTURES_DEFAULT "${CMAKE_MATCH_1}") + endif() endforeach() endif() -# If the user didn't set the architectures, then set them to a default. -# If the user did, then make sure those architectures worked. +# If the user did not set CMAKE_CUDA_ARCHITECTURES, use the compiler's default. if("${CMAKE_CUDA_ARCHITECTURES}" STREQUAL "") cmake_policy(GET CMP0104 _CUDA_CMP0104) - if(NOT CMAKE_CUDA_COMPILER_ID STREQUAL "NVIDIA" OR _CUDA_CMP0104 STREQUAL "NEW") - set(CMAKE_CUDA_ARCHITECTURES "${architectures_detected}" CACHE STRING "CUDA architectures") - + set(CMAKE_CUDA_ARCHITECTURES "${CMAKE_CUDA_ARCHITECTURES_DEFAULT}" CACHE STRING "CUDA architectures") if(NOT CMAKE_CUDA_ARCHITECTURES) message(FATAL_ERROR "Failed to detect a default CUDA architecture.\n\nCompiler output:\n${CMAKE_CUDA_COMPILER_PRODUCED_OUTPUT}") endif() endif() endif() +unset(CMAKE_CUDA_ARCHITECTURES_DEFAULT) # configure all variables set in this file configure_file(${CMAKE_ROOT}/Modules/CMakeCUDACompiler.cmake.in @@ -621,7 +620,5 @@ configure_file(${CMAKE_ROOT}/Modules/CMakeCUDACompiler.cmake.in @ONLY ) -unset(architectures_detected) - set(CMAKE_CUDA_COMPILER_ENV_VAR "CUDACXX") set(CMAKE_CUDA_HOST_COMPILER_ENV_VAR "CUDAHOSTCXX") -- cgit v0.12 From d08b7f3cdab24a21b3da3c43b6d0d9f256f76f77 Mon Sep 17 00:00:00 2001 From: Brad King Date: Fri, 15 Sep 2023 10:39:16 -0400 Subject: CUDA: Clarify compiler-specific logic in architectures table --- Modules/CUDA/architectures.cmake | 51 +++++++++++++++++++++++++--------------- 1 file changed, 32 insertions(+), 19 deletions(-) diff --git a/Modules/CUDA/architectures.cmake b/Modules/CUDA/architectures.cmake index 7d6a6e0..87cbaaf 100644 --- a/Modules/CUDA/architectures.cmake +++ b/Modules/CUDA/architectures.cmake @@ -11,7 +11,9 @@ if(CMAKE_CUDA_COMPILER_TOOLKIT_VERSION VERSION_GREATER_EQUAL 8.0) endif() if(CMAKE_CUDA_COMPILER_TOOLKIT_VERSION VERSION_GREATER_EQUAL 9.0) - if(NOT CMAKE_CUDA_COMPILER_ID STREQUAL "Clang" OR CMAKE_CUDA_COMPILER_VERSION VERSION_GREATER_EQUAL 6.0) + if(CMAKE_CUDA_COMPILER_ID STREQUAL "NVIDIA" + OR (CMAKE_CUDA_COMPILER_ID STREQUAL "Clang" AND CMAKE_CUDA_COMPILER_VERSION VERSION_GREATER_EQUAL 6.0) + ) list(APPEND CMAKE_CUDA_ARCHITECTURES_ALL 70 72) list(APPEND CMAKE_CUDA_ARCHITECTURES_ALL_MAJOR 70) endif() @@ -20,13 +22,18 @@ if(CMAKE_CUDA_COMPILER_TOOLKIT_VERSION VERSION_GREATER_EQUAL 9.0) list(REMOVE_ITEM CMAKE_CUDA_ARCHITECTURES_ALL_MAJOR 20) endif() -if(CMAKE_CUDA_COMPILER_TOOLKIT_VERSION VERSION_GREATER_EQUAL 10.0 - AND (NOT CMAKE_CUDA_COMPILER_ID STREQUAL "Clang" OR CMAKE_CUDA_COMPILER_VERSION VERSION_GREATER_EQUAL 8.0)) - list(APPEND CMAKE_CUDA_ARCHITECTURES_ALL 75) +if(CMAKE_CUDA_COMPILER_TOOLKIT_VERSION VERSION_GREATER_EQUAL 10.0) + if(CMAKE_CUDA_COMPILER_ID STREQUAL "NVIDIA" + OR (CMAKE_CUDA_COMPILER_ID STREQUAL "Clang" AND CMAKE_CUDA_COMPILER_VERSION VERSION_GREATER_EQUAL 8.0) + ) + list(APPEND CMAKE_CUDA_ARCHITECTURES_ALL 75) + endif() endif() if(CMAKE_CUDA_COMPILER_TOOLKIT_VERSION VERSION_GREATER_EQUAL 11.0) - if(NOT CMAKE_CUDA_COMPILER_ID STREQUAL "Clang" OR CMAKE_CUDA_COMPILER_VERSION VERSION_GREATER_EQUAL 11.0) + if(CMAKE_CUDA_COMPILER_ID STREQUAL "NVIDIA" + OR (CMAKE_CUDA_COMPILER_ID STREQUAL "Clang" AND CMAKE_CUDA_COMPILER_VERSION VERSION_GREATER_EQUAL 11.0) + ) list(APPEND CMAKE_CUDA_ARCHITECTURES_ALL 80) list(APPEND CMAKE_CUDA_ARCHITECTURES_ALL_MAJOR 80) endif() @@ -35,26 +42,32 @@ if(CMAKE_CUDA_COMPILER_TOOLKIT_VERSION VERSION_GREATER_EQUAL 11.0) list(REMOVE_ITEM CMAKE_CUDA_ARCHITECTURES_ALL_MAJOR 30) endif() -if(CMAKE_CUDA_COMPILER_TOOLKIT_VERSION VERSION_GREATER_EQUAL 11.1 - AND (NOT CMAKE_CUDA_COMPILER_ID STREQUAL "Clang" OR CMAKE_CUDA_COMPILER_VERSION VERSION_GREATER_EQUAL 13.0)) - list(APPEND CMAKE_CUDA_ARCHITECTURES_ALL 86) +if(CMAKE_CUDA_COMPILER_TOOLKIT_VERSION VERSION_GREATER_EQUAL 11.1) + if(CMAKE_CUDA_COMPILER_ID STREQUAL "NVIDIA" + OR (CMAKE_CUDA_COMPILER_ID STREQUAL "Clang" AND CMAKE_CUDA_COMPILER_VERSION VERSION_GREATER_EQUAL 13.0) + ) + list(APPEND CMAKE_CUDA_ARCHITECTURES_ALL 86) + endif() endif() -if(CMAKE_CUDA_COMPILER_TOOLKIT_VERSION VERSION_GREATER_EQUAL 11.4 - AND (NOT CMAKE_CUDA_COMPILER_ID STREQUAL "Clang")) - list(APPEND CMAKE_CUDA_ARCHITECTURES_ALL 87) +if(CMAKE_CUDA_COMPILER_TOOLKIT_VERSION VERSION_GREATER_EQUAL 11.4) + if(CMAKE_CUDA_COMPILER_ID STREQUAL "NVIDIA") + list(APPEND CMAKE_CUDA_ARCHITECTURES_ALL 87) + endif() endif() -if(CMAKE_CUDA_COMPILER_TOOLKIT_VERSION VERSION_GREATER_EQUAL 11.8 - AND (NOT CMAKE_CUDA_COMPILER_ID STREQUAL "Clang")) - list(APPEND CMAKE_CUDA_ARCHITECTURES_ALL 89 90) - list(APPEND CMAKE_CUDA_ARCHITECTURES_ALL_MAJOR 90) +if(CMAKE_CUDA_COMPILER_TOOLKIT_VERSION VERSION_GREATER_EQUAL 11.8) + if(CMAKE_CUDA_COMPILER_ID STREQUAL "NVIDIA") + list(APPEND CMAKE_CUDA_ARCHITECTURES_ALL 89 90) + list(APPEND CMAKE_CUDA_ARCHITECTURES_ALL_MAJOR 90) + endif() endif() -if(CMAKE_CUDA_COMPILER_TOOLKIT_VERSION VERSION_GREATER_EQUAL 12.0 - AND (NOT CMAKE_CUDA_COMPILER_ID STREQUAL "Clang")) - list(REMOVE_ITEM CMAKE_CUDA_ARCHITECTURES_ALL 35 37) - list(REMOVE_ITEM CMAKE_CUDA_ARCHITECTURES_ALL_MAJOR 35) +if(CMAKE_CUDA_COMPILER_TOOLKIT_VERSION VERSION_GREATER_EQUAL 12.0) + if(CMAKE_CUDA_COMPILER_ID STREQUAL "NVIDIA") + list(REMOVE_ITEM CMAKE_CUDA_ARCHITECTURES_ALL 35 37) + list(REMOVE_ITEM CMAKE_CUDA_ARCHITECTURES_ALL_MAJOR 35) + endif() endif() # only generate jit code for the newest arch for all/all-major -- cgit v0.12 From f125dfcd302dcc65547c8f67390187f92f696e49 Mon Sep 17 00:00:00 2001 From: Brad King Date: Thu, 14 Sep 2023 11:45:25 -0400 Subject: CUDA: Clarify order of logic finding CUDA Toolkit for compiler Finish all the search logic before using any results. --- Modules/CMakeDetermineCUDACompiler.cmake | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Modules/CMakeDetermineCUDACompiler.cmake b/Modules/CMakeDetermineCUDACompiler.cmake index 734b039..1ddb7ba 100644 --- a/Modules/CMakeDetermineCUDACompiler.cmake +++ b/Modules/CMakeDetermineCUDACompiler.cmake @@ -211,9 +211,6 @@ if(NOT CMAKE_CUDA_COMPILER_ID_RUN) endif() unset(_CUDA_NVCC_OUT) - set(CMAKE_CUDA_DEVICE_LINKER "${CMAKE_CUDA_COMPILER_TOOLKIT_ROOT}/bin/nvlink${CMAKE_EXECUTABLE_SUFFIX}") - set(CMAKE_CUDA_FATBINARY "${CMAKE_CUDA_COMPILER_TOOLKIT_ROOT}/bin/fatbinary${CMAKE_EXECUTABLE_SUFFIX}") - # In a non-scattered installation the following are equivalent to CMAKE_CUDA_COMPILER_TOOLKIT_ROOT. # We first check for a non-scattered installation to prefer it over a scattered installation. @@ -252,6 +249,9 @@ if(NOT CMAKE_CUDA_COMPILER_ID_RUN) # Don't leak variables unnecessarily to user code. unset(_CUDA_NVCC_EXECUTABLE) + + set(CMAKE_CUDA_DEVICE_LINKER "${CMAKE_CUDA_COMPILER_TOOLKIT_ROOT}/bin/nvlink${CMAKE_EXECUTABLE_SUFFIX}") + set(CMAKE_CUDA_FATBINARY "${CMAKE_CUDA_COMPILER_TOOLKIT_ROOT}/bin/fatbinary${CMAKE_EXECUTABLE_SUFFIX}") endif() set(CMAKE_CUDA_COMPILER_ID_FLAGS_ALWAYS "-v") -- cgit v0.12 From e1b2a5062f0c45da3cc69055825e9aad4fffbf32 Mon Sep 17 00:00:00 2001 From: Brad King Date: Fri, 15 Sep 2023 14:12:49 -0400 Subject: CUDA: Factor out some NVCC compiler information Prepare to use nvcc for other languages. --- Modules/Compiler/NVIDIA-CUDA.cmake | 94 +----------------------------------- Modules/Compiler/NVIDIA.cmake | 99 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 100 insertions(+), 93 deletions(-) diff --git a/Modules/Compiler/NVIDIA-CUDA.cmake b/Modules/Compiler/NVIDIA-CUDA.cmake index 13d8d8e..93ad182 100644 --- a/Modules/Compiler/NVIDIA-CUDA.cmake +++ b/Modules/Compiler/NVIDIA-CUDA.cmake @@ -1,11 +1,9 @@ include(Compiler/NVIDIA) __compiler_nvidia_cxx_standards(CUDA) +__compiler_nvidia_cuda_flags(CUDA) set(CMAKE_CUDA_COMPILER_HAS_DEVICE_LINK_PHASE True) -set(CMAKE_CUDA_VERBOSE_FLAG "-v") -set(CMAKE_CUDA_VERBOSE_COMPILE_FLAG "-Xcompiler=-v") -set(_CMAKE_COMPILE_AS_CUDA_FLAG "-x cu") set(_CMAKE_CUDA_WHOLE_FLAG "-c") set(_CMAKE_CUDA_RDC_FLAG "-rdc=true") set(_CMAKE_CUDA_PTX_FLAG "-ptx") @@ -15,101 +13,11 @@ if(CMAKE_CUDA_COMPILER_VERSION VERSION_GREATER_EQUAL "11.7.0") set(_CMAKE_CUDA_OPTIX_FLAG "-optix-ir") endif() -if (CMAKE_CUDA_COMPILER_VERSION VERSION_GREATER_EQUAL 10.2.89) - # The -forward-unknown-to-host-compiler flag was only - # added to nvcc in 10.2 so before that we had no good - # way to invoke the CUDA compiler and propagate unknown - # flags such as -pthread to the host compiler - set(_CMAKE_CUDA_EXTRA_FLAGS "-forward-unknown-to-host-compiler") -else() - set(_CMAKE_CUDA_EXTRA_FLAGS "") -endif() - -if(CMAKE_CUDA_COMPILER_VERSION VERSION_GREATER_EQUAL "8.0.0") - set(_CMAKE_CUDA_EXTRA_DEVICE_LINK_FLAGS "-Wno-deprecated-gpu-targets") -else() - set(_CMAKE_CUDA_EXTRA_DEVICE_LINK_FLAGS "") -endif() - -if(CMAKE_CUDA_HOST_COMPILER AND NOT CMAKE_GENERATOR MATCHES "Visual Studio") - string(APPEND _CMAKE_CUDA_EXTRA_FLAGS " -ccbin=") -endif() - -if (CMAKE_CUDA_COMPILER_VERSION VERSION_GREATER_EQUAL 10.2.89) - # Starting in 10.2, nvcc supported treating all warnings as errors - set(CMAKE_CUDA_COMPILE_OPTIONS_WARNING_AS_ERROR "-Werror" "all-warnings") -endif() - -if (CMAKE_CUDA_COMPILER_VERSION VERSION_GREATER_EQUAL 10.2.89) - # The -MD flag was only added to nvcc in 10.2 so - # before that we had to invoke the compiler twice - # to get header dependency information - set(CMAKE_DEPFILE_FLAGS_CUDA "-MD -MT -MF ") -else() - set(CMAKE_CUDA_DEPENDS_EXTRA_COMMANDS " ${_CMAKE_CUDA_EXTRA_FLAGS} ${_CMAKE_COMPILE_AS_CUDA_FLAG} -M -MT -o ") -endif() -set(CMAKE_CUDA_DEPFILE_FORMAT gcc) -if((NOT DEFINED CMAKE_DEPENDS_USE_COMPILER OR CMAKE_DEPENDS_USE_COMPILER) - AND CMAKE_GENERATOR MATCHES "Makefiles|WMake") - set(CMAKE_CUDA_DEPENDS_USE_COMPILER TRUE) -endif() - if(CMAKE_CUDA_COMPILER_VERSION VERSION_GREATER_EQUAL 11.2) - set(_CMAKE_CUDA_IPO_SUPPORTED_BY_CMAKE YES) - set(_CMAKE_CUDA_IPO_MAY_BE_SUPPORTED_BY_COMPILER YES) - set(CMAKE_CUDA_DEVICE_LINK_OPTIONS_IPO " -dlto") endif() -if(NOT "x${CMAKE_CUDA_SIMULATE_ID}" STREQUAL "xMSVC") - set(CMAKE_CUDA_COMPILE_OPTIONS_PIE -Xcompiler=-fPIE) - set(CMAKE_CUDA_COMPILE_OPTIONS_PIC -Xcompiler=-fPIC) - set(CMAKE_CUDA_COMPILE_OPTIONS_VISIBILITY -Xcompiler=-fvisibility=) - # CMAKE_SHARED_LIBRARY_CUDA_FLAGS is sent to the host linker so we - # don't need to forward it through nvcc. - set(CMAKE_SHARED_LIBRARY_CUDA_FLAGS -fPIC) - string(APPEND CMAKE_CUDA_FLAGS_INIT " ") - string(APPEND CMAKE_CUDA_FLAGS_DEBUG_INIT " -g") - string(APPEND CMAKE_CUDA_FLAGS_RELEASE_INIT " -O3 -DNDEBUG") - string(APPEND CMAKE_CUDA_FLAGS_MINSIZEREL_INIT " -O1 -DNDEBUG") - string(APPEND CMAKE_CUDA_FLAGS_RELWITHDEBINFO_INIT " -O2 -g -DNDEBUG") -endif() - -set(CMAKE_SHARED_LIBRARY_CREATE_CUDA_FLAGS -shared) -set(CMAKE_INCLUDE_SYSTEM_FLAG_CUDA "-isystem ") - -if (CMAKE_CUDA_SIMULATE_ID STREQUAL "GNU") - set(CMAKE_CUDA_LINKER_WRAPPER_FLAG "-Wl,") - set(CMAKE_CUDA_LINKER_WRAPPER_FLAG_SEP ",") -elseif(CMAKE_CUDA_SIMULATE_ID STREQUAL "Clang") - set(CMAKE_CUDA_LINKER_WRAPPER_FLAG "-Xlinker" " ") - set(CMAKE_CUDA_LINKER_WRAPPER_FLAG_SEP) -endif() - set(CMAKE_CUDA_DEVICE_COMPILER_WRAPPER_FLAG "-Xcompiler=") set(CMAKE_CUDA_DEVICE_COMPILER_WRAPPER_FLAG_SEP ",") set(CMAKE_CUDA_DEVICE_LINKER_WRAPPER_FLAG "-Xlinker=") set(CMAKE_CUDA_DEVICE_LINKER_WRAPPER_FLAG_SEP ",") - -set(CMAKE_CUDA_RUNTIME_LIBRARY_LINK_OPTIONS_STATIC "cudadevrt;cudart_static") -set(CMAKE_CUDA_RUNTIME_LIBRARY_LINK_OPTIONS_SHARED "cudadevrt;cudart") -set(CMAKE_CUDA_RUNTIME_LIBRARY_LINK_OPTIONS_NONE "") - -if(UNIX AND NOT (CMAKE_SYSTEM_NAME STREQUAL "QNX")) - list(APPEND CMAKE_CUDA_RUNTIME_LIBRARY_LINK_OPTIONS_STATIC "rt" "pthread" "dl") -endif() - -if (CMAKE_CUDA_COMPILER_VERSION VERSION_GREATER_EQUAL "9.0") - set(CMAKE_CUDA_RESPONSE_FILE_DEVICE_LINK_FLAG "--options-file ") - set(CMAKE_CUDA_RESPONSE_FILE_FLAG "--options-file ") -endif() - -if (CMAKE_CUDA_COMPILER_VERSION VERSION_GREATER_EQUAL "11.0") - set(CMAKE_CUDA_USE_RESPONSE_FILE_FOR_INCLUDES 1) - set(CMAKE_CUDA_USE_RESPONSE_FILE_FOR_LIBRARIES 1) - set(CMAKE_CUDA_USE_RESPONSE_FILE_FOR_OBJECTS 1) -else() - set(CMAKE_CUDA_USE_RESPONSE_FILE_FOR_INCLUDES 0) - set(CMAKE_CUDA_USE_RESPONSE_FILE_FOR_LIBRARIES 0) - set(CMAKE_CUDA_USE_RESPONSE_FILE_FOR_OBJECTS 0) -endif() diff --git a/Modules/Compiler/NVIDIA.cmake b/Modules/Compiler/NVIDIA.cmake index 686c03d..a126c57 100644 --- a/Modules/Compiler/NVIDIA.cmake +++ b/Modules/Compiler/NVIDIA.cmake @@ -67,3 +67,102 @@ macro(__compiler_nvidia_cxx_standards lang) __compiler_check_default_language_standard(${lang} 6.0 03) endmacro() + +macro(__compiler_nvidia_cuda_flags lang) + set(CMAKE_${lang}_VERBOSE_FLAG "-v") + set(CMAKE_${lang}_VERBOSE_COMPILE_FLAG "-Xcompiler=-v") + set(_CMAKE_COMPILE_AS_${lang}_FLAG "-x cu") + + if (CMAKE_${lang}_COMPILER_VERSION VERSION_GREATER_EQUAL 10.2.89) + # The -forward-unknown-to-host-compiler flag was only + # added to nvcc in 10.2 so before that we had no good + # way to invoke the NVCC compiler and propagate unknown + # flags such as -pthread to the host compiler + set(_CMAKE_${lang}_EXTRA_FLAGS "-forward-unknown-to-host-compiler") + else() + set(_CMAKE_${lang}_EXTRA_FLAGS "") + endif() + + if(CMAKE_${lang}_COMPILER_VERSION VERSION_GREATER_EQUAL "8.0.0") + set(_CMAKE_${lang}_EXTRA_DEVICE_LINK_FLAGS "-Wno-deprecated-gpu-targets") + else() + set(_CMAKE_${lang}_EXTRA_DEVICE_LINK_FLAGS "") + endif() + + if(CMAKE_${lang}_HOST_COMPILER AND NOT CMAKE_GENERATOR MATCHES "Visual Studio") + string(APPEND _CMAKE_${lang}_EXTRA_FLAGS " -ccbin=") + endif() + + if (CMAKE_${lang}_COMPILER_VERSION VERSION_GREATER_EQUAL 10.2.89) + # Starting in 10.2, nvcc supported treating all warnings as errors + set(CMAKE_${lang}_COMPILE_OPTIONS_WARNING_AS_ERROR "-Werror" "all-warnings") + endif() + + set(CMAKE_${lang}_DEPFILE_FORMAT gcc) + if((NOT DEFINED CMAKE_DEPENDS_USE_COMPILER OR CMAKE_DEPENDS_USE_COMPILER) + AND CMAKE_GENERATOR MATCHES "Makefiles|WMake") + set(CMAKE_${lang}_DEPENDS_USE_COMPILER TRUE) + endif() + + if (CMAKE_${lang}_COMPILER_VERSION VERSION_GREATER_EQUAL 10.2.89) + # The -MD flag was only added to nvcc in 10.2 so + # before that we had to invoke the compiler twice + # to get header dependency information + set(CMAKE_DEPFILE_FLAGS_${lang} "-MD -MT -MF ") + else() + set(CMAKE_${lang}_DEPENDS_EXTRA_COMMANDS " ${_CMAKE_${lang}_EXTRA_FLAGS} ${_CMAKE_COMPILE_AS_${lang}_FLAG} -M -MT -o ") + endif() + + if(CMAKE_${lang}_COMPILER_VERSION VERSION_GREATER_EQUAL 11.2) + set(_CMAKE_${lang}_IPO_SUPPORTED_BY_CMAKE YES) + set(_CMAKE_${lang}_IPO_MAY_BE_SUPPORTED_BY_COMPILER YES) + endif() + + if(NOT "x${CMAKE_${lang}_SIMULATE_ID}" STREQUAL "xMSVC") + set(CMAKE_${lang}_COMPILE_OPTIONS_PIE -Xcompiler=-fPIE) + set(CMAKE_${lang}_COMPILE_OPTIONS_PIC -Xcompiler=-fPIC) + set(CMAKE_${lang}_COMPILE_OPTIONS_VISIBILITY -Xcompiler=-fvisibility=) + # CMAKE_SHARED_LIBRARY_${lang}_FLAGS is sent to the host linker so we + # don't need to forward it through nvcc. + set(CMAKE_SHARED_LIBRARY_${lang}_FLAGS -fPIC) + string(APPEND CMAKE_${lang}_FLAGS_INIT " ") + string(APPEND CMAKE_${lang}_FLAGS_DEBUG_INIT " -g") + string(APPEND CMAKE_${lang}_FLAGS_RELEASE_INIT " -O3 -DNDEBUG") + string(APPEND CMAKE_${lang}_FLAGS_MINSIZEREL_INIT " -O1 -DNDEBUG") + string(APPEND CMAKE_${lang}_FLAGS_RELWITHDEBINFO_INIT " -O2 -g -DNDEBUG") + endif() + + set(CMAKE_SHARED_LIBRARY_CREATE_${lang}_FLAGS -shared) + set(CMAKE_INCLUDE_SYSTEM_FLAG_${lang} "-isystem ") + + if (CMAKE_${lang}_SIMULATE_ID STREQUAL "GNU") + set(CMAKE_${lang}_LINKER_WRAPPER_FLAG "-Wl,") + set(CMAKE_${lang}_LINKER_WRAPPER_FLAG_SEP ",") + elseif(CMAKE_${lang}_SIMULATE_ID STREQUAL "Clang") + set(CMAKE_${lang}_LINKER_WRAPPER_FLAG "-Xlinker" " ") + set(CMAKE_${lang}_LINKER_WRAPPER_FLAG_SEP) + endif() + + set(CMAKE_${lang}_RUNTIME_LIBRARY_LINK_OPTIONS_STATIC "cudadevrt;cudart_static") + set(CMAKE_${lang}_RUNTIME_LIBRARY_LINK_OPTIONS_SHARED "cudadevrt;cudart") + set(CMAKE_${lang}_RUNTIME_LIBRARY_LINK_OPTIONS_NONE "") + + if(UNIX AND NOT (CMAKE_SYSTEM_NAME STREQUAL "QNX")) + list(APPEND CMAKE_${lang}_RUNTIME_LIBRARY_LINK_OPTIONS_STATIC "rt" "pthread" "dl") + endif() + + if (CMAKE_${lang}_COMPILER_VERSION VERSION_GREATER_EQUAL "9.0") + set(CMAKE_${lang}_RESPONSE_FILE_DEVICE_LINK_FLAG "--options-file ") + set(CMAKE_${lang}_RESPONSE_FILE_FLAG "--options-file ") + endif() + + if (CMAKE_${lang}_COMPILER_VERSION VERSION_GREATER_EQUAL "11.0") + set(CMAKE_${lang}_USE_RESPONSE_FILE_FOR_INCLUDES 1) + set(CMAKE_${lang}_USE_RESPONSE_FILE_FOR_LIBRARIES 1) + set(CMAKE_${lang}_USE_RESPONSE_FILE_FOR_OBJECTS 1) + else() + set(CMAKE_${lang}_USE_RESPONSE_FILE_FOR_INCLUDES 0) + set(CMAKE_${lang}_USE_RESPONSE_FILE_FOR_LIBRARIES 0) + set(CMAKE_${lang}_USE_RESPONSE_FILE_FOR_OBJECTS 0) + endif() +endmacro() -- cgit v0.12 From deff0e638d2a6308354c0bdbc2c262d525218e64 Mon Sep 17 00:00:00 2001 From: Brad King Date: Fri, 15 Sep 2023 14:10:51 -0400 Subject: CUDA: Factor out helper to parse NVCC implicit compiler and linker flags Prepare to use it for other languages. --- Modules/CMakeDetermineCUDACompiler.cmake | 163 ++------------------- Modules/CMakeTestCUDACompiler.cmake | 14 +- Modules/Internal/CMakeNVCCFilterImplicitInfo.cmake | 16 ++ Modules/Internal/CMakeNVCCParseImplicitInfo.cmake | 149 +++++++++++++++++++ 4 files changed, 181 insertions(+), 161 deletions(-) create mode 100644 Modules/Internal/CMakeNVCCFilterImplicitInfo.cmake create mode 100644 Modules/Internal/CMakeNVCCParseImplicitInfo.cmake diff --git a/Modules/CMakeDetermineCUDACompiler.cmake b/Modules/CMakeDetermineCUDACompiler.cmake index 1ddb7ba..a495a28 100644 --- a/Modules/CMakeDetermineCUDACompiler.cmake +++ b/Modules/CMakeDetermineCUDACompiler.cmake @@ -423,121 +423,20 @@ elseif(CMAKE_CUDA_COMPILER_ID STREQUAL "Clang") unset(_CUDA_TARGET_DIR) unset(_CUDA_TARGET_NAME) elseif(CMAKE_CUDA_COMPILER_ID STREQUAL "NVIDIA") - set(_nvcc_log "") - string(REPLACE "\r" "" _nvcc_output_orig "${CMAKE_CUDA_COMPILER_PRODUCED_OUTPUT}") - if(_nvcc_output_orig MATCHES "#\\\$ +PATH= *([^\n]*)\n") - set(_nvcc_path "${CMAKE_MATCH_1}") - string(APPEND _nvcc_log " found 'PATH=' string: [${_nvcc_path}]\n") - string(REPLACE ":" ";" _nvcc_path "${_nvcc_path}") - else() - set(_nvcc_path "") - string(REPLACE "\n" "\n " _nvcc_output_log "\n${_nvcc_output_orig}") - string(APPEND _nvcc_log " no 'PATH=' string found in nvcc output:${_nvcc_output_log}\n") - endif() - if(_nvcc_output_orig MATCHES "#\\\$ +LIBRARIES= *([^\n]*)\n") - set(_nvcc_libraries "${CMAKE_MATCH_1}") - string(APPEND _nvcc_log " found 'LIBRARIES=' string: [${_nvcc_libraries}]\n") - else() - set(_nvcc_libraries "") - string(REPLACE "\n" "\n " _nvcc_output_log "\n${_nvcc_output_orig}") - string(APPEND _nvcc_log " no 'LIBRARIES=' string found in nvcc output:${_nvcc_output_log}\n") - endif() + include(Internal/CMakeNVCCParseImplicitInfo) + # Parse CMAKE_CUDA_COMPILER_PRODUCED_OUTPUT to get: + # - CMAKE_CUDA_ARCHITECTURES_DEFAULT + # - CMAKE_CUDA_HOST_IMPLICIT_LINK_DIRECTORIES + # - CMAKE_CUDA_HOST_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES + # - CMAKE_CUDA_HOST_IMPLICIT_LINK_LIBRARIES + # - CMAKE_CUDA_HOST_LINK_LAUNCHER + # - CMAKE_CUDA_RUNTIME_LIBRARY_DEFAULT + # - CMAKE_CUDA_TOOLKIT_INCLUDE_DIRECTORIES + # Match arguments with cmake_nvcc_filter_implicit_info call in CMakeTestCUDACompiler. + cmake_nvcc_parse_implicit_info(CUDA CMAKE_CUDA_) - set(_nvcc_link_line "") - if(_nvcc_libraries) - # Remove variable assignments. - string(REGEX REPLACE "#\\\$ *[^= ]+=[^\n]*\n" "" _nvcc_output "${_nvcc_output_orig}") - # Encode [] characters that break list expansion. - string(REPLACE "[" "{==={" _nvcc_output "${_nvcc_output}") - string(REPLACE "]" "}===}" _nvcc_output "${_nvcc_output}") - # Split lines. - string(REGEX REPLACE "\n+(#\\\$ )?" ";" _nvcc_output "${_nvcc_output}") - foreach(line IN LISTS _nvcc_output) - set(_nvcc_output_line "${line}") - string(REPLACE "{==={" "[" _nvcc_output_line "${_nvcc_output_line}") - string(REPLACE "}===}" "]" _nvcc_output_line "${_nvcc_output_line}") - string(APPEND _nvcc_log " considering line: [${_nvcc_output_line}]\n") - if("${_nvcc_output_line}" MATCHES "^ *nvlink") - string(APPEND _nvcc_log " ignoring nvlink line\n") - elseif(_nvcc_libraries) - if("${_nvcc_output_line}" MATCHES "(@\"?((tmp/)?a\\.exe\\.res)\"?)") - set(_nvcc_link_res_arg "${CMAKE_MATCH_1}") - set(_nvcc_link_res_file "${CMAKE_MATCH_2}") - set(_nvcc_link_res "${CMAKE_PLATFORM_INFO_DIR}/CompilerIdCUDA/${_nvcc_link_res_file}") - if(EXISTS "${_nvcc_link_res}") - file(READ "${_nvcc_link_res}" _nvcc_link_res_content) - string(REPLACE "${_nvcc_link_res_arg}" "${_nvcc_link_res_content}" _nvcc_output_line "${_nvcc_output_line}") - endif() - endif() - string(FIND "${_nvcc_output_line}" "${_nvcc_libraries}" _nvcc_libraries_pos) - if(NOT _nvcc_libraries_pos EQUAL -1) - set(_nvcc_link_line "${_nvcc_output_line}") - string(APPEND _nvcc_log " extracted link line: [${_nvcc_link_line}]\n") - endif() - endif() - endforeach() - endif() - - if(_nvcc_link_line) - if("x${CMAKE_CUDA_SIMULATE_ID}" STREQUAL "xMSVC") - set(CMAKE_CUDA_HOST_LINK_LAUNCHER "${CMAKE_LINKER}") - else() - #extract the compiler that is being used for linking - separate_arguments(_nvcc_link_line_args UNIX_COMMAND "${_nvcc_link_line}") - list(GET _nvcc_link_line_args 0 _nvcc_host_link_launcher) - if(IS_ABSOLUTE "${_nvcc_host_link_launcher}") - string(APPEND _nvcc_log " extracted link launcher absolute path: [${_nvcc_host_link_launcher}]\n") - set(CMAKE_CUDA_HOST_LINK_LAUNCHER "${_nvcc_host_link_launcher}") - else() - string(APPEND _nvcc_log " extracted link launcher name: [${_nvcc_host_link_launcher}]\n") - find_program(_nvcc_find_host_link_launcher - NAMES ${_nvcc_host_link_launcher} - PATHS ${_nvcc_path} NO_DEFAULT_PATH) - find_program(_nvcc_find_host_link_launcher - NAMES ${_nvcc_host_link_launcher}) - if(_nvcc_find_host_link_launcher) - string(APPEND _nvcc_log " found link launcher absolute path: [${_nvcc_find_host_link_launcher}]\n") - set(CMAKE_CUDA_HOST_LINK_LAUNCHER "${_nvcc_find_host_link_launcher}") - else() - string(APPEND _nvcc_log " could not find link launcher absolute path\n") - set(CMAKE_CUDA_HOST_LINK_LAUNCHER "${_nvcc_host_link_launcher}") - endif() - unset(_nvcc_find_host_link_launcher CACHE) - endif() - endif() - - #prefix the line with cuda-fake-ld so that implicit link info believes it is - #a link line - set(_nvcc_link_line "cuda-fake-ld ${_nvcc_link_line}") - CMAKE_PARSE_IMPLICIT_LINK_INFO("${_nvcc_link_line}" - CMAKE_CUDA_HOST_IMPLICIT_LINK_LIBRARIES - CMAKE_CUDA_HOST_IMPLICIT_LINK_DIRECTORIES - CMAKE_CUDA_HOST_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES - log - "${CMAKE_CUDA_IMPLICIT_OBJECT_REGEX}" - LANGUAGE CUDA) - - # Detect CMAKE_CUDA_RUNTIME_LIBRARY_DEFAULT from the compiler by looking at which - # cudart library exists in the implicit link libraries passed to the host linker. - # This is required when a project sets the cuda runtime library as part of the - # initial flags. - if(";${CMAKE_CUDA_HOST_IMPLICIT_LINK_LIBRARIES};" MATCHES [[;cudart_static(\.lib)?;]]) - set(CMAKE_CUDA_RUNTIME_LIBRARY_DEFAULT "STATIC") - elseif(";${CMAKE_CUDA_HOST_IMPLICIT_LINK_LIBRARIES};" MATCHES [[;cudart(\.lib)?;]]) - set(CMAKE_CUDA_RUNTIME_LIBRARY_DEFAULT "SHARED") - else() - set(CMAKE_CUDA_RUNTIME_LIBRARY_DEFAULT "NONE") - endif() - set(_SET_CMAKE_CUDA_RUNTIME_LIBRARY_DEFAULT - "set(CMAKE_CUDA_RUNTIME_LIBRARY_DEFAULT \"${CMAKE_CUDA_RUNTIME_LIBRARY_DEFAULT}\")") - - message(CONFIGURE_LOG - "Parsed CUDA nvcc implicit link information:\n${_nvcc_log}\n${log}\n\n") - else() - message(CONFIGURE_LOG - "Failed to parse CUDA nvcc implicit link information:\n${_nvcc_log}\n\n") - message(FATAL_ERROR "Failed to extract nvcc implicit link line.") - endif() + set(_SET_CMAKE_CUDA_RUNTIME_LIBRARY_DEFAULT + "set(CMAKE_CUDA_RUNTIME_LIBRARY_DEFAULT \"${CMAKE_CUDA_RUNTIME_LIBRARY_DEFAULT}\")") endif() # CMAKE_CUDA_HOST_IMPLICIT_LINK_LIBRARIES is detected above as the list of @@ -566,42 +465,6 @@ else() set(_SET_CMAKE_CUDA_COMPILER_SYSROOT "") endif() -# Determine CMAKE_CUDA_TOOLKIT_INCLUDE_DIRECTORIES -if(CMAKE_CUDA_COMPILER_ID STREQUAL "NVIDIA") - set(CMAKE_CUDA_TOOLKIT_INCLUDE_DIRECTORIES) - string(REPLACE "\r" "" _nvcc_output_orig "${CMAKE_CUDA_COMPILER_PRODUCED_OUTPUT}") - if(_nvcc_output_orig MATCHES "#\\\$ +INCLUDES= *([^\n]*)\n") - set(_nvcc_includes "${CMAKE_MATCH_1}") - string(APPEND _nvcc_log " found 'INCLUDES=' string: [${_nvcc_includes}]\n") - else() - set(_nvcc_includes "") - string(REPLACE "\n" "\n " _nvcc_output_log "\n${_nvcc_output_orig}") - string(APPEND _nvcc_log " no 'INCLUDES=' string found in nvcc output:${_nvcc_output_log}\n") - endif() - if(_nvcc_includes) - # across all operating system each include directory is prefixed with -I - separate_arguments(_nvcc_output NATIVE_COMMAND "${_nvcc_includes}") - foreach(line IN LISTS _nvcc_output) - string(REGEX REPLACE "^-I" "" line "${line}") - get_filename_component(line "${line}" ABSOLUTE) - list(APPEND CMAKE_CUDA_TOOLKIT_INCLUDE_DIRECTORIES "${line}") - endforeach() - - message(CONFIGURE_LOG - "Parsed CUDA nvcc include information:\n${_nvcc_log}\n${log}\n\n") - else() - message(CONFIGURE_LOG - "Failed to detect CUDA nvcc include information:\n${_nvcc_log}\n\n") - endif() - - string(REGEX MATCHALL "-arch compute_([0-9]+)" _nvcc_target_cpus "${CMAKE_CUDA_COMPILER_PRODUCED_OUTPUT}") - foreach(_nvcc_target_cpu ${_nvcc_target_cpus}) - if(_nvcc_target_cpu MATCHES "-arch compute_([0-9]+)") - list(APPEND CMAKE_CUDA_ARCHITECTURES_DEFAULT "${CMAKE_MATCH_1}") - endif() - endforeach() -endif() - # If the user did not set CMAKE_CUDA_ARCHITECTURES, use the compiler's default. if("${CMAKE_CUDA_ARCHITECTURES}" STREQUAL "") cmake_policy(GET CMP0104 _CUDA_CMP0104) diff --git a/Modules/CMakeTestCUDACompiler.cmake b/Modules/CMakeTestCUDACompiler.cmake index 5779e4b..3fbf230 100644 --- a/Modules/CMakeTestCUDACompiler.cmake +++ b/Modules/CMakeTestCUDACompiler.cmake @@ -119,17 +119,9 @@ endif() list(REMOVE_ITEM CMAKE_CUDA_IMPLICIT_LINK_LIBRARIES ${CMAKE_CUDA_IMPLICIT_LINK_LIBRARIES_EXCLUDE}) if(CMAKE_CUDA_COMPILER_ID STREQUAL "NVIDIA") - # Remove the CUDA Toolkit include directories from the set of - # implicit system include directories. - # This resolves the issue that NVCC doesn't specify these - # includes as SYSTEM includes when compiling device code, and sometimes - # they contain headers that generate warnings, so let users mark them - # as SYSTEM explicitly - if(CMAKE_CUDA_TOOLKIT_INCLUDE_DIRECTORIES) - list(REMOVE_ITEM CMAKE_CUDA_IMPLICIT_INCLUDE_DIRECTORIES - ${CMAKE_CUDA_TOOLKIT_INCLUDE_DIRECTORIES} - ) - endif() + include(Internal/CMakeNVCCFilterImplicitInfo) + # Match arguments with cmake_nvcc_parse_implicit_info call in CMakeDetermineCUDACompiler. + cmake_nvcc_filter_implicit_info(CUDA CMAKE_CUDA_) endif() # Re-configure to save learned information. diff --git a/Modules/Internal/CMakeNVCCFilterImplicitInfo.cmake b/Modules/Internal/CMakeNVCCFilterImplicitInfo.cmake new file mode 100644 index 0000000..dee7580 --- /dev/null +++ b/Modules/Internal/CMakeNVCCFilterImplicitInfo.cmake @@ -0,0 +1,16 @@ +# Distributed under the OSI-approved BSD 3-Clause License. See accompanying +# file Copyright.txt or https://cmake.org/licensing for details. + +macro(cmake_nvcc_filter_implicit_info lang lang_var_) + # Remove the CUDA Toolkit include directories from the set of + # implicit system include directories. + # This resolves the issue that NVCC doesn't specify these + # includes as SYSTEM includes when compiling device code, and sometimes + # they contain headers that generate warnings, so let users mark them + # as SYSTEM explicitly + if(${lang_var_}TOOLKIT_INCLUDE_DIRECTORIES) + list(REMOVE_ITEM CMAKE_${lang}_IMPLICIT_INCLUDE_DIRECTORIES + ${${lang_var_}TOOLKIT_INCLUDE_DIRECTORIES} + ) + endif() +endmacro() diff --git a/Modules/Internal/CMakeNVCCParseImplicitInfo.cmake b/Modules/Internal/CMakeNVCCParseImplicitInfo.cmake new file mode 100644 index 0000000..32ff28a --- /dev/null +++ b/Modules/Internal/CMakeNVCCParseImplicitInfo.cmake @@ -0,0 +1,149 @@ +# Distributed under the OSI-approved BSD 3-Clause License. See accompanying +# file Copyright.txt or https://cmake.org/licensing for details. + +macro(cmake_nvcc_parse_implicit_info lang lang_var_) + set(_nvcc_log "") + string(REPLACE "\r" "" _nvcc_output_orig "${CMAKE_${lang}_COMPILER_PRODUCED_OUTPUT}") + if(_nvcc_output_orig MATCHES "#\\\$ +PATH= *([^\n]*)\n") + set(_nvcc_path "${CMAKE_MATCH_1}") + string(APPEND _nvcc_log " found 'PATH=' string: [${_nvcc_path}]\n") + string(REPLACE ":" ";" _nvcc_path "${_nvcc_path}") + else() + set(_nvcc_path "") + string(REPLACE "\n" "\n " _nvcc_output_log "\n${_nvcc_output_orig}") + string(APPEND _nvcc_log " no 'PATH=' string found in nvcc output:${_nvcc_output_log}\n") + endif() + if(_nvcc_output_orig MATCHES "#\\\$ +LIBRARIES= *([^\n]*)\n") + set(_nvcc_libraries "${CMAKE_MATCH_1}") + string(APPEND _nvcc_log " found 'LIBRARIES=' string: [${_nvcc_libraries}]\n") + else() + set(_nvcc_libraries "") + string(REPLACE "\n" "\n " _nvcc_output_log "\n${_nvcc_output_orig}") + string(APPEND _nvcc_log " no 'LIBRARIES=' string found in nvcc output:${_nvcc_output_log}\n") + endif() + if(_nvcc_output_orig MATCHES "#\\\$ +INCLUDES= *([^\n]*)\n") + set(_nvcc_includes "${CMAKE_MATCH_1}") + string(APPEND _nvcc_log " found 'INCLUDES=' string: [${_nvcc_includes}]\n") + else() + set(_nvcc_includes "") + string(REPLACE "\n" "\n " _nvcc_output_log "\n${_nvcc_output_orig}") + string(APPEND _nvcc_log " no 'INCLUDES=' string found in nvcc output:${_nvcc_output_log}\n") + endif() + string(REGEX MATCHALL "-arch compute_([0-9]+)" _nvcc_target_cpus "${_nvcc_output_orig}") + foreach(_nvcc_target_cpu ${_nvcc_target_cpus}) + if(_nvcc_target_cpu MATCHES "-arch compute_([0-9]+)") + list(APPEND CMAKE_${lang}_ARCHITECTURES_DEFAULT "${CMAKE_MATCH_1}") + endif() + endforeach() + + set(_nvcc_link_line "") + if(_nvcc_libraries) + # Remove variable assignments. + string(REGEX REPLACE "#\\\$ *[^= ]+=[^\n]*\n" "" _nvcc_output "${_nvcc_output_orig}") + # Encode [] characters that break list expansion. + string(REPLACE "[" "{==={" _nvcc_output "${_nvcc_output}") + string(REPLACE "]" "}===}" _nvcc_output "${_nvcc_output}") + # Split lines. + string(REGEX REPLACE "\n+(#\\\$ )?" ";" _nvcc_output "${_nvcc_output}") + foreach(line IN LISTS _nvcc_output) + set(_nvcc_output_line "${line}") + string(REPLACE "{==={" "[" _nvcc_output_line "${_nvcc_output_line}") + string(REPLACE "}===}" "]" _nvcc_output_line "${_nvcc_output_line}") + string(APPEND _nvcc_log " considering line: [${_nvcc_output_line}]\n") + if("${_nvcc_output_line}" MATCHES "^ *nvlink") + string(APPEND _nvcc_log " ignoring nvlink line\n") + elseif(_nvcc_libraries) + if("${_nvcc_output_line}" MATCHES "(@\"?((tmp/)?a\\.exe\\.res)\"?)") + set(_nvcc_link_res_arg "${CMAKE_MATCH_1}") + set(_nvcc_link_res_file "${CMAKE_MATCH_2}") + set(_nvcc_link_res "${CMAKE_PLATFORM_INFO_DIR}/CompilerId${lang}/${_nvcc_link_res_file}") + if(EXISTS "${_nvcc_link_res}") + file(READ "${_nvcc_link_res}" _nvcc_link_res_content) + string(REPLACE "${_nvcc_link_res_arg}" "${_nvcc_link_res_content}" _nvcc_output_line "${_nvcc_output_line}") + endif() + endif() + string(FIND "${_nvcc_output_line}" "${_nvcc_libraries}" _nvcc_libraries_pos) + if(NOT _nvcc_libraries_pos EQUAL -1) + set(_nvcc_link_line "${_nvcc_output_line}") + string(APPEND _nvcc_log " extracted link line: [${_nvcc_link_line}]\n") + endif() + endif() + endforeach() + endif() + + if(_nvcc_link_line) + if("x${CMAKE_${lang}_SIMULATE_ID}" STREQUAL "xMSVC") + set(CMAKE_${lang}_HOST_LINK_LAUNCHER "${CMAKE_LINKER}") + else() + #extract the compiler that is being used for linking + separate_arguments(_nvcc_link_line_args UNIX_COMMAND "${_nvcc_link_line}") + list(GET _nvcc_link_line_args 0 _nvcc_host_link_launcher) + if(IS_ABSOLUTE "${_nvcc_host_link_launcher}") + string(APPEND _nvcc_log " extracted link launcher absolute path: [${_nvcc_host_link_launcher}]\n") + set(CMAKE_${lang}_HOST_LINK_LAUNCHER "${_nvcc_host_link_launcher}") + else() + string(APPEND _nvcc_log " extracted link launcher name: [${_nvcc_host_link_launcher}]\n") + find_program(_nvcc_find_host_link_launcher + NAMES ${_nvcc_host_link_launcher} + PATHS ${_nvcc_path} NO_DEFAULT_PATH) + find_program(_nvcc_find_host_link_launcher + NAMES ${_nvcc_host_link_launcher}) + if(_nvcc_find_host_link_launcher) + string(APPEND _nvcc_log " found link launcher absolute path: [${_nvcc_find_host_link_launcher}]\n") + set(CMAKE_${lang}_HOST_LINK_LAUNCHER "${_nvcc_find_host_link_launcher}") + else() + string(APPEND _nvcc_log " could not find link launcher absolute path\n") + set(CMAKE_${lang}_HOST_LINK_LAUNCHER "${_nvcc_host_link_launcher}") + endif() + unset(_nvcc_find_host_link_launcher CACHE) + endif() + endif() + + #prefix the line with cuda-fake-ld so that implicit link info believes it is + #a link line + set(_nvcc_link_line "cuda-fake-ld ${_nvcc_link_line}") + CMAKE_PARSE_IMPLICIT_LINK_INFO("${_nvcc_link_line}" + CMAKE_${lang}_HOST_IMPLICIT_LINK_LIBRARIES + CMAKE_${lang}_HOST_IMPLICIT_LINK_DIRECTORIES + CMAKE_${lang}_HOST_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES + log + "${CMAKE_${lang}_IMPLICIT_OBJECT_REGEX}" + LANGUAGE ${lang}) + + # Detect CMAKE_${lang}_RUNTIME_LIBRARY_DEFAULT from the compiler by looking at which + # cudart library exists in the implicit link libraries passed to the host linker. + # This is required when a project sets the cuda runtime library as part of the + # initial flags. + if(";${CMAKE_${lang}_HOST_IMPLICIT_LINK_LIBRARIES};" MATCHES [[;cudart_static(\.lib)?;]]) + set(CMAKE_${lang}_RUNTIME_LIBRARY_DEFAULT "STATIC") + elseif(";${CMAKE_${lang}_HOST_IMPLICIT_LINK_LIBRARIES};" MATCHES [[;cudart(\.lib)?;]]) + set(CMAKE_${lang}_RUNTIME_LIBRARY_DEFAULT "SHARED") + else() + set(CMAKE_${lang}_RUNTIME_LIBRARY_DEFAULT "NONE") + endif() + + message(CONFIGURE_LOG + "Parsed ${lang} nvcc implicit link information:\n${_nvcc_log}\n${log}\n\n") + else() + message(CONFIGURE_LOG + "Failed to parse ${lang} nvcc implicit link information:\n${_nvcc_log}\n\n") + message(FATAL_ERROR "Failed to extract nvcc implicit link line.") + endif() + + set(${lang_var_}TOOLKIT_INCLUDE_DIRECTORIES) + if(_nvcc_includes) + # across all operating system each include directory is prefixed with -I + separate_arguments(_nvcc_output NATIVE_COMMAND "${_nvcc_includes}") + foreach(line IN LISTS _nvcc_output) + string(REGEX REPLACE "^-I" "" line "${line}") + get_filename_component(line "${line}" ABSOLUTE) + list(APPEND ${lang_var_}TOOLKIT_INCLUDE_DIRECTORIES "${line}") + endforeach() + + message(CONFIGURE_LOG + "Parsed CUDA nvcc include information:\n${_nvcc_log}\n${log}\n\n") + else() + message(CONFIGURE_LOG + "Failed to detect CUDA nvcc include information:\n${_nvcc_log}\n\n") + endif() +endmacro() -- cgit v0.12 From a6841a967bc933101a351597b5b09363287ddfa6 Mon Sep 17 00:00:00 2001 From: Brad King Date: Thu, 21 Sep 2023 14:18:52 -0400 Subject: CUDA: Factor out helper to filter implicit link libraries Prepare to use it for other languages. --- Modules/CMakeDetermineCUDACompiler.cmake | 20 +++----------------- Modules/CMakeTestCUDACompiler.cmake | 4 ++-- Modules/Internal/CMakeCUDAFilterImplicitLibs.cmake | 20 ++++++++++++++++++++ 3 files changed, 25 insertions(+), 19 deletions(-) create mode 100644 Modules/Internal/CMakeCUDAFilterImplicitLibs.cmake diff --git a/Modules/CMakeDetermineCUDACompiler.cmake b/Modules/CMakeDetermineCUDACompiler.cmake index a495a28..657550a 100644 --- a/Modules/CMakeDetermineCUDACompiler.cmake +++ b/Modules/CMakeDetermineCUDACompiler.cmake @@ -439,23 +439,9 @@ elseif(CMAKE_CUDA_COMPILER_ID STREQUAL "NVIDIA") "set(CMAKE_CUDA_RUNTIME_LIBRARY_DEFAULT \"${CMAKE_CUDA_RUNTIME_LIBRARY_DEFAULT}\")") endif() -# CMAKE_CUDA_HOST_IMPLICIT_LINK_LIBRARIES is detected above as the list of -# libraries that the CUDA compiler implicitly passes to the host linker. -# CMake invokes the host linker directly and so needs to pass these libraries. -# We filter out those that should not be passed unconditionally both here -# and from CMAKE_CUDA_IMPLICIT_LINK_LIBRARIES in CMakeTestCUDACompiler. -set(CMAKE_CUDA_IMPLICIT_LINK_LIBRARIES_EXCLUDE - # The CUDA runtime libraries are controlled by CMAKE_CUDA_RUNTIME_LIBRARY. - cudart cudart.lib - cudart_static cudart_static.lib - cudadevrt cudadevrt.lib - - # Dependencies of the CUDA static runtime library on Linux hosts. - rt - pthread - dl - ) -list(REMOVE_ITEM CMAKE_CUDA_HOST_IMPLICIT_LINK_LIBRARIES ${CMAKE_CUDA_IMPLICIT_LINK_LIBRARIES_EXCLUDE}) +include(Internal/CMakeCUDAFilterImplicitLibs) +# Filter out implicit link libraries that should not be passed unconditionally. +cmake_cuda_filter_implicit_libs(CMAKE_CUDA_HOST_IMPLICIT_LINK_LIBRARIES) if(CMAKE_CUDA_COMPILER_SYSROOT) string(CONCAT _SET_CMAKE_CUDA_COMPILER_SYSROOT diff --git a/Modules/CMakeTestCUDACompiler.cmake b/Modules/CMakeTestCUDACompiler.cmake index 3fbf230..79ee20f 100644 --- a/Modules/CMakeTestCUDACompiler.cmake +++ b/Modules/CMakeTestCUDACompiler.cmake @@ -114,9 +114,9 @@ if("x${CMAKE_CUDA_SIMULATE_ID}" STREQUAL "xMSVC") set(CMAKE_CUDA_IMPLICIT_LINK_DIRECTORIES "${CMAKE_CUDA_HOST_IMPLICIT_LINK_DIRECTORIES}") endif() +include(Internal/CMakeCUDAFilterImplicitLibs) # Filter out implicit link libraries that should not be passed unconditionally. -# See CMAKE_CUDA_IMPLICIT_LINK_LIBRARIES_EXCLUDE in CMakeDetermineCUDACompiler. -list(REMOVE_ITEM CMAKE_CUDA_IMPLICIT_LINK_LIBRARIES ${CMAKE_CUDA_IMPLICIT_LINK_LIBRARIES_EXCLUDE}) +cmake_cuda_filter_implicit_libs(CMAKE_CUDA_IMPLICIT_LINK_LIBRARIES) if(CMAKE_CUDA_COMPILER_ID STREQUAL "NVIDIA") include(Internal/CMakeNVCCFilterImplicitInfo) diff --git a/Modules/Internal/CMakeCUDAFilterImplicitLibs.cmake b/Modules/Internal/CMakeCUDAFilterImplicitLibs.cmake new file mode 100644 index 0000000..60287af --- /dev/null +++ b/Modules/Internal/CMakeCUDAFilterImplicitLibs.cmake @@ -0,0 +1,20 @@ +# Distributed under the OSI-approved BSD 3-Clause License. See accompanying +# file Copyright.txt or https://cmake.org/licensing for details. + +# In CMakeDetermineCUDACompiler and CMakeTestCUDACompiler we detect +# libraries that the CUDA compiler implicitly passes to the host linker. +# CMake invokes the host linker directly and so needs to pass these libraries. +# Filter out implicit link libraries that should not be passed unconditionally. +macro(cmake_cuda_filter_implicit_libs _var_CMAKE_CUDA_IMPLICIT_LINK_LIBRARIES) + list(REMOVE_ITEM "${_var_CMAKE_CUDA_IMPLICIT_LINK_LIBRARIES}" + # The CUDA runtime libraries are controlled by CMAKE_CUDA_RUNTIME_LIBRARY. + cudart cudart.lib + cudart_static cudart_static.lib + cudadevrt cudadevrt.lib + + # Dependencies of the CUDA static runtime library on Linux hosts. + rt + pthread + dl + ) +endmacro() -- cgit v0.12 From c16f1e2b938918c4c8c917c713d09eb6af36ce3b Mon Sep 17 00:00:00 2001 From: Brad King Date: Thu, 14 Sep 2023 11:49:20 -0400 Subject: CUDA: Factor out helper to find CUDA Toolkit for compiler Prepare to use it for other languages. --- Modules/CMakeDetermineCUDACompiler.cmake | 179 ++-------------------------- Modules/Internal/CMakeCUDAFindToolkit.cmake | 173 +++++++++++++++++++++++++++ 2 files changed, 181 insertions(+), 171 deletions(-) create mode 100644 Modules/Internal/CMakeCUDAFindToolkit.cmake diff --git a/Modules/CMakeDetermineCUDACompiler.cmake b/Modules/CMakeDetermineCUDACompiler.cmake index 657550a..e698b79 100644 --- a/Modules/CMakeDetermineCUDACompiler.cmake +++ b/Modules/CMakeDetermineCUDACompiler.cmake @@ -78,177 +78,14 @@ if(NOT CMAKE_CUDA_COMPILER_ID_RUN) message(FATAL_ERROR "Clang with CUDA is not yet supported on Windows. See CMake issue #20776.") endif() - # Find the CUDA toolkit. We store the CMAKE_CUDA_COMPILER_TOOLKIT_ROOT, CMAKE_CUDA_COMPILER_TOOLKIT_VERSION and - # CMAKE_CUDA_COMPILER_LIBRARY_ROOT in CMakeCUDACompiler.cmake so FindCUDAToolkit can avoid searching on future - # runs and the toolkit is the same. - # This is very similar to FindCUDAToolkit, but somewhat simplified since we can issue fatal errors - # if we fail and we don't need to account for searching the libraries. - - # For NVCC we can easily deduce the SDK binary directory from the compiler path. - if(CMAKE_CUDA_COMPILER_ID STREQUAL "NVIDIA") - set(_CUDA_NVCC_EXECUTABLE "${CMAKE_CUDA_COMPILER}") - else() - # Search using CUDAToolkit_ROOT and then CUDA_PATH for equivalence with FindCUDAToolkit. - # In FindCUDAToolkit CUDAToolkit_ROOT is searched automatically due to being in a find_package(). - # First we search candidate non-default paths to give them priority. - find_program(_CUDA_NVCC_EXECUTABLE - NAMES nvcc nvcc.exe - PATHS ${CUDAToolkit_ROOT} - ENV CUDAToolkit_ROOT - ENV CUDA_PATH - PATH_SUFFIXES bin - NO_DEFAULT_PATH - NO_CACHE - ) - - # If we didn't find NVCC, then try the default paths. - find_program(_CUDA_NVCC_EXECUTABLE - NAMES nvcc nvcc.exe - PATH_SUFFIXES bin - NO_CACHE - ) - - # If the user specified CUDAToolkit_ROOT but nvcc could not be found, this is an error. - if(NOT _CUDA_NVCC_EXECUTABLE AND (DEFINED CUDAToolkit_ROOT OR DEFINED ENV{CUDAToolkit_ROOT})) - set(fail_base "Could not find nvcc executable in path specified by") - - if(DEFINED CUDAToolkit_ROOT) - message(FATAL_ERROR "${fail_base} CUDAToolkit_ROOT=${CUDAToolkit_ROOT}") - elseif(DEFINED ENV{CUDAToolkit_ROOT}) - message(FATAL_ERROR "${fail_base} environment variable CUDAToolkit_ROOT=$ENV{CUDAToolkit_ROOT}") - endif() - endif() - - # CUDAToolkit_ROOT cmake/env variable not specified, try platform defaults. - # - # - Linux: /usr/local/cuda-X.Y - # - macOS: /Developer/NVIDIA/CUDA-X.Y - # - Windows: C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\vX.Y - # - # We will also search the default symlink location /usr/local/cuda first since - # if CUDAToolkit_ROOT is not specified, it is assumed that the symlinked - # directory is the desired location. - if(NOT _CUDA_NVCC_EXECUTABLE) - if(UNIX) - if(NOT APPLE) - set(platform_base "/usr/local/cuda-") - else() - set(platform_base "/Developer/NVIDIA/CUDA-") - endif() - else() - set(platform_base "C:\\Program Files\\NVIDIA GPU Computing Toolkit\\CUDA\\v") - endif() - - # Build out a descending list of possible cuda installations, e.g. - file(GLOB possible_paths "${platform_base}*") - # Iterate the glob results and create a descending list. - set(versions) - foreach(p ${possible_paths}) - # Extract version number from end of string - string(REGEX MATCH "[0-9][0-9]?\\.[0-9]$" p_version ${p}) - if(IS_DIRECTORY ${p} AND p_version) - list(APPEND versions ${p_version}) - endif() - endforeach() - - # Sort numerically in descending order, so we try the newest versions first. - list(SORT versions COMPARE NATURAL ORDER DESCENDING) - - # With a descending list of versions, populate possible paths to search. - set(search_paths) - foreach(v ${versions}) - list(APPEND search_paths "${platform_base}${v}") - endforeach() - - # Force the global default /usr/local/cuda to the front on Unix. - if(UNIX) - list(INSERT search_paths 0 "/usr/local/cuda") - endif() - - # Now search for nvcc again using the platform default search paths. - find_program(_CUDA_NVCC_EXECUTABLE - NAMES nvcc nvcc.exe - PATHS ${search_paths} - PATH_SUFFIXES bin - NO_CACHE - ) - - # We are done with these variables now, cleanup. - unset(platform_base) - unset(possible_paths) - unset(versions) - unset(search_paths) - - if(NOT _CUDA_NVCC_EXECUTABLE) - message(FATAL_ERROR "Failed to find nvcc.\nCompiler ${CMAKE_CUDA_COMPILER_ID} requires the CUDA toolkit. Please set the CUDAToolkit_ROOT variable.") - endif() - endif() - endif() - - # Given that NVCC can be provided by multiple different sources (NVIDIA HPC SDK, CUDA Toolkit, distro) - # each of which has a different layout, we need to extract the CUDA toolkit root from the compiler - # itself, allowing us to support numerous different scattered toolkit layouts - execute_process(COMMAND ${_CUDA_NVCC_EXECUTABLE} "-v" "__cmake_determine_cuda" - OUTPUT_VARIABLE _CUDA_NVCC_OUT ERROR_VARIABLE _CUDA_NVCC_OUT) - if(_CUDA_NVCC_OUT MATCHES "\\#\\$ TOP=([^\r\n]*)") - get_filename_component(CMAKE_CUDA_COMPILER_TOOLKIT_ROOT "${CMAKE_MATCH_1}" ABSOLUTE) - else() - get_filename_component(CMAKE_CUDA_COMPILER_TOOLKIT_ROOT "${_CUDA_NVCC_EXECUTABLE}" DIRECTORY) - get_filename_component(CMAKE_CUDA_COMPILER_TOOLKIT_ROOT "${CMAKE_CUDA_COMPILER_TOOLKIT_ROOT}" DIRECTORY) - endif() - - if(_CUDA_NVCC_OUT MATCHES "\\#\\$ NVVMIR_LIBRARY_DIR=([^\r\n]*)") - get_filename_component(_CUDA_NVVMIR_LIBRARY_DIR "${CMAKE_MATCH_1}" ABSOLUTE) - - #We require the path to end in `/nvvm/libdevice' - if(_CUDA_NVVMIR_LIBRARY_DIR MATCHES "nvvm/libdevice$") - get_filename_component(_CUDA_NVVMIR_LIBRARY_DIR "${_CUDA_NVVMIR_LIBRARY_DIR}/../.." ABSOLUTE) - set(_CUDA_COMPILER_LIBRARY_ROOT_FROM_NVVMIR_LIBRARY_DIR "${_CUDA_NVVMIR_LIBRARY_DIR}") - endif() - - unset(_CUDA_NVVMIR_LIBRARY_DIR) - unset(_cuda_nvvmir_dir_name) - endif() - unset(_CUDA_NVCC_OUT) - - # In a non-scattered installation the following are equivalent to CMAKE_CUDA_COMPILER_TOOLKIT_ROOT. - # We first check for a non-scattered installation to prefer it over a scattered installation. - - # CMAKE_CUDA_COMPILER_LIBRARY_ROOT contains the device library. - if(DEFINED _CUDA_COMPILER_LIBRARY_ROOT_FROM_NVVMIR_LIBRARY_DIR) - set(CMAKE_CUDA_COMPILER_LIBRARY_ROOT "${_CUDA_COMPILER_LIBRARY_ROOT_FROM_NVVMIR_LIBRARY_DIR}") - elseif(EXISTS "${CMAKE_CUDA_COMPILER_TOOLKIT_ROOT}/nvvm/libdevice") - set(CMAKE_CUDA_COMPILER_LIBRARY_ROOT "${CMAKE_CUDA_COMPILER_TOOLKIT_ROOT}") - elseif(CMAKE_SYSROOT_LINK AND EXISTS "${CMAKE_SYSROOT_LINK}/usr/lib/cuda/nvvm/libdevice") - set(CMAKE_CUDA_COMPILER_LIBRARY_ROOT "${CMAKE_SYSROOT_LINK}/usr/lib/cuda") - elseif(EXISTS "${CMAKE_SYSROOT}/usr/lib/cuda/nvvm/libdevice") - set(CMAKE_CUDA_COMPILER_LIBRARY_ROOT "${CMAKE_SYSROOT}/usr/lib/cuda") - else() - message(FATAL_ERROR "Couldn't find CUDA library root.") - endif() - unset(_CUDA_COMPILER_LIBRARY_ROOT_FROM_NVVMIR_LIBRARY_DIR) - - # CMAKE_CUDA_COMPILER_TOOLKIT_LIBRARY_ROOT contains the linking stubs necessary for device linking and other low-level library files. - if(CMAKE_SYSROOT_LINK AND EXISTS "${CMAKE_SYSROOT_LINK}/usr/lib/nvidia-cuda-toolkit/bin/crt/link.stub") - set(CMAKE_CUDA_COMPILER_TOOLKIT_LIBRARY_ROOT "${CMAKE_SYSROOT_LINK}/usr/lib/nvidia-cuda-toolkit") - elseif(EXISTS "${CMAKE_SYSROOT}/usr/lib/nvidia-cuda-toolkit/bin/crt/link.stub") - set(CMAKE_CUDA_COMPILER_TOOLKIT_LIBRARY_ROOT "${CMAKE_SYSROOT}/usr/lib/nvidia-cuda-toolkit") - else() - set(CMAKE_CUDA_COMPILER_TOOLKIT_LIBRARY_ROOT "${CMAKE_CUDA_COMPILER_TOOLKIT_ROOT}") - endif() - - # For regular nvcc we the toolkit version is the same as the compiler version and we can parse it from the vendor test output. - # For Clang we need to invoke nvcc to get version output. - if(CMAKE_CUDA_COMPILER_ID STREQUAL "Clang") - execute_process(COMMAND ${_CUDA_NVCC_EXECUTABLE} "--version" OUTPUT_VARIABLE CMAKE_CUDA_COMPILER_ID_OUTPUT) - endif() - - if(CMAKE_CUDA_COMPILER_ID_OUTPUT MATCHES [=[V([0-9]+\.[0-9]+\.[0-9]+)]=]) - set(CMAKE_CUDA_COMPILER_TOOLKIT_VERSION "${CMAKE_MATCH_1}") - endif() - - # Don't leak variables unnecessarily to user code. - unset(_CUDA_NVCC_EXECUTABLE) + # Find the CUDA toolkit to get: + # - CMAKE_CUDA_COMPILER_TOOLKIT_VERSION + # - CMAKE_CUDA_COMPILER_TOOLKIT_ROOT + # - CMAKE_CUDA_COMPILER_LIBRARY_ROOT + # We save them in CMakeCUDACompiler.cmake so FindCUDAToolkit can + # avoid searching on future runs and the toolkit is the same. + include(Internal/CMakeCUDAFindToolkit) + cmake_cuda_find_toolkit(CUDA CMAKE_CUDA_COMPILER_) set(CMAKE_CUDA_DEVICE_LINKER "${CMAKE_CUDA_COMPILER_TOOLKIT_ROOT}/bin/nvlink${CMAKE_EXECUTABLE_SUFFIX}") set(CMAKE_CUDA_FATBINARY "${CMAKE_CUDA_COMPILER_TOOLKIT_ROOT}/bin/fatbinary${CMAKE_EXECUTABLE_SUFFIX}") diff --git a/Modules/Internal/CMakeCUDAFindToolkit.cmake b/Modules/Internal/CMakeCUDAFindToolkit.cmake new file mode 100644 index 0000000..58d1e55 --- /dev/null +++ b/Modules/Internal/CMakeCUDAFindToolkit.cmake @@ -0,0 +1,173 @@ +# Distributed under the OSI-approved BSD 3-Clause License. See accompanying +# file Copyright.txt or https://cmake.org/licensing for details. + +macro(cmake_cuda_find_toolkit lang lang_var_) + # This is very similar to FindCUDAToolkit, but somewhat simplified since we can issue fatal errors + # if we fail and we don't need to account for searching the libraries. + + # For NVCC we can easily deduce the SDK binary directory from the compiler path. + if(CMAKE_${lang}_COMPILER_ID STREQUAL "NVIDIA") + set(_CUDA_NVCC_EXECUTABLE "${CMAKE_${lang}_COMPILER}") + else() + # Search using CUDAToolkit_ROOT and then CUDA_PATH for equivalence with FindCUDAToolkit. + # In FindCUDAToolkit CUDAToolkit_ROOT is searched automatically due to being in a find_package(). + # First we search candidate non-default paths to give them priority. + find_program(_CUDA_NVCC_EXECUTABLE + NAMES nvcc nvcc.exe + PATHS ${CUDAToolkit_ROOT} + ENV CUDAToolkit_ROOT + ENV CUDA_PATH + PATH_SUFFIXES bin + NO_DEFAULT_PATH + NO_CACHE + ) + + # If we didn't find NVCC, then try the default paths. + find_program(_CUDA_NVCC_EXECUTABLE + NAMES nvcc nvcc.exe + PATH_SUFFIXES bin + NO_CACHE + ) + + # If the user specified CUDAToolkit_ROOT but nvcc could not be found, this is an error. + if(NOT _CUDA_NVCC_EXECUTABLE AND (DEFINED CUDAToolkit_ROOT OR DEFINED ENV{CUDAToolkit_ROOT})) + set(fail_base "Could not find nvcc executable in path specified by") + + if(DEFINED CUDAToolkit_ROOT) + message(FATAL_ERROR "${fail_base} CUDAToolkit_ROOT=${CUDAToolkit_ROOT}") + elseif(DEFINED ENV{CUDAToolkit_ROOT}) + message(FATAL_ERROR "${fail_base} environment variable CUDAToolkit_ROOT=$ENV{CUDAToolkit_ROOT}") + endif() + endif() + + # CUDAToolkit_ROOT cmake/env variable not specified, try platform defaults. + # + # - Linux: /usr/local/cuda-X.Y + # - macOS: /Developer/NVIDIA/CUDA-X.Y + # - Windows: C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\vX.Y + # + # We will also search the default symlink location /usr/local/cuda first since + # if CUDAToolkit_ROOT is not specified, it is assumed that the symlinked + # directory is the desired location. + if(NOT _CUDA_NVCC_EXECUTABLE) + if(UNIX) + if(NOT APPLE) + set(platform_base "/usr/local/cuda-") + else() + set(platform_base "/Developer/NVIDIA/CUDA-") + endif() + else() + set(platform_base "C:\\Program Files\\NVIDIA GPU Computing Toolkit\\CUDA\\v") + endif() + + # Build out a descending list of possible cuda installations, e.g. + file(GLOB possible_paths "${platform_base}*") + # Iterate the glob results and create a descending list. + set(versions) + foreach(p ${possible_paths}) + # Extract version number from end of string + string(REGEX MATCH "[0-9][0-9]?\\.[0-9]$" p_version ${p}) + if(IS_DIRECTORY ${p} AND p_version) + list(APPEND versions ${p_version}) + endif() + endforeach() + + # Sort numerically in descending order, so we try the newest versions first. + list(SORT versions COMPARE NATURAL ORDER DESCENDING) + + # With a descending list of versions, populate possible paths to search. + set(search_paths) + foreach(v ${versions}) + list(APPEND search_paths "${platform_base}${v}") + endforeach() + + # Force the global default /usr/local/cuda to the front on Unix. + if(UNIX) + list(INSERT search_paths 0 "/usr/local/cuda") + endif() + + # Now search for nvcc again using the platform default search paths. + find_program(_CUDA_NVCC_EXECUTABLE + NAMES nvcc nvcc.exe + PATHS ${search_paths} + PATH_SUFFIXES bin + NO_CACHE + ) + + # We are done with these variables now, cleanup. + unset(platform_base) + unset(possible_paths) + unset(versions) + unset(search_paths) + + if(NOT _CUDA_NVCC_EXECUTABLE) + message(FATAL_ERROR "Failed to find nvcc.\nCompiler ${CMAKE_${lang}_COMPILER_ID} requires the CUDA toolkit. Please set the CUDAToolkit_ROOT variable.") + endif() + endif() + endif() + + # Given that NVCC can be provided by multiple different sources (NVIDIA HPC SDK, CUDA Toolkit, distro) + # each of which has a different layout, we need to extract the CUDA toolkit root from the compiler + # itself, allowing us to support numerous different scattered toolkit layouts + execute_process(COMMAND ${_CUDA_NVCC_EXECUTABLE} "-v" "__cmake_determine_cuda" + OUTPUT_VARIABLE _CUDA_NVCC_OUT ERROR_VARIABLE _CUDA_NVCC_OUT) + if(_CUDA_NVCC_OUT MATCHES "\\#\\$ TOP=([^\r\n]*)") + get_filename_component(${lang_var_}TOOLKIT_ROOT "${CMAKE_MATCH_1}" ABSOLUTE) + else() + get_filename_component(${lang_var_}TOOLKIT_ROOT "${_CUDA_NVCC_EXECUTABLE}" DIRECTORY) + get_filename_component(${lang_var_}TOOLKIT_ROOT "${${lang_var_}TOOLKIT_ROOT}" DIRECTORY) + endif() + + if(_CUDA_NVCC_OUT MATCHES "\\#\\$ NVVMIR_LIBRARY_DIR=([^\r\n]*)") + get_filename_component(_CUDA_NVVMIR_LIBRARY_DIR "${CMAKE_MATCH_1}" ABSOLUTE) + + #We require the path to end in `/nvvm/libdevice' + if(_CUDA_NVVMIR_LIBRARY_DIR MATCHES "nvvm/libdevice$") + get_filename_component(_CUDA_NVVMIR_LIBRARY_DIR "${_CUDA_NVVMIR_LIBRARY_DIR}/../.." ABSOLUTE) + set(_CUDA_COMPILER_LIBRARY_ROOT_FROM_NVVMIR_LIBRARY_DIR "${_CUDA_NVVMIR_LIBRARY_DIR}") + endif() + + unset(_CUDA_NVVMIR_LIBRARY_DIR) + unset(_cuda_nvvmir_dir_name) + endif() + unset(_CUDA_NVCC_OUT) + + # In a non-scattered installation the following are equivalent to ${lang_var_}TOOLKIT_ROOT. + # We first check for a non-scattered installation to prefer it over a scattered installation. + + # ${lang_var_}LIBRARY_ROOT contains the device library. + if(DEFINED _CUDA_COMPILER_LIBRARY_ROOT_FROM_NVVMIR_LIBRARY_DIR) + set(${lang_var_}LIBRARY_ROOT "${_CUDA_COMPILER_LIBRARY_ROOT_FROM_NVVMIR_LIBRARY_DIR}") + elseif(EXISTS "${${lang_var_}TOOLKIT_ROOT}/nvvm/libdevice") + set(${lang_var_}LIBRARY_ROOT "${${lang_var_}TOOLKIT_ROOT}") + elseif(CMAKE_SYSROOT_LINK AND EXISTS "${CMAKE_SYSROOT_LINK}/usr/lib/cuda/nvvm/libdevice") + set(${lang_var_}LIBRARY_ROOT "${CMAKE_SYSROOT_LINK}/usr/lib/cuda") + elseif(EXISTS "${CMAKE_SYSROOT}/usr/lib/cuda/nvvm/libdevice") + set(${lang_var_}LIBRARY_ROOT "${CMAKE_SYSROOT}/usr/lib/cuda") + else() + message(FATAL_ERROR "Couldn't find CUDA library root.") + endif() + unset(_CUDA_COMPILER_LIBRARY_ROOT_FROM_NVVMIR_LIBRARY_DIR) + + # ${lang_var_}TOOLKIT_LIBRARY_ROOT contains the linking stubs necessary for device linking and other low-level library files. + if(CMAKE_SYSROOT_LINK AND EXISTS "${CMAKE_SYSROOT_LINK}/usr/lib/nvidia-cuda-toolkit/bin/crt/link.stub") + set(${lang_var_}TOOLKIT_LIBRARY_ROOT "${CMAKE_SYSROOT_LINK}/usr/lib/nvidia-cuda-toolkit") + elseif(EXISTS "${CMAKE_SYSROOT}/usr/lib/nvidia-cuda-toolkit/bin/crt/link.stub") + set(${lang_var_}TOOLKIT_LIBRARY_ROOT "${CMAKE_SYSROOT}/usr/lib/nvidia-cuda-toolkit") + else() + set(${lang_var_}TOOLKIT_LIBRARY_ROOT "${${lang_var_}TOOLKIT_ROOT}") + endif() + + # For regular nvcc we the toolkit version is the same as the compiler version and we can parse it from the vendor test output. + # For Clang we need to invoke nvcc to get version output. + if(CMAKE_${lang}_COMPILER_ID STREQUAL "Clang") + execute_process(COMMAND ${_CUDA_NVCC_EXECUTABLE} "--version" OUTPUT_VARIABLE CMAKE_${lang}_COMPILER_ID_OUTPUT) + endif() + + if(CMAKE_${lang}_COMPILER_ID_OUTPUT MATCHES [=[V([0-9]+\.[0-9]+\.[0-9]+)]=]) + set(${lang_var_}TOOLKIT_VERSION "${CMAKE_MATCH_1}") + endif() + + # Don't leak variables unnecessarily to user code. + unset(_CUDA_NVCC_EXECUTABLE) +endmacro() -- cgit v0.12 From 0db0fe7958346ace0f5f01496e071c365faf3eb9 Mon Sep 17 00:00:00 2001 From: Brad King Date: Fri, 15 Sep 2023 10:54:23 -0400 Subject: CUDA: Factor out helper to compute all CUDA architectures Prepare to use it for other languages. --- Modules/CMakeDetermineCUDACompiler.cmake | 8 ++- Modules/CUDA/architectures.cmake | 82 ---------------------- Modules/Internal/CMakeCUDAArchitecturesAll.cmake | 88 ++++++++++++++++++++++++ 3 files changed, 95 insertions(+), 83 deletions(-) delete mode 100644 Modules/CUDA/architectures.cmake create mode 100644 Modules/Internal/CMakeCUDAArchitecturesAll.cmake diff --git a/Modules/CMakeDetermineCUDACompiler.cmake b/Modules/CMakeDetermineCUDACompiler.cmake index e698b79..481a15b 100644 --- a/Modules/CMakeDetermineCUDACompiler.cmake +++ b/Modules/CMakeDetermineCUDACompiler.cmake @@ -84,6 +84,7 @@ if(NOT CMAKE_CUDA_COMPILER_ID_RUN) # - CMAKE_CUDA_COMPILER_LIBRARY_ROOT # We save them in CMakeCUDACompiler.cmake so FindCUDAToolkit can # avoid searching on future runs and the toolkit is the same. + # Match arguments with cmake_cuda_architectures_all call. include(Internal/CMakeCUDAFindToolkit) cmake_cuda_find_toolkit(CUDA CMAKE_CUDA_COMPILER_) @@ -157,7 +158,12 @@ if(NOT CMAKE_CUDA_COMPILER_ID_RUN) set(CMAKE_CUDA_COMPILER_TOOLKIT_VERSION ${CMAKE_CUDA_COMPILER_VERSION}) endif() - include(${CMAKE_ROOT}/Modules/CUDA/architectures.cmake) + include(Internal/CMakeCUDAArchitecturesAll) + # From CMAKE_CUDA_COMPILER_TOOLKIT_VERSION and CMAKE_CUDA_COMPILER_{ID,VERSION}, get: + # - CMAKE_CUDA_ARCHITECTURES_ALL + # - CMAKE_CUDA_ARCHITECTURES_ALL_MAJOR + # Match arguments with cmake_cuda_find_toolkit call. + cmake_cuda_architectures_all(CUDA CMAKE_CUDA_COMPILER_) _cmake_find_compiler_sysroot(CUDA) endif() diff --git a/Modules/CUDA/architectures.cmake b/Modules/CUDA/architectures.cmake deleted file mode 100644 index 87cbaaf..0000000 --- a/Modules/CUDA/architectures.cmake +++ /dev/null @@ -1,82 +0,0 @@ -# See supported GPUs on Wikipedia -# https://en.wikipedia.org/wiki/CUDA#GPUs_supported - -# Initial set based on CUDA 7.0. -set(CMAKE_CUDA_ARCHITECTURES_ALL 20 21 30 35 37 50 52 53) -set(CMAKE_CUDA_ARCHITECTURES_ALL_MAJOR 20 30 35 50) - -if(CMAKE_CUDA_COMPILER_TOOLKIT_VERSION VERSION_GREATER_EQUAL 8.0) - list(APPEND CMAKE_CUDA_ARCHITECTURES_ALL 60 61 62) - list(APPEND CMAKE_CUDA_ARCHITECTURES_ALL_MAJOR 60) -endif() - -if(CMAKE_CUDA_COMPILER_TOOLKIT_VERSION VERSION_GREATER_EQUAL 9.0) - if(CMAKE_CUDA_COMPILER_ID STREQUAL "NVIDIA" - OR (CMAKE_CUDA_COMPILER_ID STREQUAL "Clang" AND CMAKE_CUDA_COMPILER_VERSION VERSION_GREATER_EQUAL 6.0) - ) - list(APPEND CMAKE_CUDA_ARCHITECTURES_ALL 70 72) - list(APPEND CMAKE_CUDA_ARCHITECTURES_ALL_MAJOR 70) - endif() - - list(REMOVE_ITEM CMAKE_CUDA_ARCHITECTURES_ALL 20 21) - list(REMOVE_ITEM CMAKE_CUDA_ARCHITECTURES_ALL_MAJOR 20) -endif() - -if(CMAKE_CUDA_COMPILER_TOOLKIT_VERSION VERSION_GREATER_EQUAL 10.0) - if(CMAKE_CUDA_COMPILER_ID STREQUAL "NVIDIA" - OR (CMAKE_CUDA_COMPILER_ID STREQUAL "Clang" AND CMAKE_CUDA_COMPILER_VERSION VERSION_GREATER_EQUAL 8.0) - ) - list(APPEND CMAKE_CUDA_ARCHITECTURES_ALL 75) - endif() -endif() - -if(CMAKE_CUDA_COMPILER_TOOLKIT_VERSION VERSION_GREATER_EQUAL 11.0) - if(CMAKE_CUDA_COMPILER_ID STREQUAL "NVIDIA" - OR (CMAKE_CUDA_COMPILER_ID STREQUAL "Clang" AND CMAKE_CUDA_COMPILER_VERSION VERSION_GREATER_EQUAL 11.0) - ) - list(APPEND CMAKE_CUDA_ARCHITECTURES_ALL 80) - list(APPEND CMAKE_CUDA_ARCHITECTURES_ALL_MAJOR 80) - endif() - - list(REMOVE_ITEM CMAKE_CUDA_ARCHITECTURES_ALL 30) - list(REMOVE_ITEM CMAKE_CUDA_ARCHITECTURES_ALL_MAJOR 30) -endif() - -if(CMAKE_CUDA_COMPILER_TOOLKIT_VERSION VERSION_GREATER_EQUAL 11.1) - if(CMAKE_CUDA_COMPILER_ID STREQUAL "NVIDIA" - OR (CMAKE_CUDA_COMPILER_ID STREQUAL "Clang" AND CMAKE_CUDA_COMPILER_VERSION VERSION_GREATER_EQUAL 13.0) - ) - list(APPEND CMAKE_CUDA_ARCHITECTURES_ALL 86) - endif() -endif() - -if(CMAKE_CUDA_COMPILER_TOOLKIT_VERSION VERSION_GREATER_EQUAL 11.4) - if(CMAKE_CUDA_COMPILER_ID STREQUAL "NVIDIA") - list(APPEND CMAKE_CUDA_ARCHITECTURES_ALL 87) - endif() -endif() - -if(CMAKE_CUDA_COMPILER_TOOLKIT_VERSION VERSION_GREATER_EQUAL 11.8) - if(CMAKE_CUDA_COMPILER_ID STREQUAL "NVIDIA") - list(APPEND CMAKE_CUDA_ARCHITECTURES_ALL 89 90) - list(APPEND CMAKE_CUDA_ARCHITECTURES_ALL_MAJOR 90) - endif() -endif() - -if(CMAKE_CUDA_COMPILER_TOOLKIT_VERSION VERSION_GREATER_EQUAL 12.0) - if(CMAKE_CUDA_COMPILER_ID STREQUAL "NVIDIA") - list(REMOVE_ITEM CMAKE_CUDA_ARCHITECTURES_ALL 35 37) - list(REMOVE_ITEM CMAKE_CUDA_ARCHITECTURES_ALL_MAJOR 35) - endif() -endif() - -# only generate jit code for the newest arch for all/all-major -list(POP_BACK CMAKE_CUDA_ARCHITECTURES_ALL _latest_arch) -list(TRANSFORM CMAKE_CUDA_ARCHITECTURES_ALL APPEND "-real") -list(APPEND CMAKE_CUDA_ARCHITECTURES_ALL ${_latest_arch}) - -list(POP_BACK CMAKE_CUDA_ARCHITECTURES_ALL_MAJOR _latest_arch) -list(TRANSFORM CMAKE_CUDA_ARCHITECTURES_ALL_MAJOR APPEND "-real") -list(APPEND CMAKE_CUDA_ARCHITECTURES_ALL_MAJOR ${_latest_arch}) - -unset(_latest_arch) diff --git a/Modules/Internal/CMakeCUDAArchitecturesAll.cmake b/Modules/Internal/CMakeCUDAArchitecturesAll.cmake new file mode 100644 index 0000000..873400a --- /dev/null +++ b/Modules/Internal/CMakeCUDAArchitecturesAll.cmake @@ -0,0 +1,88 @@ +# Distributed under the OSI-approved BSD 3-Clause License. See accompanying +# file Copyright.txt or https://cmake.org/licensing for details. + +# See supported GPUs on Wikipedia +# https://en.wikipedia.org/wiki/CUDA#GPUs_supported + +function(cmake_cuda_architectures_all lang lang_var_) + # Initial set based on CUDA 7.0. + set(CMAKE_CUDA_ARCHITECTURES_ALL 20 21 30 35 37 50 52 53) + set(CMAKE_CUDA_ARCHITECTURES_ALL_MAJOR 20 30 35 50) + + if(${lang_var_}TOOLKIT_VERSION VERSION_GREATER_EQUAL 8.0) + list(APPEND CMAKE_CUDA_ARCHITECTURES_ALL 60 61 62) + list(APPEND CMAKE_CUDA_ARCHITECTURES_ALL_MAJOR 60) + endif() + + if(${lang_var_}TOOLKIT_VERSION VERSION_GREATER_EQUAL 9.0) + if(CMAKE_${lang}_COMPILER_ID STREQUAL "NVIDIA" + OR (CMAKE_${lang}_COMPILER_ID STREQUAL "Clang" AND CMAKE_${lang}_COMPILER_VERSION VERSION_GREATER_EQUAL 6.0) + ) + list(APPEND CMAKE_CUDA_ARCHITECTURES_ALL 70 72) + list(APPEND CMAKE_CUDA_ARCHITECTURES_ALL_MAJOR 70) + endif() + + list(REMOVE_ITEM CMAKE_CUDA_ARCHITECTURES_ALL 20 21) + list(REMOVE_ITEM CMAKE_CUDA_ARCHITECTURES_ALL_MAJOR 20) + endif() + + if(${lang_var_}TOOLKIT_VERSION VERSION_GREATER_EQUAL 10.0) + if(CMAKE_${lang}_COMPILER_ID STREQUAL "NVIDIA" + OR (CMAKE_${lang}_COMPILER_ID STREQUAL "Clang" AND CMAKE_${lang}_COMPILER_VERSION VERSION_GREATER_EQUAL 8.0) + ) + list(APPEND CMAKE_CUDA_ARCHITECTURES_ALL 75) + endif() + endif() + + if(${lang_var_}TOOLKIT_VERSION VERSION_GREATER_EQUAL 11.0) + if(CMAKE_${lang}_COMPILER_ID STREQUAL "NVIDIA" + OR (CMAKE_${lang}_COMPILER_ID STREQUAL "Clang" AND CMAKE_${lang}_COMPILER_VERSION VERSION_GREATER_EQUAL 11.0) + ) + list(APPEND CMAKE_CUDA_ARCHITECTURES_ALL 80) + list(APPEND CMAKE_CUDA_ARCHITECTURES_ALL_MAJOR 80) + endif() + + list(REMOVE_ITEM CMAKE_CUDA_ARCHITECTURES_ALL 30) + list(REMOVE_ITEM CMAKE_CUDA_ARCHITECTURES_ALL_MAJOR 30) + endif() + + if(${lang_var_}TOOLKIT_VERSION VERSION_GREATER_EQUAL 11.1) + if(CMAKE_${lang}_COMPILER_ID STREQUAL "NVIDIA" + OR (CMAKE_${lang}_COMPILER_ID STREQUAL "Clang" AND CMAKE_${lang}_COMPILER_VERSION VERSION_GREATER_EQUAL 13.0) + ) + list(APPEND CMAKE_CUDA_ARCHITECTURES_ALL 86) + endif() + endif() + + if(${lang_var_}TOOLKIT_VERSION VERSION_GREATER_EQUAL 11.4) + if(CMAKE_${lang}_COMPILER_ID STREQUAL "NVIDIA") + list(APPEND CMAKE_CUDA_ARCHITECTURES_ALL 87) + endif() + endif() + + if(${lang_var_}TOOLKIT_VERSION VERSION_GREATER_EQUAL 11.8) + if(CMAKE_${lang}_COMPILER_ID STREQUAL "NVIDIA") + list(APPEND CMAKE_CUDA_ARCHITECTURES_ALL 89 90) + list(APPEND CMAKE_CUDA_ARCHITECTURES_ALL_MAJOR 90) + endif() + endif() + + if(${lang_var_}TOOLKIT_VERSION VERSION_GREATER_EQUAL 12.0) + if(CMAKE_${lang}_COMPILER_ID STREQUAL "NVIDIA") + list(REMOVE_ITEM CMAKE_CUDA_ARCHITECTURES_ALL 35 37) + list(REMOVE_ITEM CMAKE_CUDA_ARCHITECTURES_ALL_MAJOR 35) + endif() + endif() + + # only generate jit code for the newest arch for all/all-major + list(POP_BACK CMAKE_CUDA_ARCHITECTURES_ALL _latest_arch) + list(TRANSFORM CMAKE_CUDA_ARCHITECTURES_ALL APPEND "-real") + list(APPEND CMAKE_CUDA_ARCHITECTURES_ALL ${_latest_arch}) + + list(POP_BACK CMAKE_CUDA_ARCHITECTURES_ALL_MAJOR _latest_arch) + list(TRANSFORM CMAKE_CUDA_ARCHITECTURES_ALL_MAJOR APPEND "-real") + list(APPEND CMAKE_CUDA_ARCHITECTURES_ALL_MAJOR ${_latest_arch}) + + set(CMAKE_${lang}_ARCHITECTURES_ALL "${CMAKE_CUDA_ARCHITECTURES_ALL}" PARENT_SCOPE) + set(CMAKE_${lang}_ARCHITECTURES_ALL_MAJOR "${CMAKE_CUDA_ARCHITECTURES_ALL_MAJOR}" PARENT_SCOPE) +endfunction() -- cgit v0.12 From 8617c28221cac2bd89402178b25dcd47445a9349 Mon Sep 17 00:00:00 2001 From: Brad King Date: Fri, 15 Sep 2023 11:47:28 -0400 Subject: CUDA: Factor out helper for detecting native CUDA architectures Prepare to use it for other languages. --- Modules/CMakeCUDACompilerABI.cu | 25 +---------- Modules/CMakeCompilerCUDAArch.h | 29 +++++++++++++ Modules/CMakeTestCUDACompiler.cmake | 49 ++-------------------- .../Internal/CMakeCUDAArchitecturesNative.cmake | 49 ++++++++++++++++++++++ 4 files changed, 84 insertions(+), 68 deletions(-) create mode 100644 Modules/CMakeCompilerCUDAArch.h create mode 100644 Modules/Internal/CMakeCUDAArchitecturesNative.cmake diff --git a/Modules/CMakeCUDACompilerABI.cu b/Modules/CMakeCUDACompilerABI.cu index 8463e86..b04d0ec 100644 --- a/Modules/CMakeCUDACompilerABI.cu +++ b/Modules/CMakeCUDACompilerABI.cu @@ -2,11 +2,8 @@ # error "A C or C++ compiler has been selected for CUDA" #endif -#include - -#include - #include "CMakeCompilerABI.h" +#include "CMakeCompilerCUDAArch.h" int main(int argc, char* argv[]) { @@ -19,25 +16,7 @@ int main(int argc, char* argv[]) #endif static_cast(argv); - int count = 0; - if (cudaGetDeviceCount(&count) != cudaSuccess || count == 0) { - std::fprintf(stderr, "No CUDA devices found.\n"); - return -1; - } - - int found = 0; - const char* sep = ""; - for (int device = 0; device < count; ++device) { - cudaDeviceProp prop; - if (cudaGetDeviceProperties(&prop, device) == cudaSuccess) { - std::printf("%s%d%d", sep, prop.major, prop.minor); - sep = ";"; - found = 1; - } - } - - if (!found) { - std::fprintf(stderr, "No CUDA architecture detected from any devices.\n"); + if (!cmakeCompilerCUDAArch()) { // Convince the compiler that the non-zero return value depends // on the info strings so they are not optimized out. return require ? -1 : 1; diff --git a/Modules/CMakeCompilerCUDAArch.h b/Modules/CMakeCompilerCUDAArch.h new file mode 100644 index 0000000..dcb030f --- /dev/null +++ b/Modules/CMakeCompilerCUDAArch.h @@ -0,0 +1,29 @@ +#include + +#include + +static bool cmakeCompilerCUDAArch() +{ + int count = 0; + if (cudaGetDeviceCount(&count) != cudaSuccess || count == 0) { + std::fprintf(stderr, "No CUDA devices found.\n"); + return -1; + } + + bool found = false; + const char* sep = ""; + for (int device = 0; device < count; ++device) { + cudaDeviceProp prop; + if (cudaGetDeviceProperties(&prop, device) == cudaSuccess) { + std::printf("%s%d%d", sep, prop.major, prop.minor); + sep = ";"; + found = true; + } + } + + if (!found) { + std::fprintf(stderr, "No CUDA architecture detected from any devices.\n"); + } + + return found; +} diff --git a/Modules/CMakeTestCUDACompiler.cmake b/Modules/CMakeTestCUDACompiler.cmake index 79ee20f..3057fe9 100644 --- a/Modules/CMakeTestCUDACompiler.cmake +++ b/Modules/CMakeTestCUDACompiler.cmake @@ -22,51 +22,10 @@ if(CMAKE_CUDA_ABI_COMPILED) set(CMAKE_CUDA_COMPILER_WORKS TRUE) message(STATUS "Check for working CUDA compiler: ${CMAKE_CUDA_COMPILER} - skipped") - # Run the test binary to detect the native architectures. - execute_process(COMMAND "${CMAKE_PLATFORM_INFO_DIR}/CMakeDetermineCompilerABI_CUDA.bin" - RESULT_VARIABLE _CUDA_ARCHS_RESULT - OUTPUT_VARIABLE _CUDA_ARCHS_OUTPUT - ERROR_VARIABLE _CUDA_ARCHS_OUTPUT - OUTPUT_STRIP_TRAILING_WHITESPACE - ) - if(_CUDA_ARCHS_RESULT EQUAL 0) - if("$ENV{CMAKE_CUDA_ARCHITECTURES_NATIVE_CLAMP}") - # Undocumented hook used by CMake's CI. - # Clamp native architecture to version range supported by this CUDA. - list(GET CMAKE_CUDA_ARCHITECTURES_ALL 0 _CUDA_ARCH_MIN) - list(GET CMAKE_CUDA_ARCHITECTURES_ALL -1 _CUDA_ARCH_MAX) - set(CMAKE_CUDA_ARCHITECTURES_NATIVE "") - foreach(_CUDA_ARCH IN LISTS _CUDA_ARCHS_OUTPUT) - if(_CUDA_ARCH LESS _CUDA_ARCH_MIN) - set(_CUDA_ARCH "${_CUDA_ARCH_MIN}") - endif() - if(_CUDA_ARCH GREATER _CUDA_ARCH_MAX) - set(_CUDA_ARCH "${_CUDA_ARCH_MAX}") - endif() - list(APPEND CMAKE_CUDA_ARCHITECTURES_NATIVE ${_CUDA_ARCH}) - endforeach() - unset(_CUDA_ARCH) - unset(_CUDA_ARCH_MIN) - unset(_CUDA_ARCH_MAX) - else() - set(CMAKE_CUDA_ARCHITECTURES_NATIVE "${_CUDA_ARCHS_OUTPUT}") - endif() - list(REMOVE_DUPLICATES CMAKE_CUDA_ARCHITECTURES_NATIVE) - list(TRANSFORM CMAKE_CUDA_ARCHITECTURES_NATIVE APPEND "-real") - else() - if(NOT _CUDA_ARCHS_RESULT MATCHES "[0-9]+") - set(_CUDA_ARCHS_STATUS " (${_CUDA_ARCHS_RESULT})") - else() - set(_CUDA_ARCHS_STATUS "") - endif() - string(REPLACE "\n" "\n " _CUDA_ARCHS_OUTPUT " ${_CUDA_ARCHS_OUTPUT}") - message(CONFIGURE_LOG - "Detecting the CUDA native architecture(s) failed with " - "the following output:\n${_CUDA_ARCHS_OUTPUT}\n\n") - endif() - unset(_CUDA_ARCHS_EXE) - unset(_CUDA_ARCHS_RESULT) - unset(_CUDA_ARCHS_OUTPUT) + include(Internal/CMakeCUDAArchitecturesNative) + # Run the test binary to get: + # - CMAKE_CUDA_ARCHITECTURES_NATIVE + cmake_cuda_architectures_native(CUDA) endif() # This file is used by EnableLanguage in cmGlobalGenerator to diff --git a/Modules/Internal/CMakeCUDAArchitecturesNative.cmake b/Modules/Internal/CMakeCUDAArchitecturesNative.cmake new file mode 100644 index 0000000..4185eda --- /dev/null +++ b/Modules/Internal/CMakeCUDAArchitecturesNative.cmake @@ -0,0 +1,49 @@ +# Distributed under the OSI-approved BSD 3-Clause License. See accompanying +# file Copyright.txt or https://cmake.org/licensing for details. + +function(cmake_cuda_architectures_native lang) + # Run the test binary to detect the native architectures. + execute_process(COMMAND "${CMAKE_PLATFORM_INFO_DIR}/CMakeDetermineCompilerABI_${lang}.bin" + RESULT_VARIABLE archs_result + OUTPUT_VARIABLE archs_output + ERROR_VARIABLE archs_output + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + if(archs_result EQUAL 0) + if("$ENV{CMAKE_CUDA_ARCHITECTURES_NATIVE_CLAMP}") + # Undocumented hook used by CMake's CI. + # Clamp native architecture to version range supported by this CUDA. + list(GET CMAKE_${lang}_ARCHITECTURES_ALL 0 arch_min) + list(GET CMAKE_${lang}_ARCHITECTURES_ALL -1 arch_max) + set(CMAKE_CUDA_ARCHITECTURES_NATIVE "") + foreach(arch IN LISTS archs_output) + if(arch LESS arch_min) + set(arch "${arch_min}") + endif() + if(arch GREATER arch_max) + set(arch "${arch_max}") + endif() + list(APPEND CMAKE_CUDA_ARCHITECTURES_NATIVE ${arch}) + endforeach() + unset(arch) + unset(arch_min) + unset(arch_max) + else() + set(CMAKE_CUDA_ARCHITECTURES_NATIVE "${archs_output}") + endif() + list(REMOVE_DUPLICATES CMAKE_CUDA_ARCHITECTURES_NATIVE) + list(TRANSFORM CMAKE_CUDA_ARCHITECTURES_NATIVE APPEND "-real") + else() + if(NOT archs_result MATCHES "[0-9]+") + set(archs_status " (${archs_result})") + else() + set(archs_status "") + endif() + string(REPLACE "\n" "\n " archs_output " ${archs_output}") + message(CONFIGURE_LOG + "Detecting the CUDA native architecture(s) failed with " + "the following output${archs_status}:\n${archs_output}\n\n") + endif() + + set(CMAKE_${lang}_ARCHITECTURES_NATIVE "${CMAKE_CUDA_ARCHITECTURES_NATIVE}" PARENT_SCOPE) +endfunction() -- cgit v0.12 From b3a1f175677016d4314793f91e255f384c320ec7 Mon Sep 17 00:00:00 2001 From: Brad King Date: Mon, 18 Sep 2023 13:38:25 -0400 Subject: CUDA: Factor out helper to validate CMAKE_CUDA_ARCHITECTURES Prepare to use it for other languages. --- Modules/CMakeDetermineCUDACompiler.cmake | 20 +++----------------- .../Internal/CMakeCUDAArchitecturesValidate.cmake | 19 +++++++++++++++++++ .../architectures-empty-stderr.txt | 4 +++- .../architectures-invalid-stderr.txt | 4 +++- 4 files changed, 28 insertions(+), 19 deletions(-) create mode 100644 Modules/Internal/CMakeCUDAArchitecturesValidate.cmake diff --git a/Modules/CMakeDetermineCUDACompiler.cmake b/Modules/CMakeDetermineCUDACompiler.cmake index 481a15b..585b2aa 100644 --- a/Modules/CMakeDetermineCUDACompiler.cmake +++ b/Modules/CMakeDetermineCUDACompiler.cmake @@ -111,23 +111,9 @@ if(NOT CMAKE_CUDA_COMPILER_ID_RUN) endif() endif() - # Rest of the code treats an empty value as equivalent to "use the defaults". - # Error out early to prevent confusing errors as a result of this. - # Note that this also catches invalid non-numerical values such as "a". - if(DEFINED CMAKE_CUDA_ARCHITECTURES) - if(CMAKE_CUDA_ARCHITECTURES STREQUAL "") - message(FATAL_ERROR "CMAKE_CUDA_ARCHITECTURES must be non-empty if set.") - elseif(CMAKE_CUDA_ARCHITECTURES AND NOT CMAKE_CUDA_ARCHITECTURES MATCHES "^([0-9]+a?(-real|-virtual)?(;[0-9]+a?(-real|-virtual)?|;)*|all|all-major|native)$") - message(FATAL_ERROR - "CMAKE_CUDA_ARCHITECTURES:\n" - " ${CMAKE_CUDA_ARCHITECTURES}\n" - "is not one of the following:\n" - " * a semicolon-separated list of integers, each optionally\n" - " followed by '-real' or '-virtual'\n" - " * a special value: all, all-major, native\n" - ) - endif() - endif() + # If the user set CMAKE_CUDA_ARCHITECTURES, validate its value. + include(Internal/CMakeCUDAArchitecturesValidate) + cmake_cuda_architectures_validate(CUDA) if(CMAKE_CUDA_COMPILER_ID STREQUAL "Clang") # Clang doesn't automatically select an architecture supported by the SDK. diff --git a/Modules/Internal/CMakeCUDAArchitecturesValidate.cmake b/Modules/Internal/CMakeCUDAArchitecturesValidate.cmake new file mode 100644 index 0000000..b6997d2 --- /dev/null +++ b/Modules/Internal/CMakeCUDAArchitecturesValidate.cmake @@ -0,0 +1,19 @@ +# Distributed under the OSI-approved BSD 3-Clause License. See accompanying +# file Copyright.txt or https://cmake.org/licensing for details. + +function(cmake_cuda_architectures_validate lang) + if(DEFINED CMAKE_${lang}_ARCHITECTURES) + if(CMAKE_${lang}_ARCHITECTURES STREQUAL "") + message(FATAL_ERROR "CMAKE_${lang}_ARCHITECTURES must be non-empty if set.") + elseif(CMAKE_${lang}_ARCHITECTURES AND NOT CMAKE_${lang}_ARCHITECTURES MATCHES "^([0-9]+a?(-real|-virtual)?(;[0-9]+a?(-real|-virtual)?|;)*|all|all-major|native)$") + message(FATAL_ERROR + "CMAKE_${lang}_ARCHITECTURES:\n" + " ${CMAKE_${lang}_ARCHITECTURES}\n" + "is not one of the following:\n" + " * a semicolon-separated list of integers, each optionally\n" + " followed by '-real' or '-virtual'\n" + " * a special value: all, all-major, native\n" + ) + endif() + endif() +endfunction() diff --git a/Tests/RunCMake/CUDA_architectures/architectures-empty-stderr.txt b/Tests/RunCMake/CUDA_architectures/architectures-empty-stderr.txt index 6c42612..dbadd048 100644 --- a/Tests/RunCMake/CUDA_architectures/architectures-empty-stderr.txt +++ b/Tests/RunCMake/CUDA_architectures/architectures-empty-stderr.txt @@ -1,5 +1,7 @@ -^CMake Error at .*/Modules/CMakeDetermineCUDACompiler\.cmake:[0-9]+ \(message\): +^CMake Error at .*/Internal/CMakeCUDAArchitecturesValidate\.cmake:[0-9]+ \(message\): CMAKE_CUDA_ARCHITECTURES must be non-empty if set\. Call Stack \(most recent call first\): + [^ +]*/Modules/CMakeDetermineCUDACompiler.cmake:[0-9]+ \(cmake_cuda_architectures_validate\) architectures-empty\.cmake:2 \(enable_language\) CMakeLists\.txt:3 \(include\) diff --git a/Tests/RunCMake/CUDA_architectures/architectures-invalid-stderr.txt b/Tests/RunCMake/CUDA_architectures/architectures-invalid-stderr.txt index 14c76d2..891aa40 100644 --- a/Tests/RunCMake/CUDA_architectures/architectures-invalid-stderr.txt +++ b/Tests/RunCMake/CUDA_architectures/architectures-invalid-stderr.txt @@ -1,4 +1,4 @@ -^CMake Error at .*/Modules/CMakeDetermineCUDACompiler\.cmake:[0-9]+ \(message\): +^CMake Error at .*/Internal/CMakeCUDAArchitecturesValidate\.cmake:[0-9]+ \(message\): CMAKE_CUDA_ARCHITECTURES: invalid @@ -10,5 +10,7 @@ \* a special value: all, all-major, native Call Stack \(most recent call first\): + [^ +]*/Modules/CMakeDetermineCUDACompiler.cmake:[0-9]+ \(cmake_cuda_architectures_validate\) architectures-invalid\.cmake:2 \(enable_language\) CMakeLists\.txt:3 \(include\)$ -- cgit v0.12 From b32ea7cff050574c00b5207035762e3b24f8a405 Mon Sep 17 00:00:00 2001 From: Brad King Date: Mon, 18 Sep 2023 14:44:29 -0400 Subject: CUDA: Factor out helper to generate CUDA architecture flags Prepare to use it for other languages. --- Source/cmGeneratorTarget.cxx | 53 +++++++++++++++++++++++++++----------------- Source/cmGeneratorTarget.h | 6 ++++- 2 files changed, 38 insertions(+), 21 deletions(-) diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx index 0eb3851..80e3392 100644 --- a/Source/cmGeneratorTarget.cxx +++ b/Source/cmGeneratorTarget.cxx @@ -3387,7 +3387,7 @@ void cmGeneratorTarget::AddExplicitLanguageFlags(std::string& flags, } void cmGeneratorTarget::AddCUDAArchitectureFlags(cmBuildStep compileOrLink, - const std::string& config, + std::string const& config, std::string& flags) const { std::string arch = this->GetSafeProperty("CUDA_ARCHITECTURES"); @@ -3418,39 +3418,52 @@ void cmGeneratorTarget::AddCUDAArchitectureFlags(cmBuildStep compileOrLink, return; } - std::string const& compiler = - this->Makefile->GetSafeDefinition("CMAKE_CUDA_COMPILER_ID"); - const bool ipoEnabled = this->IsIPOEnabled("CUDA", config); + return this->AddCUDAArchitectureFlagsImpl(compileOrLink, config, "CUDA", + std::move(arch), flags); +} + +void cmGeneratorTarget::AddCUDAArchitectureFlagsImpl(cmBuildStep compileOrLink, + std::string const& config, + std::string const& lang, + std::string arch, + std::string& flags) const +{ + std::string const& compiler = this->Makefile->GetSafeDefinition( + cmStrCat("CMAKE_", lang, "_COMPILER_ID")); + const bool ipoEnabled = this->IsIPOEnabled(lang, config); // Check for special modes: `all`, `all-major`. if (arch == "all" || arch == "all-major") { if (compiler == "NVIDIA" && - cmSystemTools::VersionCompare( - cmSystemTools::OP_GREATER_EQUAL, - this->Makefile->GetDefinition("CMAKE_CUDA_COMPILER_VERSION"), - "11.5")) { + cmSystemTools::VersionCompare(cmSystemTools::OP_GREATER_EQUAL, + this->Makefile->GetDefinition(cmStrCat( + "CMAKE_", lang, "_COMPILER_VERSION")), + "11.5")) { flags = cmStrCat(flags, " -arch=", arch); return; } if (arch == "all") { - arch = *this->Makefile->GetDefinition("CMAKE_CUDA_ARCHITECTURES_ALL"); + arch = *this->Makefile->GetDefinition( + cmStrCat("CMAKE_", lang, "_ARCHITECTURES_ALL")); } else if (arch == "all-major") { - arch = - *this->Makefile->GetDefinition("CMAKE_CUDA_ARCHITECTURES_ALL_MAJOR"); + arch = *this->Makefile->GetDefinition( + cmStrCat("CMAKE_", lang, "_ARCHITECTURES_ALL_MAJOR")); } } else if (arch == "native") { - cmValue native = - this->Makefile->GetDefinition("CMAKE_CUDA_ARCHITECTURES_NATIVE"); + cmValue native = this->Makefile->GetDefinition( + cmStrCat("CMAKE_", lang, "_ARCHITECTURES_NATIVE")); if (native.IsEmpty()) { this->Makefile->IssueMessage( MessageType::FATAL_ERROR, - "CUDA_ARCHITECTURES is set to \"native\", but no GPU was detected."); + cmStrCat(lang, + "_ARCHITECTURES is set to \"native\", but no NVIDIA GPU was " + "detected.")); } if (compiler == "NVIDIA" && - cmSystemTools::VersionCompare( - cmSystemTools::OP_GREATER_EQUAL, - this->Makefile->GetDefinition("CMAKE_CUDA_COMPILER_VERSION"), - "11.6")) { + cmSystemTools::VersionCompare(cmSystemTools::OP_GREATER_EQUAL, + this->Makefile->GetDefinition(cmStrCat( + "CMAKE_", lang, "_COMPILER_VERSION")), + "11.6")) { flags = cmStrCat(flags, " -arch=", arch); return; } @@ -3499,8 +3512,8 @@ void cmGeneratorTarget::AddCUDAArchitectureFlags(cmBuildStep compileOrLink, if (compiler == "NVIDIA") { if (ipoEnabled && compileOrLink == cmBuildStep::Link) { - if (cmValue cudaIPOFlags = - this->Makefile->GetDefinition("CMAKE_CUDA_LINK_OPTIONS_IPO")) { + if (cmValue cudaIPOFlags = this->Makefile->GetDefinition( + cmStrCat("CMAKE_", lang, "_LINK_OPTIONS_IPO"))) { flags += *cudaIPOFlags; } } diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h index 7673bef..6a385ea 100644 --- a/Source/cmGeneratorTarget.h +++ b/Source/cmGeneratorTarget.h @@ -496,8 +496,12 @@ public: cmSourceFile const& sf) const; void AddCUDAArchitectureFlags(cmBuildStep compileOrLink, - const std::string& config, + std::string const& config, std::string& flags) const; + void AddCUDAArchitectureFlagsImpl(cmBuildStep compileOrLink, + std::string const& config, + std::string const& lang, std::string arch, + std::string& flags) const; void AddCUDAToolkitFlags(std::string& flags) const; void AddHIPArchitectureFlags(std::string& flags) const; -- cgit v0.12