Skip to content

Commit 12fefee

Browse files
committed
[CUDA] Assume the latest known CUDA version if we've found an unknown one.
This makes clang somewhat forward-compatible with new CUDA releases without having to patch it for every minor release without adding any new function. If an unknown version is found, clang issues a warning (can be disabled with -Wno-cuda-unknown-version) and assumes that it has detected the latest known version. CUDA releases are usually supersets of older ones feature-wise, so it should be sufficient to keep released clang versions working with minor CUDA updates without having to upgrade clang, too. Differential Revision: https://reviews.llvm.org/D73231
1 parent 66e47a5 commit 12fefee

File tree

13 files changed

+34
-33
lines changed

13 files changed

+34
-33
lines changed

clang/include/clang/Basic/Cuda.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

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

@@ -30,7 +31,7 @@ enum class CudaVersion {
3031
};
3132
const char *CudaVersionToString(CudaVersion V);
3233
// Input is "Major.Minor"
33-
CudaVersion CudaStringToVersion(llvm::StringRef S);
34+
CudaVersion CudaStringToVersion(const llvm::Twine &S);
3435

3536
enum class CudaArch {
3637
UNKNOWN,

clang/include/clang/Basic/DiagnosticDriverKinds.td

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,9 @@ def err_drv_cuda_version_unsupported : Error<
6060
"but installation at %3 is %4. Use --cuda-path to specify a different CUDA "
6161
"install, pass a different GPU arch with --cuda-gpu-arch, or pass "
6262
"--no-cuda-version-check.">;
63+
def warn_drv_unknown_cuda_version: Warning<
64+
"Unknown CUDA version %0. Assuming the latest supported version %1">,
65+
InGroup<CudaUnknownVersion>;
6366
def err_drv_cuda_host_arch : Error<"unsupported architecture '%0' for host compilation.">;
6467
def err_drv_mix_cuda_hip : Error<"Mixed Cuda and HIP compilation is not supported.">;
6568
def err_drv_invalid_thread_model_for_target : Error<

clang/include/clang/Basic/DiagnosticGroups.td

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1113,6 +1113,9 @@ def SerializedDiagnostics : DiagGroup<"serialized-diagnostics">;
11131113
// compiling CUDA C/C++ but which is not compatible with the CUDA spec.
11141114
def CudaCompat : DiagGroup<"cuda-compat">;
11151115

1116+
// Warning about unknown CUDA SDK version.
1117+
def CudaUnknownVersion: DiagGroup<"unknown-cuda-version">;
1118+
11161119
// A warning group for warnings about features supported by HIP but
11171120
// ignored by CUDA.
11181121
def HIPOnly : DiagGroup<"hip-only">;

clang/lib/Basic/Cuda.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
#include "llvm/ADT/StringRef.h"
44
#include "llvm/ADT/StringSwitch.h"
5+
#include "llvm/ADT/Twine.h"
56
#include "llvm/Support/ErrorHandling.h"
67
#include "llvm/Support/VersionTuple.h"
78

@@ -31,16 +32,17 @@ const char *CudaVersionToString(CudaVersion V) {
3132
llvm_unreachable("invalid enum");
3233
}
3334

34-
CudaVersion CudaStringToVersion(llvm::StringRef S) {
35-
return llvm::StringSwitch<CudaVersion>(S)
35+
CudaVersion CudaStringToVersion(const llvm::Twine &S) {
36+
return llvm::StringSwitch<CudaVersion>(S.str())
3637
.Case("7.0", CudaVersion::CUDA_70)
3738
.Case("7.5", CudaVersion::CUDA_75)
3839
.Case("8.0", CudaVersion::CUDA_80)
3940
.Case("9.0", CudaVersion::CUDA_90)
4041
.Case("9.1", CudaVersion::CUDA_91)
4142
.Case("9.2", CudaVersion::CUDA_92)
4243
.Case("10.0", CudaVersion::CUDA_100)
43-
.Case("10.1", CudaVersion::CUDA_101);
44+
.Case("10.1", CudaVersion::CUDA_101)
45+
.Default(CudaVersion::UNKNOWN);
4446
}
4547

4648
const char *CudaArchToString(CudaArch A) {

clang/lib/Driver/ToolChains/Cuda.cpp

Lines changed: 15 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -33,37 +33,24 @@ using namespace llvm::opt;
3333

3434
// Parses the contents of version.txt in an CUDA installation. It should
3535
// contain one line of the from e.g. "CUDA Version 7.5.2".
36-
static CudaVersion ParseCudaVersionFile(llvm::StringRef V) {
36+
static CudaVersion ParseCudaVersionFile(const Driver &D, llvm::StringRef V) {
3737
if (!V.startswith("CUDA Version "))
3838
return CudaVersion::UNKNOWN;
3939
V = V.substr(strlen("CUDA Version "));
40-
int Major = -1, Minor = -1;
41-
auto First = V.split('.');
42-
auto Second = First.second.split('.');
43-
if (First.first.getAsInteger(10, Major) ||
44-
Second.first.getAsInteger(10, Minor))
40+
SmallVector<StringRef,4> VersionParts;
41+
V.split(VersionParts, '.');
42+
if (VersionParts.size() < 2)
4543
return CudaVersion::UNKNOWN;
46-
47-
if (Major == 7 && Minor == 0) {
48-
// This doesn't appear to ever happen -- version.txt doesn't exist in the
49-
// CUDA 7 installs I've seen. But no harm in checking.
50-
return CudaVersion::CUDA_70;
51-
}
52-
if (Major == 7 && Minor == 5)
53-
return CudaVersion::CUDA_75;
54-
if (Major == 8 && Minor == 0)
55-
return CudaVersion::CUDA_80;
56-
if (Major == 9 && Minor == 0)
57-
return CudaVersion::CUDA_90;
58-
if (Major == 9 && Minor == 1)
59-
return CudaVersion::CUDA_91;
60-
if (Major == 9 && Minor == 2)
61-
return CudaVersion::CUDA_92;
62-
if (Major == 10 && Minor == 0)
63-
return CudaVersion::CUDA_100;
64-
if (Major == 10 && Minor == 1)
65-
return CudaVersion::CUDA_101;
66-
return CudaVersion::UNKNOWN;
44+
std::string MajorMinor = join_items(".", VersionParts[0], VersionParts[1]);
45+
CudaVersion Version = CudaStringToVersion(MajorMinor);
46+
if (Version != CudaVersion::UNKNOWN)
47+
return Version;
48+
49+
// Issue a warning and assume that the version we've found is compatible with
50+
// the latest version we support.
51+
D.Diag(diag::warn_drv_unknown_cuda_version)
52+
<< MajorMinor << CudaVersionToString(CudaVersion::LATEST);
53+
return CudaVersion::LATEST;
6754
}
6855

6956
CudaInstallationDetector::CudaInstallationDetector(
@@ -161,7 +148,7 @@ CudaInstallationDetector::CudaInstallationDetector(
161148
// version.txt isn't present.
162149
Version = CudaVersion::CUDA_70;
163150
} else {
164-
Version = ParseCudaVersionFile((*VersionFile)->getBuffer());
151+
Version = ParseCudaVersionFile(D, (*VersionFile)->getBuffer());
165152
}
166153

167154
if (Version >= CudaVersion::CUDA_90) {

clang/lib/Headers/__clang_cuda_runtime_wrapper.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@
4848
#include "cuda.h"
4949
#if !defined(CUDA_VERSION)
5050
#error "cuda.h did not define CUDA_VERSION"
51-
#elif CUDA_VERSION < 7000 || CUDA_VERSION > 10010
51+
#elif CUDA_VERSION < 7000
5252
#error "Unsupported CUDA version!"
5353
#endif
5454

clang/test/Driver/Inputs/CUDA-unknown/usr/local/cuda/bin/.keep

Whitespace-only changes.

clang/test/Driver/Inputs/CUDA-unknown/usr/local/cuda/include/.keep

Whitespace-only changes.

clang/test/Driver/Inputs/CUDA-unknown/usr/local/cuda/lib/.keep

Whitespace-only changes.

clang/test/Driver/Inputs/CUDA-unknown/usr/local/cuda/lib64/.keep

Whitespace-only changes.

clang/test/Driver/Inputs/CUDA-unknown/usr/local/cuda/nvvm/libdevice/libdevice.10.bc

Whitespace-only changes.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
CUDA Version 999.999.999

clang/test/Driver/cuda-version-check.cu

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
// RUN: FileCheck %s --check-prefix=OK
99
// RUN: %clang --target=x86_64-linux -v -### --cuda-gpu-arch=sm_60 --cuda-path=%S/Inputs/CUDA_80/usr/local/cuda 2>&1 %s | \
1010
// RUN: FileCheck %s --check-prefix=OK
11+
// RUN: %clang --target=x86_64-linux -v -### --cuda-gpu-arch=sm_60 --cuda-path=%S/Inputs/CUDA-unknown/usr/local/cuda 2>&1 %s | \
12+
// RUN: FileCheck %s --check-prefix=UNKNOWN_VERSION
1113

1214
// The installation at Inputs/CUDA is CUDA 7.0, which doesn't support sm_60.
1315
// RUN: %clang --target=x86_64-linux -v -### --cuda-gpu-arch=sm_60 --cuda-path=%S/Inputs/CUDA/usr/local/cuda 2>&1 %s | \
@@ -58,3 +60,5 @@
5860

5961
// ERR_SM61: error: GPU arch sm_61 {{.*}}
6062
// ERR_SM61-NOT: error: GPU arch sm_61
63+
64+
// UNKNOWN_VERSION: Unknown CUDA version 999.999. Assuming the latest supported version

0 commit comments

Comments
 (0)