diff options
author | Artem Belevich <tra@google.com> | 2019-01-31 21:32:24 +0000 |
---|---|---|
committer | Artem Belevich <tra@google.com> | 2019-01-31 21:32:24 +0000 |
commit | 8fa28a0db058eb53970f7eca3aaf71c86357e478 (patch) | |
tree | 7f593cf811fcdfc58944847184d49d07f59e085c | |
parent | 4399878082518815a6e6f070a25fcc18340633df (diff) | |
download | bcm5719-llvm-8fa28a0db058eb53970f7eca3aaf71c86357e478.tar.gz bcm5719-llvm-8fa28a0db058eb53970f7eca3aaf71c86357e478.zip |
[CUDA] Propagate detected version of CUDA to cc1
..and use it to control that parts of CUDA compilation
that depend on the specific version of CUDA SDK.
This patch has a placeholder for a 'new launch API' support
which is in a separate patch. The list will be further
extended in the upcoming patch to support CUDA-10.1.
Differential Revision: https://reviews.llvm.org/D57487
llvm-svn: 352798
-rw-r--r-- | clang/include/clang/Basic/Cuda.h | 15 | ||||
-rw-r--r-- | clang/include/clang/Basic/TargetOptions.h | 5 | ||||
-rw-r--r-- | clang/lib/Basic/Cuda.cpp | 46 | ||||
-rw-r--r-- | clang/lib/Driver/ToolChains/Clang.cpp | 16 | ||||
-rw-r--r-- | clang/lib/Driver/ToolChains/Cuda.cpp | 6 | ||||
-rw-r--r-- | clang/test/Driver/cuda-detect.cu | 22 |
6 files changed, 104 insertions, 6 deletions
diff --git a/clang/include/clang/Basic/Cuda.h b/clang/include/clang/Basic/Cuda.h index 7c8ca8da42f..532c23098ee 100644 --- a/clang/include/clang/Basic/Cuda.h +++ b/clang/include/clang/Basic/Cuda.h @@ -11,6 +11,7 @@ namespace llvm { class StringRef; +class VersionTuple; } // namespace llvm namespace clang { @@ -27,9 +28,8 @@ enum class CudaVersion { LATEST = CUDA_100, }; const char *CudaVersionToString(CudaVersion V); - -// No string -> CudaVersion conversion function because there's no canonical -// spelling of the various CUDA versions. +// Input is "Major.Minor" +CudaVersion CudaStringToVersion(llvm::StringRef S); enum class CudaArch { UNKNOWN, @@ -103,6 +103,15 @@ CudaVersion MinVersionForCudaArch(CudaArch A); /// Get the latest CudaVersion that supports the given CudaArch. CudaVersion MaxVersionForCudaArch(CudaArch A); +// Various SDK-dependent features that affect CUDA compilation +enum class CudaFeature { + // CUDA-9.2+ uses a new API for launching kernels. + CUDA_USES_NEW_LAUNCH, +}; + +bool CudaFeatureEnabled(llvm::VersionTuple, CudaFeature); +bool CudaFeatureEnabled(CudaVersion, CudaFeature); + } // namespace clang #endif diff --git a/clang/include/clang/Basic/TargetOptions.h b/clang/include/clang/Basic/TargetOptions.h index 45ecda1c2f9..bbe86aebb07 100644 --- a/clang/include/clang/Basic/TargetOptions.h +++ b/clang/include/clang/Basic/TargetOptions.h @@ -75,6 +75,11 @@ public: std::string CodeModel; /// The version of the SDK which was used during the compilation. + /// The option is used for two different purposes: + /// * on darwin the version is propagated to LLVM where it's used + /// to support SDK Version metadata (See D55673). + /// * CUDA compilation uses it to control parts of CUDA compilation + /// in clang that depend on specific version of the CUDA SDK. llvm::VersionTuple SDKVersion; }; diff --git a/clang/lib/Basic/Cuda.cpp b/clang/lib/Basic/Cuda.cpp index 6c34856dfdf..6ba9a8437e2 100644 --- a/clang/lib/Basic/Cuda.cpp +++ b/clang/lib/Basic/Cuda.cpp @@ -3,6 +3,7 @@ #include "llvm/ADT/StringRef.h" #include "llvm/ADT/StringSwitch.h" #include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/VersionTuple.h" namespace clang { @@ -28,6 +29,17 @@ const char *CudaVersionToString(CudaVersion V) { llvm_unreachable("invalid enum"); } +CudaVersion CudaStringToVersion(llvm::StringRef S) { + return llvm::StringSwitch<CudaVersion>(S) + .Case("7.0", CudaVersion::CUDA_70) + .Case("7.5", CudaVersion::CUDA_75) + .Case("8.0", CudaVersion::CUDA_80) + .Case("9.0", CudaVersion::CUDA_90) + .Case("9.1", CudaVersion::CUDA_91) + .Case("9.2", CudaVersion::CUDA_92) + .Case("10.0", CudaVersion::CUDA_100); +} + const char *CudaArchToString(CudaArch A) { switch (A) { case CudaArch::LAST: @@ -322,4 +334,38 @@ CudaVersion MaxVersionForCudaArch(CudaArch A) { } } +static CudaVersion ToCudaVersion(llvm::VersionTuple Version) { + int IVer = + Version.getMajor() * 10 + Version.getMinor().getValueOr(0); + switch(IVer) { + case 70: + return CudaVersion::CUDA_70; + case 75: + return CudaVersion::CUDA_75; + case 80: + return CudaVersion::CUDA_80; + case 90: + return CudaVersion::CUDA_90; + case 91: + return CudaVersion::CUDA_91; + case 92: + return CudaVersion::CUDA_92; + case 100: + return CudaVersion::CUDA_100; + default: + return CudaVersion::UNKNOWN; + } +} + +bool CudaFeatureEnabled(llvm::VersionTuple Version, CudaFeature Feature) { + return CudaFeatureEnabled(ToCudaVersion(Version), Feature); +} + +bool CudaFeatureEnabled(CudaVersion Version, CudaFeature Feature) { + switch (Feature) { + case CudaFeature::CUDA_USES_NEW_LAUNCH: + return Version >= CudaVersion::CUDA_92; + } + llvm_unreachable("Unknown CUDA feature."); +} } // namespace clang diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index 2b668f76b58..c02446bcd5e 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -3464,13 +3464,25 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, NormalizedTriple = C.getSingleOffloadToolChain<Action::OFK_Host>() ->getTriple() .normalize(); - else + else { + // Host-side compilation. NormalizedTriple = (IsCuda ? C.getSingleOffloadToolChain<Action::OFK_Cuda>() : C.getSingleOffloadToolChain<Action::OFK_HIP>()) ->getTriple() .normalize(); - + if (IsCuda) { + // We need to figure out which CUDA version we're compiling for, as that + // determines how we load and launch GPU kernels. + auto *CTC = static_cast<const toolchains::CudaToolChain *>( + C.getSingleOffloadToolChain<Action::OFK_Cuda>()); + assert(CTC && "Expected valid CUDA Toolchain."); + if (CTC && CTC->CudaInstallation.version() != CudaVersion::UNKNOWN) + CmdArgs.push_back(Args.MakeArgString( + Twine("-target-sdk-version=") + + CudaVersionToString(CTC->CudaInstallation.version()))); + } + } CmdArgs.push_back("-aux-triple"); CmdArgs.push_back(Args.MakeArgString(NormalizedTriple)); } diff --git a/clang/lib/Driver/ToolChains/Cuda.cpp b/clang/lib/Driver/ToolChains/Cuda.cpp index 119c9fcd0d9..e3fe84b1018 100644 --- a/clang/lib/Driver/ToolChains/Cuda.cpp +++ b/clang/lib/Driver/ToolChains/Cuda.cpp @@ -661,9 +661,13 @@ void CudaToolChain::addClangTargetOptions( options::OPT_fno_cuda_short_ptr, false)) CC1Args.append({"-mllvm", "--nvptx-short-ptr"}); + if (CudaInstallation.version() >= CudaVersion::UNKNOWN) + CC1Args.push_back(DriverArgs.MakeArgString( + Twine("-target-sdk-version=") + + CudaVersionToString(CudaInstallation.version()))); + if (DeviceOffloadingKind == Action::OFK_OpenMP) { SmallVector<StringRef, 8> LibraryPaths; - if (const Arg *A = DriverArgs.getLastArg(options::OPT_libomptarget_nvptx_path_EQ)) LibraryPaths.push_back(A->getValue()); diff --git a/clang/test/Driver/cuda-detect.cu b/clang/test/Driver/cuda-detect.cu index e5dfe36571a..7fff62c123b 100644 --- a/clang/test/Driver/cuda-detect.cu +++ b/clang/test/Driver/cuda-detect.cu @@ -137,6 +137,16 @@ // RUN: --gcc-toolchain="" 2>&1 \ // RUN: | FileCheck %s --check-prefix CHECK-CXXINCLUDE +// Verify that CUDA SDK version is propagated to the CC1 compilations. +// RUN: %clang -### -v -target x86_64-linux-gnu --cuda-gpu-arch=sm_50 \ +// RUN: --cuda-path=%S/Inputs/CUDA_80/usr/local/cuda %s 2>&1 \ +// RUN: | FileCheck %s -check-prefix CUDA80 + +// Verify that if no version file is found, we report the default of 7.0. +// RUN: %clang -### -v -target x86_64-linux-gnu --cuda-gpu-arch=sm_50 \ +// RUN: --cuda-path=%S/Inputs/CUDA/usr/local/cuda %s 2>&1 \ +// RUN: | FileCheck %s -check-prefix CUDA70 + // CHECK: Found CUDA installation: {{.*}}/Inputs/CUDA/usr/local/cuda // NO-LIBDEVICE: Found CUDA installation: {{.*}}/Inputs/CUDA-nolibdevice/usr/local/cuda // NOCUDA-NOT: Found CUDA installation: @@ -167,3 +177,15 @@ // CHECK-CXXINCLUDE: clang{{.*}} "-cc1" "-triple" "x86_64-unknown-linux-gnu" // CHECK-CXXINCLUDE-SAME: {{.*}}"-internal-isystem" "{{.+}}/include/c++/4.8" // CHECK-CXXINCLUDE: ld{{.*}}" + +// CUDA80: clang{{.*}} "-cc1" "-triple" "nvptx64-nvidia-cuda" +// CUDA80-SAME: -target-sdk-version=8.0 +// CUDA80: clang{{.*}} "-cc1" "-triple" "x86_64-unknown-linux-gnu" +// CUDA80-SAME: -target-sdk-version=8.0 +// CUDA80: ld{{.*}}" + +// CUDA70: clang{{.*}} "-cc1" "-triple" "nvptx64-nvidia-cuda" +// CUDA70-SAME: -target-sdk-version=7.0 +// CUDA70: clang{{.*}} "-cc1" "-triple" "x86_64-unknown-linux-gnu" +// CUDA70-SAME: -target-sdk-version=7.0 +// CUDA70: ld{{.*}}" |