mirror of
https://gitlab.kitware.com/cmake/cmake.git
synced 2026-09-25 04:09:36 +03:00
Clang/CUDA: Support the llvm23+ offload linker model
Fixes: #26120, #26810
This commit is contained in:
@@ -0,0 +1,6 @@
|
||||
clang-cuda-offload-linker
|
||||
-------------------------
|
||||
|
||||
* Clang compiler version 20 and above use a new offload linker
|
||||
model for CUDA where device linking is performed as part of the host link
|
||||
phase.
|
||||
@@ -34,6 +34,10 @@ set(CMAKE_CUDA_COMPILER_LOADED 1)
|
||||
set(CMAKE_CUDA_COMPILER_ID_RUN 1)
|
||||
set(CMAKE_CUDA_SOURCE_FILE_EXTENSIONS cu)
|
||||
set(CMAKE_CUDA_LINKER_PREFERENCE 15)
|
||||
if(CMAKE_CUDA_COMPILER_ID STREQUAL "Clang" AND
|
||||
CMAKE_CUDA_COMPILER_VERSION VERSION_GREATER_EQUAL 20.0)
|
||||
set(CMAKE_CUDA_LINKER_PREFERENCE 90)
|
||||
endif()
|
||||
set(CMAKE_CUDA_LINKER_PREFERENCE_PROPAGATES 1)
|
||||
set(CMAKE_CUDA_LINKER_DEPFILE_SUPPORTED @CMAKE_CUDA_LINKER_DEPFILE_SUPPORTED@)
|
||||
set(CMAKE_LINKER_PUSHPOP_STATE_SUPPORTED @CMAKE_LINKER_PUSHPOP_STATE_SUPPORTED@)
|
||||
|
||||
@@ -54,6 +54,7 @@ endif()
|
||||
# any makefiles or projects.
|
||||
if(NOT CMAKE_CUDA_COMPILER_WORKS)
|
||||
PrintTestCompilerStatus("CUDA")
|
||||
__TestCompiler_setTryCompileTargetType()
|
||||
string(CONCAT __TestCompiler_testCudaCompilerSource
|
||||
"#ifndef __CUDACC__\n"
|
||||
"# error \"The CMAKE_CUDA_COMPILER is set to an invalid CUDA compiler\"\n"
|
||||
@@ -69,7 +70,7 @@ if(NOT CMAKE_CUDA_COMPILER_WORKS)
|
||||
NO_CACHE
|
||||
OUTPUT_VARIABLE __CMAKE_CUDA_COMPILER_OUTPUT)
|
||||
unset(__TestCompiler_testCudaCompilerSource)
|
||||
|
||||
__TestCompiler_restoreTryCompileTargetType()
|
||||
if(NOT CMAKE_CUDA_COMPILER_WORKS)
|
||||
PrintTestCompilerResult(CHECK_FAIL "broken")
|
||||
string(REPLACE "\n" "\n " _output "${__CMAKE_CUDA_COMPILER_OUTPUT}")
|
||||
|
||||
@@ -21,6 +21,14 @@ macro(__TestCompiler_setTryCompileTargetType)
|
||||
set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)
|
||||
set(__CMAKE_TEST_COMPILER_TARGET_TYPE_RESTORE 1)
|
||||
endif()
|
||||
|
||||
if(CMAKE_CUDA_COMPILER_ID STREQUAL "Clang" AND
|
||||
CMAKE_CUDA_COMPILER_VERSION VERSION_GREATER_EQUAL 20.0 AND
|
||||
CMAKE_CUDA_COMPILER_VERSION VERSION_LESS 23.0)
|
||||
# https://github.com/llvm/llvm-project/issues/191041
|
||||
set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)
|
||||
set(__CMAKE_TEST_COMPILER_TARGET_TYPE_RESTORE 1)
|
||||
endif()
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
|
||||
@@ -22,6 +22,12 @@ set(_CMAKE_CUDA_WHOLE_FLAG "-c")
|
||||
set(_CMAKE_CUDA_RDC_FLAG "-fgpu-rdc")
|
||||
set(_CMAKE_CUDA_PTX_FLAG "--cuda-device-only -S")
|
||||
|
||||
if (CMAKE_CUDA_COMPILER_VERSION VERSION_GREATER_EQUAL 20.0)
|
||||
# Starting in 20.0, clang supports device linking as part of the host link phase
|
||||
set(CMAKE_CUDA_COMPILER_HAS_DEVICE_LINK_PHASE FALSE)
|
||||
set(_CMAKE_CUDA_RDC_LINK_FLAG "--offload-link")
|
||||
endif()
|
||||
|
||||
# Device linking is just regular linking so these are the same.
|
||||
set(CMAKE_CUDA_DEVICE_LINKER_WRAPPER_FLAG ${CMAKE_CUDA_LINKER_WRAPPER_FLAG})
|
||||
set(CMAKE_CUDA_DEVICE_LINKER_WRAPPER_FLAG_SEP ${CMAKE_CUDA_LINKER_WRAPPER_FLAG_SEP})
|
||||
@@ -29,8 +35,8 @@ set(CMAKE_CUDA_DEVICE_LINKER_WRAPPER_FLAG_SEP ${CMAKE_CUDA_LINKER_WRAPPER_FLAG_S
|
||||
set(CMAKE_CUDA_DEVICE_LINK_MODE DRIVER)
|
||||
|
||||
# RulePlaceholderExpander expands crosscompile variables like sysroot and target only for CMAKE_<LANG>_COMPILER. Override the default.
|
||||
set(CMAKE_CUDA_LINK_EXECUTABLE "<CMAKE_CUDA_COMPILER> <FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>${__IMPLICIT_LINKS}")
|
||||
set(CMAKE_CUDA_CREATE_SHARED_LIBRARY "<CMAKE_CUDA_COMPILER> <CMAKE_SHARED_LIBRARY_CUDA_FLAGS> <LANGUAGE_COMPILE_FLAGS> <LINK_FLAGS> <SONAME_FLAG><TARGET_SONAME> -o <TARGET> <OBJECTS> <LINK_LIBRARIES>${__IMPLICIT_LINKS}")
|
||||
set(CMAKE_CUDA_LINK_EXECUTABLE "<CMAKE_CUDA_COMPILER> <FLAGS> <LINK_FLAGS> ${_CMAKE_CUDA_RDC_LINK_FLAG} <OBJECTS> -o <TARGET> <LINK_LIBRARIES>${__IMPLICIT_LINKS}")
|
||||
set(CMAKE_CUDA_CREATE_SHARED_LIBRARY "<CMAKE_CUDA_COMPILER> <CMAKE_SHARED_LIBRARY_CUDA_FLAGS> <LANGUAGE_COMPILE_FLAGS> <LINK_FLAGS> ${_CMAKE_CUDA_RDC_LINK_FLAG} <SONAME_FLAG><TARGET_SONAME> -o <TARGET> <OBJECTS> <LINK_LIBRARIES>${__IMPLICIT_LINKS}")
|
||||
|
||||
set(CMAKE_CUDA_RUNTIME_LIBRARY_DEFAULT "STATIC")
|
||||
set(CMAKE_CUDA_RUNTIME_LIBRARY_LINK_OPTIONS_STATIC "cudadevrt;cudart_static")
|
||||
|
||||
@@ -12,6 +12,12 @@ function(cmake_cuda_architectures_all lang lang_var_)
|
||||
# Initial set based on CUDA 13.0.
|
||||
set(CMAKE_CUDA_ARCHITECTURES_ALL 75 80 86 87 88 89 90 100 103 110 120 121)
|
||||
set(CMAKE_CUDA_ARCHITECTURES_ALL_MAJOR 75 80 90 100 110 120)
|
||||
|
||||
if((CMAKE_${lang}_COMPILER_ID STREQUAL "Clang" AND CMAKE_${lang}_COMPILER_VERSION VERSION_LESS 23.0))
|
||||
list(REMOVE_ITEM CMAKE_CUDA_ARCHITECTURES_ALL 110)
|
||||
list(REMOVE_ITEM CMAKE_CUDA_ARCHITECTURES_ALL_MAJOR 110)
|
||||
endif()
|
||||
|
||||
else()
|
||||
# Initial set based on CUDA 7.0.
|
||||
set(CMAKE_CUDA_ARCHITECTURES_ALL 20 21 30 35 37 50 52 53)
|
||||
|
||||
@@ -2838,19 +2838,40 @@ void cmGeneratorTarget::AddCUDAArchitectureFlagsImpl(cmBuildStep compileOrLink,
|
||||
flags += "]\"";
|
||||
}
|
||||
} else if (compiler == "Clang" && compileOrLink == cmBuildStep::Compile) {
|
||||
for (CudaArchitecture& architecture : architectures) {
|
||||
flags =
|
||||
cmStrCat(std::move(flags), " --cuda-gpu-arch=sm_", architecture.name);
|
||||
if (cmSystemTools::VersionCompare(cmSystemTools::OP_GREATER_EQUAL,
|
||||
this->Makefile->GetDefinition(cmStrCat(
|
||||
"CMAKE_", lang, "_COMPILER_VERSION")),
|
||||
"20.0")) {
|
||||
for (CudaArchitecture& architecture : architectures) {
|
||||
flags =
|
||||
cmStrCat(std::move(flags), " --offload-arch=sm_", architecture.name);
|
||||
|
||||
if (!architecture.real) {
|
||||
this->Makefile->IssueMessage(
|
||||
MessageType::WARNING,
|
||||
"Clang doesn't support disabling CUDA real code generation.");
|
||||
if (!architecture.real) {
|
||||
this->Makefile->IssueMessage(
|
||||
MessageType::WARNING,
|
||||
"Clang doesn't support disabling CUDA real code generation.");
|
||||
}
|
||||
|
||||
if (architecture.virtual_) {
|
||||
flags = cmStrCat(std::move(flags), " --cuda-include-ptx=sm_",
|
||||
architecture.name);
|
||||
}
|
||||
}
|
||||
|
||||
if (!architecture.virtual_) {
|
||||
flags = cmStrCat(std::move(flags), " --no-cuda-include-ptx=sm_",
|
||||
} else {
|
||||
for (CudaArchitecture& architecture : architectures) {
|
||||
flags = cmStrCat(std::move(flags), " --cuda-gpu-arch=sm_",
|
||||
architecture.name);
|
||||
|
||||
if (!architecture.real) {
|
||||
this->Makefile->IssueMessage(
|
||||
MessageType::WARNING,
|
||||
"Clang doesn't support disabling CUDA real code generation.");
|
||||
}
|
||||
|
||||
if (!architecture.virtual_) {
|
||||
flags = cmStrCat(std::move(flags), " --no-cuda-include-ptx=sm_",
|
||||
architecture.name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,7 +9,8 @@ add_cuda_test_macro(Cuda.ObjectLibrary CudaObjectLibrary)
|
||||
add_cuda_test_macro(Cuda.MixedStandardLevels1 MixedStandardLevels1)
|
||||
add_cuda_test_macro(Cuda.MixedStandardLevels2 MixedStandardLevels2)
|
||||
add_cuda_test_macro(Cuda.MixedStandardLevels3 MixedStandardLevels3)
|
||||
if(NOT WIN32 OR NOT CMake_TEST_CUDA STREQUAL "Clang") # MSVC std lib needs C++14
|
||||
if(NOT WIN32 AND CMake_TEST_CUDA STREQUAL "NVIDIA")
|
||||
# MSVC std lib, and newer clang needs C++14
|
||||
add_cuda_test_macro(Cuda.MixedStandardLevels4 MixedStandardLevels4)
|
||||
add_cuda_test_macro(Cuda.MixedStandardLevels5 MixedStandardLevels5)
|
||||
endif()
|
||||
|
||||
@@ -13,7 +13,8 @@ add_cuda_test_macro(CudaOnly.EnableStandard CudaOnlyEnableStandard)
|
||||
add_cuda_test_macro(CudaOnly.ExportPTX CudaOnlyExportPTX)
|
||||
add_cuda_test_macro(CudaOnly.SharedRuntimePlusToolkit CudaOnlySharedRuntimePlusToolkit)
|
||||
add_cuda_test_macro(CudaOnly.StaticRuntimePlusToolkit CudaOnlyStaticRuntimePlusToolkit)
|
||||
if(NOT WIN32 OR NOT CMake_TEST_CUDA STREQUAL "Clang") # MSVC std lib needs C++14
|
||||
if(NOT WIN32 AND CMake_TEST_CUDA STREQUAL "NVIDIA")
|
||||
# MSVC std lib, and newer clang needs C++14
|
||||
add_cuda_test_macro(CudaOnly.Standard98 CudaOnlyStandard98)
|
||||
endif()
|
||||
set(CudaOnly.Toolkit_BUILD_OPTIONS -DHAS_CUPTI:BOOL=${CMake_TEST_CUDA_CUPTI})
|
||||
@@ -24,12 +25,13 @@ add_cuda_test_macro(CudaOnly.TryCompileTargetStatic CudaOnlyTryCompileTargetStat
|
||||
add_cuda_test_macro(CudaOnly.Unity CudaOnlyUnity)
|
||||
add_cuda_test_macro(CudaOnly.WithDefs CudaOnlyWithDefs)
|
||||
add_cuda_test_macro(CudaOnly.CircularLinkLine CudaOnlyCircularLinkLine)
|
||||
add_cuda_test_macro(CudaOnly.ResolveDeviceSymbols CudaOnlyResolveDeviceSymbols)
|
||||
add_cuda_test_macro(CudaOnly.SeparateCompilation main/CudaOnlySeparateCompilation)
|
||||
add_cuda_test_macro(CudaOnly.SeparateCompilationPTX CudaOnlySeparateCompilationPTX)
|
||||
add_cuda_test_macro(CudaOnly.SeparateCompilationTargetObjects CudaOnlySeparateCompilationTargetObjects)
|
||||
|
||||
if(CMake_TEST_CUDA AND NOT CMake_TEST_CUDA STREQUAL "Clang")
|
||||
add_cuda_test_macro(CudaOnly.ResolveDeviceSymbols CudaOnlyResolveDeviceSymbols)
|
||||
|
||||
# Clang doesn't have flags for selecting the runtime.
|
||||
add_cuda_test_macro(CudaOnly.SharedRuntimeViaCUDAFlags CudaOnlySharedRuntimeViaCUDAFlags)
|
||||
|
||||
|
||||
@@ -4,6 +4,13 @@
|
||||
|
||||
#include "embedded_objs.h"
|
||||
|
||||
#if defined(CUDA_VERSION) && \
|
||||
CUDA_VERSION >= 13000 // get version from cuda.h header (clang cuda)
|
||||
# define CUDA_13_OR_GREATER
|
||||
#elif defined(__CUDACC_VER_MAJOR__) && \
|
||||
__CUDACC_VER_MAJOR__ >= 13 // get version from nvcc compiler defines
|
||||
# define CUDA_13_OR_GREATER
|
||||
#endif
|
||||
int main()
|
||||
{
|
||||
cuInit(0);
|
||||
@@ -18,7 +25,7 @@ int main()
|
||||
cuDeviceGet(&device, 0);
|
||||
|
||||
CUcontext context;
|
||||
#if defined(__CUDACC_VER_MAJOR__) && __CUDACC_VER_MAJOR__ >= 13
|
||||
#if defined(CUDA_13_OR_GREATER)
|
||||
CUctxCreateParams params = {};
|
||||
params.execAffinityParams = nullptr;
|
||||
params.numExecAffinityParams = 0;
|
||||
|
||||
@@ -61,14 +61,19 @@ if (NOT CMAKE_C_COMPILER_ID STREQUAL "Intel")
|
||||
run_cmake_target(genex_LINK_LANG_AND_ID exe LinkOptions_exe --config Release)
|
||||
|
||||
run_cmake(genex_DEVICE_LINK)
|
||||
if (CMake_TEST_CUDA)
|
||||
include("${RunCMake_BINARY_DIR}/genex_DEVICE_LINK-build/info.cmake" OPTIONAL)
|
||||
endif()
|
||||
|
||||
run_cmake_target(genex_DEVICE_LINK interface LinkOptions_shared_interface --config Release)
|
||||
run_cmake_target(genex_DEVICE_LINK private LinkOptions_private --config Release)
|
||||
if (CMake_TEST_CUDA)
|
||||
run_cmake_target(genex_DEVICE_LINK CMP0105_UNSET LinkOptions_CMP0105_UNSET --config Release)
|
||||
run_cmake_target(genex_DEVICE_LINK CMP0105_OLD LinkOptions_CMP0105_OLD --config Release)
|
||||
run_cmake_target(genex_DEVICE_LINK CMP0105_NEW LinkOptions_CMP0105_NEW --config Release)
|
||||
run_cmake_target(genex_DEVICE_LINK device LinkOptions_device --config Release)
|
||||
if (CMAKE_CUDA_COMPILER_HAS_DEVICE_LINK_PHASE)
|
||||
run_cmake_target(genex_DEVICE_LINK CMP0105_NEW LinkOptions_CMP0105_NEW --config Release)
|
||||
run_cmake_target(genex_DEVICE_LINK device LinkOptions_device --config Release)
|
||||
endif()
|
||||
|
||||
if (RunCMake_GENERATOR MATCHES "(Ninja|Unix Makefiles)")
|
||||
run_cmake_target(genex_DEVICE_LINK host_link_options LinkOptions_host_link_options --config Release ${VERBOSE})
|
||||
|
||||
@@ -36,7 +36,6 @@ if (CMake_TEST_CUDA)
|
||||
target_link_options(LinkOptions_CMP0105_OLD PRIVATE $<DEVICE_LINK:${pre}BADFLAG_DEVICE_LINK${obj}>)
|
||||
|
||||
cmake_policy(SET CMP0105 NEW)
|
||||
|
||||
add_executable(LinkOptions_CMP0105_NEW LinkOptionsDevice.cu)
|
||||
set_property(TARGET LinkOptions_CMP0105_NEW PROPERTY CUDA_SEPARABLE_COMPILATION ON)
|
||||
target_link_options(LinkOptions_CMP0105_NEW PRIVATE $<DEVICE_LINK:${pre}BADFLAG_DEVICE_LINK${obj}>)
|
||||
@@ -45,7 +44,6 @@ if (CMake_TEST_CUDA)
|
||||
set_property(TARGET LinkOptions_device PROPERTY CUDA_SEPARABLE_COMPILATION ON)
|
||||
target_link_options(LinkOptions_device PRIVATE $<DEVICE_LINK:${pre}BADFLAG_DEVICE_LINK${obj}>
|
||||
$<HOST_LINK:${pre}BADFLAG_NORMAL_LINK${obj}>)
|
||||
|
||||
add_executable(LinkOptions_host_link_options LinkOptionsDevice.cu)
|
||||
set_property(TARGET LinkOptions_host_link_options PROPERTY CUDA_SEPARABLE_COMPILATION ON)
|
||||
if(CMake_TEST_CUDA STREQUAL "NVIDIA")
|
||||
@@ -57,4 +55,8 @@ if (CMake_TEST_CUDA)
|
||||
add_executable(LinkOptions_no_device LinkOptionsDevice.cu)
|
||||
target_link_options(LinkOptions_no_device PRIVATE $<DEVICE_LINK:${pre}BADFLAG_DEVICE_LINK${obj}>
|
||||
$<HOST_LINK:${pre}BADFLAG_NORMAL_LINK${obj}>)
|
||||
|
||||
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/info.cmake"
|
||||
"set(CMAKE_CUDA_COMPILER_HAS_DEVICE_LINK_PHASE \"${CMAKE_CUDA_COMPILER_HAS_DEVICE_LINK_PHASE}\")\n"
|
||||
)
|
||||
endif()
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
^CMake Error at .*/Tests/RunCMake/try_compile/CudaStandard-build/CMakeFiles/CMake(Tmp|Scratch/TryCompile-[^/]+)/CMakeLists\.txt:[0-9]+ \(add_executable\):
|
||||
^CMake Error at .*/Tests/RunCMake/try_compile/CudaStandard-build/CMakeFiles/CMake(Tmp|Scratch/TryCompile-[^/]+)/CMakeLists\.txt:[0-9]+ \(.*\):
|
||||
CUDA_STANDARD is set to invalid value '4'
|
||||
+
|
||||
CMake Error at CudaStandard\.cmake:[0-9]+ \(try_compile\):
|
||||
|
||||
Reference in New Issue
Block a user