tra created this revision. tra added reviewers: Hahnfeld, yaxunl. Herald added subscribers: dexonsmith, bixia. tra requested review of this revision. Herald added a project: clang.
Always use cuda.h to detect CUDA version. It's a more universal approach compared to version.txt which is no longer present in recent CUDA versions. Split the 'unknown CUDA version' warning in two: - when detected CUDA version is partially supported by clang. It's expected to work in general, at the feature parity with the latest supported CUDA version. and may be missing support for the new features/instructions/GPU variants. Clang will issue a warning. - when detected version is new. Recent CUDA versions have been working with clang reasonably well, and will likely to work similarly to the partially supported ones above. Or it may not work at all. Clang will issue a warning and proceed as if the latest known CUDA version was detected. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D108247 Files: clang/include/clang/Basic/Cuda.h clang/include/clang/Basic/DiagnosticDriverKinds.td clang/lib/Basic/Cuda.cpp clang/lib/Driver/ToolChains/Cuda.cpp clang/lib/Driver/ToolChains/Cuda.h clang/test/Driver/Inputs/CUDA-new/usr/local/cuda/bin/.keep clang/test/Driver/Inputs/CUDA-new/usr/local/cuda/include/.keep clang/test/Driver/Inputs/CUDA-new/usr/local/cuda/include/cuda.h clang/test/Driver/Inputs/CUDA-new/usr/local/cuda/lib/.keep clang/test/Driver/Inputs/CUDA-new/usr/local/cuda/lib64/.keep clang/test/Driver/Inputs/CUDA-new/usr/local/cuda/nvvm/libdevice/libdevice.10.bc clang/test/Driver/Inputs/CUDA-unknown/usr/local/cuda/version.txt clang/test/Driver/Inputs/CUDA_80/usr/local/cuda/include/cuda.h clang/test/Driver/Inputs/CUDA_80/usr/local/cuda/version.txt clang/test/Driver/Inputs/CUDA_90/usr/local/cuda/include/cuda.h clang/test/Driver/cuda-version-check.cu
Index: clang/test/Driver/cuda-version-check.cu =================================================================== --- clang/test/Driver/cuda-version-check.cu +++ clang/test/Driver/cuda-version-check.cu @@ -8,15 +8,12 @@ // 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 -// Test version guess when no version.txt or cuda.h are found +// Test version guess when cuda.h has not been found // 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 -// Unknown version with version.txt present -// RUN: %clang --target=x86_64-linux -v -### --cuda-gpu-arch=sm_60 --cuda-path=%S/Inputs/CUDA_102/usr/local/cuda 2>&1 %s | \ -// RUN: FileCheck %s --check-prefix=UNKNOWN_VERSION_V -// Unknown version with no version.txt but with version info present in cuda.h -// RUN: %clang --target=x86_64-linux -v -### --cuda-gpu-arch=sm_60 --cuda-path=%S/Inputs/CUDA_111/usr/local/cuda 2>&1 %s | \ -// RUN: FileCheck %s --check-prefix=UNKNOWN_VERSION_H +// Unknown version info present in cuda.h +// RUN: %clang --target=x86_64-linux -v -### --cuda-gpu-arch=sm_60 --cuda-path=%S/Inputs/CUDA-new/usr/local/cuda 2>&1 %s | \ +// RUN: FileCheck %s --check-prefix=NEW_VERSION // Make sure that we don't warn about CUDA version during C++ compilation. // RUN: %clang --target=x86_64-linux -v -### -x c++ --cuda-gpu-arch=sm_60 \ // RUN: --cuda-path=%S/Inputs/CUDA-unknown/usr/local/cuda 2>&1 %s | \ @@ -66,13 +63,15 @@ // OK_SM35-NOT: error: GPU arch sm_35 // We should only get one error per architecture. +// ERR_SM20: error: GPU arch sm_20 {{.*}} +// ERR_SM20-NOT: error: GPU arch sm_20 + // ERR_SM60: error: GPU arch sm_60 {{.*}} // ERR_SM60-NOT: error: GPU arch sm_60 // ERR_SM61: error: GPU arch sm_61 {{.*}} // ERR_SM61-NOT: error: GPU arch sm_61 -// UNKNOWN_VERSION_V: unknown CUDA version: version.txt:{{.*}}; assuming the latest supported version -// UNKNOWN_VERSION_H: unknown CUDA version: cuda.h: CUDA_VERSION={{.*}}; assuming the latest supported version -// UNKNOWN_VERSION: unknown CUDA version: no version found in version.txt or cuda.h; assuming the latest supported version +// UNKNOWN_VERSION: CUDA version [unknown] is newer than the latest{{.*}} supported version +// NEW_VERSION: CUDA version 99010 is newer than the latest{{.*}} supported version // UNKNOWN_VERSION_CXX-NOT: unknown CUDA version Index: clang/test/Driver/Inputs/CUDA_90/usr/local/cuda/include/cuda.h =================================================================== --- /dev/null +++ clang/test/Driver/Inputs/CUDA_90/usr/local/cuda/include/cuda.h @@ -0,0 +1,7 @@ +// +// Placeholder file for testing CUDA version detection +// + +#define CUDA_VERSION 9000 + +// Index: clang/test/Driver/Inputs/CUDA_80/usr/local/cuda/version.txt =================================================================== --- clang/test/Driver/Inputs/CUDA_80/usr/local/cuda/version.txt +++ /dev/null @@ -1 +0,0 @@ -CUDA Version 8.0.42 Index: clang/test/Driver/Inputs/CUDA_80/usr/local/cuda/include/cuda.h =================================================================== --- /dev/null +++ clang/test/Driver/Inputs/CUDA_80/usr/local/cuda/include/cuda.h @@ -0,0 +1,7 @@ +// +// Placeholder file for testing CUDA version detection +// + +#define CUDA_VERSION 8000 + +// Index: clang/test/Driver/Inputs/CUDA-unknown/usr/local/cuda/version.txt =================================================================== --- clang/test/Driver/Inputs/CUDA-unknown/usr/local/cuda/version.txt +++ /dev/null @@ -1 +0,0 @@ -CUDA Version 999.999.999 Index: clang/test/Driver/Inputs/CUDA-new/usr/local/cuda/include/cuda.h =================================================================== --- /dev/null +++ clang/test/Driver/Inputs/CUDA-new/usr/local/cuda/include/cuda.h @@ -0,0 +1,7 @@ +// +// Placeholder file for testing CUDA version detection +// + +#define CUDA_VERSION 99010 + +// Index: clang/lib/Driver/ToolChains/Cuda.h =================================================================== --- clang/lib/Driver/ToolChains/Cuda.h +++ clang/lib/Driver/ToolChains/Cuda.h @@ -31,7 +31,8 @@ bool IsValid = false; CudaVersion Version = CudaVersion::UNKNOWN; std::string DetectedVersion; - bool DetectedVersionIsNotSupported = false; + bool DetectedVersionIsPartiallySupported = false; + bool DetectedVersionIsTooNew = false; std::string InstallPath; std::string BinPath; std::string LibPath; @@ -62,7 +63,10 @@ void print(raw_ostream &OS) const; /// Get the detected Cuda install's version. - CudaVersion version() const { return Version; } + CudaVersion version() const { + return Version == CudaVersion::NEW ? CudaVersion::PARTIALLY_SUPPORTED + : Version; + } /// Get the detected Cuda installation path. StringRef getInstallPath() const { return InstallPath; } /// Get the detected path to Cuda's bin directory. Index: clang/lib/Driver/ToolChains/Cuda.cpp =================================================================== --- clang/lib/Driver/ToolChains/Cuda.cpp +++ clang/lib/Driver/ToolChains/Cuda.cpp @@ -17,6 +17,7 @@ #include "clang/Driver/InputInfo.h" #include "clang/Driver/Options.h" #include "llvm/ADT/Optional.h" +#include "llvm/ADT/StringExtras.h" #include "llvm/Option/ArgList.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/Host.h" @@ -35,24 +36,9 @@ namespace { struct CudaVersionInfo { - std::string DetectedVersion; + std::string DetectedVersionString; CudaVersion Version; }; -// 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". -CudaVersionInfo parseCudaVersionFile(llvm::StringRef V) { - V = V.trim(); - if (!V.startswith("CUDA Version ")) - return {V.str(), CudaVersion::UNKNOWN}; - V = V.substr(strlen("CUDA Version ")); - SmallVector<StringRef,4> VersionParts; - V.split(VersionParts, '.'); - return {"version.txt: " + V.str() + ".", - VersionParts.size() < 2 - ? CudaVersion::UNKNOWN - : CudaStringToVersion( - join_items(".", VersionParts[0], VersionParts[1]))}; -} CudaVersion getCudaVersion(uint32_t raw_version) { if (raw_version < 7050) @@ -83,7 +69,7 @@ return CudaVersion::CUDA_113; if (raw_version < 11050) return CudaVersion::CUDA_114; - return CudaVersion::LATEST; + return CudaVersion::NEW; } CudaVersionInfo parseCudaHFile(llvm::StringRef Input) { @@ -106,21 +92,23 @@ StartsWithWords(Input.ltrim(), {"#", "define", "CUDA_VERSION"})) { uint32_t RawVersion; Line->consumeInteger(10, RawVersion); - return {"cuda.h: CUDA_VERSION=" + Twine(RawVersion).str() + ".", - getCudaVersion(RawVersion)}; + return {llvm::utostr(RawVersion), getCudaVersion(RawVersion)}; } // Find next non-empty line. Input = Input.drop_front(Input.find_first_of("\n\r")).ltrim(); } - return {"cuda.h: CUDA_VERSION not found.", CudaVersion::UNKNOWN}; + return {"CUDA_VERSION not found.", CudaVersion::UNKNOWN}; } } // namespace void CudaInstallationDetector::WarnIfUnsupportedVersion() { - if (DetectedVersionIsNotSupported) - D.Diag(diag::warn_drv_unknown_cuda_version) + if (DetectedVersionIsTooNew) + D.Diag(diag::warn_drv_new_cuda_version) << DetectedVersion - << CudaVersionToString(CudaVersion::LATEST_SUPPORTED); + << (CudaVersion::PARTIALLY_SUPPORTED != CudaVersion::FULLY_SUPPORTED) + << CudaVersionToString(CudaVersion::PARTIALLY_SUPPORTED); + else if (DetectedVersionIsPartiallySupported) + D.Diag(diag::warn_drv_partially_supported_cuda_version) << DetectedVersion; } CudaInstallationDetector::CudaInstallationDetector( @@ -213,28 +201,23 @@ continue; CudaVersionInfo VersionInfo = {"", CudaVersion::UNKNOWN}; - if (auto VersionFile = FS.getBufferForFile(InstallPath + "/version.txt")) - VersionInfo = parseCudaVersionFile((*VersionFile)->getBuffer()); - // If version file didn't give us the version, try to find it in cuda.h - if (VersionInfo.Version == CudaVersion::UNKNOWN) - if (auto CudaHFile = FS.getBufferForFile(InstallPath + "/include/cuda.h")) - VersionInfo = parseCudaHFile((*CudaHFile)->getBuffer()); - // As the last resort, make an educated guess between CUDA-7.0, (which had - // no version.txt file and had old-style libdevice bitcode ) and an unknown - // recent CUDA version (no version.txt, new style bitcode). + if (auto CudaHFile = FS.getBufferForFile(InstallPath + "/include/cuda.h")) + VersionInfo = parseCudaHFile((*CudaHFile)->getBuffer()); + // As the last resort, make an educated guess between CUDA-7.0, which had + // old-style libdevice bitcode, and an unknown recent CUDA version. if (VersionInfo.Version == CudaVersion::UNKNOWN) { - VersionInfo.Version = (FS.exists(LibDevicePath + "/libdevice.10.bc")) - ? Version = CudaVersion::LATEST + VersionInfo.Version = FS.exists(LibDevicePath + "/libdevice.10.bc") + ? Version = CudaVersion::NEW : Version = CudaVersion::CUDA_70; - VersionInfo.DetectedVersion = "no version found in version.txt or cuda.h"; + VersionInfo.DetectedVersionString = "[unknown]"; } Version = VersionInfo.Version; - DetectedVersion = VersionInfo.DetectedVersion; + DetectedVersion = VersionInfo.DetectedVersionString; - // TODO(tra): remove the warning once we have all features of 10.2 - // and 11.0 implemented. - DetectedVersionIsNotSupported = Version > CudaVersion::LATEST_SUPPORTED; + DetectedVersionIsPartiallySupported = + Version > CudaVersion::FULLY_SUPPORTED; + DetectedVersionIsTooNew = Version > CudaVersion::PARTIALLY_SUPPORTED; if (Version >= CudaVersion::CUDA_90) { // CUDA-9+ uses single libdevice file for all GPU variants. Index: clang/lib/Basic/Cuda.cpp =================================================================== --- clang/lib/Basic/Cuda.cpp +++ clang/lib/Basic/Cuda.cpp @@ -40,6 +40,8 @@ return "11.3"; case CudaVersion::CUDA_114: return "11.4"; + case CudaVersion::NEW: + return "[new]"; } llvm_unreachable("invalid enum"); } @@ -192,7 +194,7 @@ CudaVersion MaxVersionForCudaArch(CudaArch A) { // AMD GPUs do not depend on CUDA versions. if (IsAMDGpuArch(A)) - return CudaVersion::LATEST; + return CudaVersion::NEW; switch (A) { case CudaArch::UNKNOWN: @@ -203,7 +205,7 @@ case CudaArch::SM_30: return CudaVersion::CUDA_110; default: - return CudaVersion::LATEST; + return CudaVersion::NEW; } } Index: clang/include/clang/Basic/DiagnosticDriverKinds.td =================================================================== --- clang/include/clang/Basic/DiagnosticDriverKinds.td +++ clang/include/clang/Basic/DiagnosticDriverKinds.td @@ -77,8 +77,11 @@ "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">, +def warn_drv_new_cuda_version: Warning< + "CUDA version %0 is newer than the latest%select{| partially}1 supported version %2">, + InGroup<CudaUnknownVersion>; +def warn_drv_partially_supported_cuda_version: Warning< + "CUDA version %0 is only partially supported">, InGroup<CudaUnknownVersion>; def err_drv_cuda_host_arch : Error< "unsupported architecture '%0' for host compilation">; Index: clang/include/clang/Basic/Cuda.h =================================================================== --- clang/include/clang/Basic/Cuda.h +++ clang/include/clang/Basic/Cuda.h @@ -33,8 +33,10 @@ CUDA_112, CUDA_113, CUDA_114, - LATEST = CUDA_114, - LATEST_SUPPORTED = CUDA_101, + FULLY_SUPPORTED = CUDA_101, + PARTIALLY_SUPPORTED = + CUDA_114, // Partially supported. Proceed with a warning. + NEW = 10000, // Too new. Issue a warning, but allow using it. }; const char *CudaVersionToString(CudaVersion V); // Input is "Major.Minor"
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits