[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
This commit is contained in:
Artem Belevich 2020-01-22 12:44:22 -08:00
parent 66e47a5720
commit 12fefeef20
13 changed files with 33 additions and 32 deletions

View File

@ -11,6 +11,7 @@
namespace llvm {
class StringRef;
class Twine;
class VersionTuple;
} // namespace llvm
@ -30,7 +31,7 @@ enum class CudaVersion {
};
const char *CudaVersionToString(CudaVersion V);
// Input is "Major.Minor"
CudaVersion CudaStringToVersion(llvm::StringRef S);
CudaVersion CudaStringToVersion(const llvm::Twine &S);
enum class CudaArch {
UNKNOWN,

View File

@ -60,6 +60,9 @@ def err_drv_cuda_version_unsupported : Error<
"but installation at %3 is %4. Use --cuda-path to specify a different CUDA "
"install, pass a different GPU arch with --cuda-gpu-arch, or pass "
"--no-cuda-version-check.">;
def warn_drv_unknown_cuda_version: Warning<
"Unknown CUDA version %0. Assuming the latest supported version %1">,
InGroup<CudaUnknownVersion>;
def err_drv_cuda_host_arch : Error<"unsupported architecture '%0' for host compilation.">;
def err_drv_mix_cuda_hip : Error<"Mixed Cuda and HIP compilation is not supported.">;
def err_drv_invalid_thread_model_for_target : Error<

View File

@ -1113,6 +1113,9 @@ def SerializedDiagnostics : DiagGroup<"serialized-diagnostics">;
// compiling CUDA C/C++ but which is not compatible with the CUDA spec.
def CudaCompat : DiagGroup<"cuda-compat">;
// Warning about unknown CUDA SDK version.
def CudaUnknownVersion: DiagGroup<"unknown-cuda-version">;
// A warning group for warnings about features supported by HIP but
// ignored by CUDA.
def HIPOnly : DiagGroup<"hip-only">;

View File

@ -2,6 +2,7 @@
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/ADT/Twine.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/VersionTuple.h"
@ -31,8 +32,8 @@ const char *CudaVersionToString(CudaVersion V) {
llvm_unreachable("invalid enum");
}
CudaVersion CudaStringToVersion(llvm::StringRef S) {
return llvm::StringSwitch<CudaVersion>(S)
CudaVersion CudaStringToVersion(const llvm::Twine &S) {
return llvm::StringSwitch<CudaVersion>(S.str())
.Case("7.0", CudaVersion::CUDA_70)
.Case("7.5", CudaVersion::CUDA_75)
.Case("8.0", CudaVersion::CUDA_80)
@ -40,7 +41,8 @@ CudaVersion CudaStringToVersion(llvm::StringRef S) {
.Case("9.1", CudaVersion::CUDA_91)
.Case("9.2", CudaVersion::CUDA_92)
.Case("10.0", CudaVersion::CUDA_100)
.Case("10.1", CudaVersion::CUDA_101);
.Case("10.1", CudaVersion::CUDA_101)
.Default(CudaVersion::UNKNOWN);
}
const char *CudaArchToString(CudaArch A) {

View File

@ -33,37 +33,24 @@ using namespace llvm::opt;
// Parses the contents of version.txt in an CUDA installation. It should
// contain one line of the from e.g. "CUDA Version 7.5.2".
static CudaVersion ParseCudaVersionFile(llvm::StringRef V) {
static CudaVersion ParseCudaVersionFile(const Driver &D, llvm::StringRef V) {
if (!V.startswith("CUDA Version "))
return CudaVersion::UNKNOWN;
V = V.substr(strlen("CUDA Version "));
int Major = -1, Minor = -1;
auto First = V.split('.');
auto Second = First.second.split('.');
if (First.first.getAsInteger(10, Major) ||
Second.first.getAsInteger(10, Minor))
SmallVector<StringRef,4> VersionParts;
V.split(VersionParts, '.');
if (VersionParts.size() < 2)
return CudaVersion::UNKNOWN;
std::string MajorMinor = join_items(".", VersionParts[0], VersionParts[1]);
CudaVersion Version = CudaStringToVersion(MajorMinor);
if (Version != CudaVersion::UNKNOWN)
return Version;
if (Major == 7 && Minor == 0) {
// This doesn't appear to ever happen -- version.txt doesn't exist in the
// CUDA 7 installs I've seen. But no harm in checking.
return CudaVersion::CUDA_70;
}
if (Major == 7 && Minor == 5)
return CudaVersion::CUDA_75;
if (Major == 8 && Minor == 0)
return CudaVersion::CUDA_80;
if (Major == 9 && Minor == 0)
return CudaVersion::CUDA_90;
if (Major == 9 && Minor == 1)
return CudaVersion::CUDA_91;
if (Major == 9 && Minor == 2)
return CudaVersion::CUDA_92;
if (Major == 10 && Minor == 0)
return CudaVersion::CUDA_100;
if (Major == 10 && Minor == 1)
return CudaVersion::CUDA_101;
return CudaVersion::UNKNOWN;
// Issue a warning and assume that the version we've found is compatible with
// the latest version we support.
D.Diag(diag::warn_drv_unknown_cuda_version)
<< MajorMinor << CudaVersionToString(CudaVersion::LATEST);
return CudaVersion::LATEST;
}
CudaInstallationDetector::CudaInstallationDetector(
@ -161,7 +148,7 @@ CudaInstallationDetector::CudaInstallationDetector(
// version.txt isn't present.
Version = CudaVersion::CUDA_70;
} else {
Version = ParseCudaVersionFile((*VersionFile)->getBuffer());
Version = ParseCudaVersionFile(D, (*VersionFile)->getBuffer());
}
if (Version >= CudaVersion::CUDA_90) {

View File

@ -48,7 +48,7 @@
#include "cuda.h"
#if !defined(CUDA_VERSION)
#error "cuda.h did not define CUDA_VERSION"
#elif CUDA_VERSION < 7000 || CUDA_VERSION > 10010
#elif CUDA_VERSION < 7000
#error "Unsupported CUDA version!"
#endif

View File

@ -0,0 +1 @@
CUDA Version 999.999.999

View File

@ -8,6 +8,8 @@
// RUN: FileCheck %s --check-prefix=OK
// RUN: %clang --target=x86_64-linux -v -### --cuda-gpu-arch=sm_60 --cuda-path=%S/Inputs/CUDA_80/usr/local/cuda 2>&1 %s | \
// RUN: FileCheck %s --check-prefix=OK
// RUN: %clang --target=x86_64-linux -v -### --cuda-gpu-arch=sm_60 --cuda-path=%S/Inputs/CUDA-unknown/usr/local/cuda 2>&1 %s | \
// RUN: FileCheck %s --check-prefix=UNKNOWN_VERSION
// The installation at Inputs/CUDA is CUDA 7.0, which doesn't support sm_60.
// 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 @@
// ERR_SM61: error: GPU arch sm_61 {{.*}}
// ERR_SM61-NOT: error: GPU arch sm_61
// UNKNOWN_VERSION: Unknown CUDA version 999.999. Assuming the latest supported version