[clang] 12fefee - [CUDA] Assume the latest known CUDA version if we've found an unknown one.

Artem Belevich via cfe-commits cfe-commits at lists.llvm.org
Tue Jan 28 10:19:10 PST 2020


Author: Artem Belevich
Date: 2020-01-28T10:11:42-08:00
New Revision: 12fefeef203ab4ef52d19bcdbd4180608a4deae1

URL: https://github.com/llvm/llvm-project/commit/12fefeef203ab4ef52d19bcdbd4180608a4deae1
DIFF: https://github.com/llvm/llvm-project/commit/12fefeef203ab4ef52d19bcdbd4180608a4deae1.diff

LOG: [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

Added: 
    clang/test/Driver/Inputs/CUDA-unknown/usr/local/cuda/bin/.keep
    clang/test/Driver/Inputs/CUDA-unknown/usr/local/cuda/include/.keep
    clang/test/Driver/Inputs/CUDA-unknown/usr/local/cuda/lib/.keep
    clang/test/Driver/Inputs/CUDA-unknown/usr/local/cuda/lib64/.keep
    clang/test/Driver/Inputs/CUDA-unknown/usr/local/cuda/nvvm/libdevice/libdevice.10.bc
    clang/test/Driver/Inputs/CUDA-unknown/usr/local/cuda/version.txt

Modified: 
    clang/include/clang/Basic/Cuda.h
    clang/include/clang/Basic/DiagnosticDriverKinds.td
    clang/include/clang/Basic/DiagnosticGroups.td
    clang/lib/Basic/Cuda.cpp
    clang/lib/Driver/ToolChains/Cuda.cpp
    clang/lib/Headers/__clang_cuda_runtime_wrapper.h
    clang/test/Driver/cuda-version-check.cu

Removed: 
    


################################################################################
diff  --git a/clang/include/clang/Basic/Cuda.h b/clang/include/clang/Basic/Cuda.h
index ef5d24dcf888..da572957d10d 100644
--- a/clang/include/clang/Basic/Cuda.h
+++ b/clang/include/clang/Basic/Cuda.h
@@ -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,

diff  --git a/clang/include/clang/Basic/DiagnosticDriverKinds.td b/clang/include/clang/Basic/DiagnosticDriverKinds.td
index 2da41bef2669..ecd871e36ee8 100644
--- a/clang/include/clang/Basic/DiagnosticDriverKinds.td
+++ b/clang/include/clang/Basic/DiagnosticDriverKinds.td
@@ -60,6 +60,9 @@ def err_drv_cuda_version_unsupported : Error<
   "but installation at %3 is %4.  Use --cuda-path to specify a 
diff erent CUDA "
   "install, pass a 
diff erent 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<

diff  --git a/clang/include/clang/Basic/DiagnosticGroups.td b/clang/include/clang/Basic/DiagnosticGroups.td
index d98ca36b22c7..f11a69d5f2cd 100644
--- a/clang/include/clang/Basic/DiagnosticGroups.td
+++ b/clang/include/clang/Basic/DiagnosticGroups.td
@@ -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">;

diff  --git a/clang/lib/Basic/Cuda.cpp b/clang/lib/Basic/Cuda.cpp
index f2b6c8cd3ee9..e06d120c58bf 100644
--- a/clang/lib/Basic/Cuda.cpp
+++ b/clang/lib/Basic/Cuda.cpp
@@ -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) {

diff  --git a/clang/lib/Driver/ToolChains/Cuda.cpp b/clang/lib/Driver/ToolChains/Cuda.cpp
index 44bb17d2efb5..5aeaa97b9352 100644
--- a/clang/lib/Driver/ToolChains/Cuda.cpp
+++ b/clang/lib/Driver/ToolChains/Cuda.cpp
@@ -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;
-
-  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;
+  std::string MajorMinor = join_items(".", VersionParts[0], VersionParts[1]);
+  CudaVersion Version = CudaStringToVersion(MajorMinor);
+  if (Version != CudaVersion::UNKNOWN)
+    return Version;
+
+  // 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) {

diff  --git a/clang/lib/Headers/__clang_cuda_runtime_wrapper.h b/clang/lib/Headers/__clang_cuda_runtime_wrapper.h
index 3e362dd967db..e91de3c81dbd 100644
--- a/clang/lib/Headers/__clang_cuda_runtime_wrapper.h
+++ b/clang/lib/Headers/__clang_cuda_runtime_wrapper.h
@@ -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
 

diff  --git a/clang/test/Driver/Inputs/CUDA-unknown/usr/local/cuda/bin/.keep b/clang/test/Driver/Inputs/CUDA-unknown/usr/local/cuda/bin/.keep
new file mode 100644
index 000000000000..e69de29bb2d1

diff  --git a/clang/test/Driver/Inputs/CUDA-unknown/usr/local/cuda/include/.keep b/clang/test/Driver/Inputs/CUDA-unknown/usr/local/cuda/include/.keep
new file mode 100644
index 000000000000..e69de29bb2d1

diff  --git a/clang/test/Driver/Inputs/CUDA-unknown/usr/local/cuda/lib/.keep b/clang/test/Driver/Inputs/CUDA-unknown/usr/local/cuda/lib/.keep
new file mode 100644
index 000000000000..e69de29bb2d1

diff  --git a/clang/test/Driver/Inputs/CUDA-unknown/usr/local/cuda/lib64/.keep b/clang/test/Driver/Inputs/CUDA-unknown/usr/local/cuda/lib64/.keep
new file mode 100644
index 000000000000..e69de29bb2d1

diff  --git a/clang/test/Driver/Inputs/CUDA-unknown/usr/local/cuda/nvvm/libdevice/libdevice.10.bc b/clang/test/Driver/Inputs/CUDA-unknown/usr/local/cuda/nvvm/libdevice/libdevice.10.bc
new file mode 100644
index 000000000000..e69de29bb2d1

diff  --git a/clang/test/Driver/Inputs/CUDA-unknown/usr/local/cuda/version.txt b/clang/test/Driver/Inputs/CUDA-unknown/usr/local/cuda/version.txt
new file mode 100644
index 000000000000..20e55f71b6ca
--- /dev/null
+++ b/clang/test/Driver/Inputs/CUDA-unknown/usr/local/cuda/version.txt
@@ -0,0 +1 @@
+CUDA Version 999.999.999

diff  --git a/clang/test/Driver/cuda-version-check.cu b/clang/test/Driver/cuda-version-check.cu
index 2fdd9c4afbe4..5654d4cb7f74 100644
--- a/clang/test/Driver/cuda-version-check.cu
+++ b/clang/test/Driver/cuda-version-check.cu
@@ -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


        


More information about the cfe-commits mailing list