Skip to content

Commit 8fa28a0

Browse files
committed
[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
1 parent 4399878 commit 8fa28a0

File tree

6 files changed

+104
-6
lines changed

6 files changed

+104
-6
lines changed

clang/include/clang/Basic/Cuda.h

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
namespace llvm {
1313
class StringRef;
14+
class VersionTuple;
1415
} // namespace llvm
1516

1617
namespace clang {
@@ -27,9 +28,8 @@ enum class CudaVersion {
2728
LATEST = CUDA_100,
2829
};
2930
const char *CudaVersionToString(CudaVersion V);
30-
31-
// No string -> CudaVersion conversion function because there's no canonical
32-
// spelling of the various CUDA versions.
31+
// Input is "Major.Minor"
32+
CudaVersion CudaStringToVersion(llvm::StringRef S);
3333

3434
enum class CudaArch {
3535
UNKNOWN,
@@ -103,6 +103,15 @@ CudaVersion MinVersionForCudaArch(CudaArch A);
103103
/// Get the latest CudaVersion that supports the given CudaArch.
104104
CudaVersion MaxVersionForCudaArch(CudaArch A);
105105

106+
// Various SDK-dependent features that affect CUDA compilation
107+
enum class CudaFeature {
108+
// CUDA-9.2+ uses a new API for launching kernels.
109+
CUDA_USES_NEW_LAUNCH,
110+
};
111+
112+
bool CudaFeatureEnabled(llvm::VersionTuple, CudaFeature);
113+
bool CudaFeatureEnabled(CudaVersion, CudaFeature);
114+
106115
} // namespace clang
107116

108117
#endif

clang/include/clang/Basic/TargetOptions.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,11 @@ class TargetOptions {
7575
std::string CodeModel;
7676

7777
/// The version of the SDK which was used during the compilation.
78+
/// The option is used for two different purposes:
79+
/// * on darwin the version is propagated to LLVM where it's used
80+
/// to support SDK Version metadata (See D55673).
81+
/// * CUDA compilation uses it to control parts of CUDA compilation
82+
/// in clang that depend on specific version of the CUDA SDK.
7883
llvm::VersionTuple SDKVersion;
7984
};
8085

clang/lib/Basic/Cuda.cpp

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#include "llvm/ADT/StringRef.h"
44
#include "llvm/ADT/StringSwitch.h"
55
#include "llvm/Support/ErrorHandling.h"
6+
#include "llvm/Support/VersionTuple.h"
67

78
namespace clang {
89

@@ -28,6 +29,17 @@ const char *CudaVersionToString(CudaVersion V) {
2829
llvm_unreachable("invalid enum");
2930
}
3031

32+
CudaVersion CudaStringToVersion(llvm::StringRef S) {
33+
return llvm::StringSwitch<CudaVersion>(S)
34+
.Case("7.0", CudaVersion::CUDA_70)
35+
.Case("7.5", CudaVersion::CUDA_75)
36+
.Case("8.0", CudaVersion::CUDA_80)
37+
.Case("9.0", CudaVersion::CUDA_90)
38+
.Case("9.1", CudaVersion::CUDA_91)
39+
.Case("9.2", CudaVersion::CUDA_92)
40+
.Case("10.0", CudaVersion::CUDA_100);
41+
}
42+
3143
const char *CudaArchToString(CudaArch A) {
3244
switch (A) {
3345
case CudaArch::LAST:
@@ -322,4 +334,38 @@ CudaVersion MaxVersionForCudaArch(CudaArch A) {
322334
}
323335
}
324336

337+
static CudaVersion ToCudaVersion(llvm::VersionTuple Version) {
338+
int IVer =
339+
Version.getMajor() * 10 + Version.getMinor().getValueOr(0);
340+
switch(IVer) {
341+
case 70:
342+
return CudaVersion::CUDA_70;
343+
case 75:
344+
return CudaVersion::CUDA_75;
345+
case 80:
346+
return CudaVersion::CUDA_80;
347+
case 90:
348+
return CudaVersion::CUDA_90;
349+
case 91:
350+
return CudaVersion::CUDA_91;
351+
case 92:
352+
return CudaVersion::CUDA_92;
353+
case 100:
354+
return CudaVersion::CUDA_100;
355+
default:
356+
return CudaVersion::UNKNOWN;
357+
}
358+
}
359+
360+
bool CudaFeatureEnabled(llvm::VersionTuple Version, CudaFeature Feature) {
361+
return CudaFeatureEnabled(ToCudaVersion(Version), Feature);
362+
}
363+
364+
bool CudaFeatureEnabled(CudaVersion Version, CudaFeature Feature) {
365+
switch (Feature) {
366+
case CudaFeature::CUDA_USES_NEW_LAUNCH:
367+
return Version >= CudaVersion::CUDA_92;
368+
}
369+
llvm_unreachable("Unknown CUDA feature.");
370+
}
325371
} // namespace clang

clang/lib/Driver/ToolChains/Clang.cpp

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3464,13 +3464,25 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
34643464
NormalizedTriple = C.getSingleOffloadToolChain<Action::OFK_Host>()
34653465
->getTriple()
34663466
.normalize();
3467-
else
3467+
else {
3468+
// Host-side compilation.
34683469
NormalizedTriple =
34693470
(IsCuda ? C.getSingleOffloadToolChain<Action::OFK_Cuda>()
34703471
: C.getSingleOffloadToolChain<Action::OFK_HIP>())
34713472
->getTriple()
34723473
.normalize();
3473-
3474+
if (IsCuda) {
3475+
// We need to figure out which CUDA version we're compiling for, as that
3476+
// determines how we load and launch GPU kernels.
3477+
auto *CTC = static_cast<const toolchains::CudaToolChain *>(
3478+
C.getSingleOffloadToolChain<Action::OFK_Cuda>());
3479+
assert(CTC && "Expected valid CUDA Toolchain.");
3480+
if (CTC && CTC->CudaInstallation.version() != CudaVersion::UNKNOWN)
3481+
CmdArgs.push_back(Args.MakeArgString(
3482+
Twine("-target-sdk-version=") +
3483+
CudaVersionToString(CTC->CudaInstallation.version())));
3484+
}
3485+
}
34743486
CmdArgs.push_back("-aux-triple");
34753487
CmdArgs.push_back(Args.MakeArgString(NormalizedTriple));
34763488
}

clang/lib/Driver/ToolChains/Cuda.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -661,9 +661,13 @@ void CudaToolChain::addClangTargetOptions(
661661
options::OPT_fno_cuda_short_ptr, false))
662662
CC1Args.append({"-mllvm", "--nvptx-short-ptr"});
663663

664+
if (CudaInstallation.version() >= CudaVersion::UNKNOWN)
665+
CC1Args.push_back(DriverArgs.MakeArgString(
666+
Twine("-target-sdk-version=") +
667+
CudaVersionToString(CudaInstallation.version())));
668+
664669
if (DeviceOffloadingKind == Action::OFK_OpenMP) {
665670
SmallVector<StringRef, 8> LibraryPaths;
666-
667671
if (const Arg *A = DriverArgs.getLastArg(options::OPT_libomptarget_nvptx_path_EQ))
668672
LibraryPaths.push_back(A->getValue());
669673

clang/test/Driver/cuda-detect.cu

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,16 @@
137137
// RUN: --gcc-toolchain="" 2>&1 \
138138
// RUN: | FileCheck %s --check-prefix CHECK-CXXINCLUDE
139139

140+
// Verify that CUDA SDK version is propagated to the CC1 compilations.
141+
// RUN: %clang -### -v -target x86_64-linux-gnu --cuda-gpu-arch=sm_50 \
142+
// RUN: --cuda-path=%S/Inputs/CUDA_80/usr/local/cuda %s 2>&1 \
143+
// RUN: | FileCheck %s -check-prefix CUDA80
144+
145+
// Verify that if no version file is found, we report the default of 7.0.
146+
// RUN: %clang -### -v -target x86_64-linux-gnu --cuda-gpu-arch=sm_50 \
147+
// RUN: --cuda-path=%S/Inputs/CUDA/usr/local/cuda %s 2>&1 \
148+
// RUN: | FileCheck %s -check-prefix CUDA70
149+
140150
// CHECK: Found CUDA installation: {{.*}}/Inputs/CUDA/usr/local/cuda
141151
// NO-LIBDEVICE: Found CUDA installation: {{.*}}/Inputs/CUDA-nolibdevice/usr/local/cuda
142152
// NOCUDA-NOT: Found CUDA installation:
@@ -167,3 +177,15 @@
167177
// CHECK-CXXINCLUDE: clang{{.*}} "-cc1" "-triple" "x86_64-unknown-linux-gnu"
168178
// CHECK-CXXINCLUDE-SAME: {{.*}}"-internal-isystem" "{{.+}}/include/c++/4.8"
169179
// CHECK-CXXINCLUDE: ld{{.*}}"
180+
181+
// CUDA80: clang{{.*}} "-cc1" "-triple" "nvptx64-nvidia-cuda"
182+
// CUDA80-SAME: -target-sdk-version=8.0
183+
// CUDA80: clang{{.*}} "-cc1" "-triple" "x86_64-unknown-linux-gnu"
184+
// CUDA80-SAME: -target-sdk-version=8.0
185+
// CUDA80: ld{{.*}}"
186+
187+
// CUDA70: clang{{.*}} "-cc1" "-triple" "nvptx64-nvidia-cuda"
188+
// CUDA70-SAME: -target-sdk-version=7.0
189+
// CUDA70: clang{{.*}} "-cc1" "-triple" "x86_64-unknown-linux-gnu"
190+
// CUDA70-SAME: -target-sdk-version=7.0
191+
// CUDA70: ld{{.*}}"

0 commit comments

Comments
 (0)