Commit 5777899f authored by Artem Belevich's avatar Artem Belevich Committed by Hans Wennborg
Browse files

[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 12fefeef)
parent 96765815
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -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,
+3 −0
Original line number Diff line number Diff line
@@ -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<
+3 −0
Original line number Diff line number Diff line
@@ -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">;
+5 −3
Original line number Diff line number Diff line
@@ -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) {
+15 −28
Original line number Diff line number Diff line
@@ -32,37 +32,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(
@@ -160,7 +147,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) {
Loading