Skip to content

Commit 5777899

Browse files
Artem-Bzmodem
authored andcommitted
[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 (cherry picked from commit 12fefee)
1 parent 9676581 commit 5777899

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
@@ -32,37 +32,24 @@ using namespace llvm::opt;
3232

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

6855
CudaInstallationDetector::CudaInstallationDetector(
@@ -160,7 +147,7 @@ CudaInstallationDetector::CudaInstallationDetector(
160147
// version.txt isn't present.
161148
Version = CudaVersion::CUDA_70;
162149
} else {
163-
Version = ParseCudaVersionFile((*VersionFile)->getBuffer());
150+
Version = ParseCudaVersionFile(D, (*VersionFile)->getBuffer());
164151
}
165152

166153
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)