forked from OSchip/llvm-project
[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:
parent
66e47a5720
commit
12fefeef20
|
@ -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,
|
||||
|
|
|
@ -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<
|
||||
|
|
|
@ -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">;
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
CUDA Version 999.999.999
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue