summaryrefslogtreecommitdiffstats
path: root/clang/lib/Driver/ToolChains/Cuda.cpp
diff options
context:
space:
mode:
authorJonas Hahnfeld <hahnjo@hahnjo.de>2018-01-31 08:26:51 +0000
committerJonas Hahnfeld <hahnjo@hahnjo.de>2018-01-31 08:26:51 +0000
commit7f9c5184239eb61e900ca1b34286bf90acf1fe4d (patch)
tree0537b4ed2414c38cf0c0827cc1efbe103247c732 /clang/lib/Driver/ToolChains/Cuda.cpp
parent5106d4d21c61394fa2a46fe8edf91efcbb48781d (diff)
downloadbcm5719-llvm-7f9c5184239eb61e900ca1b34286bf90acf1fe4d.tar.gz
bcm5719-llvm-7f9c5184239eb61e900ca1b34286bf90acf1fe4d.zip
[CUDA] Detect installation in PATH
If the CUDA toolkit is not installed to its default locations in /usr/local/cuda, the user is forced to specify --cuda-path. This is tedious and the driver can be smarter if well-known tools (like ptxas) can already be found in the PATH environment variable. Add option --cuda-path-ignore-env if the user wants to ignore set environment variables. Also use it in the tests to make sure the driver always finds the same CUDA installation, regardless of the user's environment. Differential Revision: https://reviews.llvm.org/D42642 llvm-svn: 323848
Diffstat (limited to 'clang/lib/Driver/ToolChains/Cuda.cpp')
-rw-r--r--clang/lib/Driver/ToolChains/Cuda.cpp65
1 files changed, 50 insertions, 15 deletions
diff --git a/clang/lib/Driver/ToolChains/Cuda.cpp b/clang/lib/Driver/ToolChains/Cuda.cpp
index 1646d136afe..e513e818ebf 100644
--- a/clang/lib/Driver/ToolChains/Cuda.cpp
+++ b/clang/lib/Driver/ToolChains/Cuda.cpp
@@ -8,18 +8,20 @@
//===----------------------------------------------------------------------===//
#include "Cuda.h"
-#include "InputInfo.h"
#include "CommonArgs.h"
+#include "InputInfo.h"
#include "clang/Basic/Cuda.h"
-#include "clang/Config/config.h"
#include "clang/Basic/VirtualFileSystem.h"
-#include "clang/Driver/Distro.h"
+#include "clang/Config/config.h"
#include "clang/Driver/Compilation.h"
+#include "clang/Driver/Distro.h"
#include "clang/Driver/Driver.h"
#include "clang/Driver/DriverDiagnostic.h"
#include "clang/Driver/Options.h"
#include "llvm/Option/ArgList.h"
+#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Path.h"
+#include "llvm/Support/Program.h"
#include <system_error>
using namespace clang::driver;
@@ -61,42 +63,75 @@ CudaInstallationDetector::CudaInstallationDetector(
const Driver &D, const llvm::Triple &HostTriple,
const llvm::opt::ArgList &Args)
: D(D) {
- SmallVector<std::string, 4> CudaPathCandidates;
+ struct Candidate {
+ std::string Path;
+ bool StrictChecking;
+
+ Candidate(std::string Path, bool StrictChecking = false)
+ : Path(Path), StrictChecking(StrictChecking) {}
+ };
+ SmallVector<Candidate, 4> Candidates;
// In decreasing order so we prefer newer versions to older versions.
std::initializer_list<const char *> Versions = {"8.0", "7.5", "7.0"};
if (Args.hasArg(clang::driver::options::OPT_cuda_path_EQ)) {
- CudaPathCandidates.push_back(
- Args.getLastArgValue(clang::driver::options::OPT_cuda_path_EQ));
+ Candidates.emplace_back(
+ Args.getLastArgValue(clang::driver::options::OPT_cuda_path_EQ).str());
} else if (HostTriple.isOSWindows()) {
for (const char *Ver : Versions)
- CudaPathCandidates.push_back(
+ Candidates.emplace_back(
D.SysRoot + "/Program Files/NVIDIA GPU Computing Toolkit/CUDA/v" +
Ver);
} else {
- CudaPathCandidates.push_back(D.SysRoot + "/usr/local/cuda");
+ if (!Args.hasArg(clang::driver::options::OPT_cuda_path_ignore_env)) {
+ // Try to find ptxas binary. If the executable is located in a directory
+ // called 'bin/', its parent directory might be a good guess for a valid
+ // CUDA installation.
+ // However, some distributions might installs 'ptxas' to /usr/bin. In that
+ // case the candidate would be '/usr' which passes the following checks
+ // because '/usr/include' exists as well. To avoid this case, we always
+ // check for the directory potentially containing files for libdevice,
+ // even if the user passes -nocudalib.
+ if (llvm::ErrorOr<std::string> ptxas =
+ llvm::sys::findProgramByName("ptxas")) {
+ SmallString<256> ptxasAbsolutePath;
+ llvm::sys::fs::real_path(*ptxas, ptxasAbsolutePath);
+
+ StringRef ptxasDir = llvm::sys::path::parent_path(ptxasAbsolutePath);
+ if (llvm::sys::path::filename(ptxasDir) == "bin")
+ Candidates.emplace_back(llvm::sys::path::parent_path(ptxasDir),
+ /*StrictChecking=*/true);
+ }
+ }
+
+ Candidates.emplace_back(D.SysRoot + "/usr/local/cuda");
for (const char *Ver : Versions)
- CudaPathCandidates.push_back(D.SysRoot + "/usr/local/cuda-" + Ver);
+ Candidates.emplace_back(D.SysRoot + "/usr/local/cuda-" + Ver);
if (Distro(D.getVFS()).IsDebian())
// Special case for Debian to have nvidia-cuda-toolkit work
// out of the box. More info on http://bugs.debian.org/882505
- CudaPathCandidates.push_back(D.SysRoot + "/usr/lib/cuda");
+ Candidates.emplace_back(D.SysRoot + "/usr/lib/cuda");
}
- for (const auto &CudaPath : CudaPathCandidates) {
- if (CudaPath.empty() || !D.getVFS().exists(CudaPath))
+ bool NoCudaLib = Args.hasArg(options::OPT_nocudalib);
+
+ for (const auto &Candidate : Candidates) {
+ InstallPath = Candidate.Path;
+ if (InstallPath.empty() || !D.getVFS().exists(InstallPath))
continue;
- InstallPath = CudaPath;
- BinPath = CudaPath + "/bin";
+ BinPath = InstallPath + "/bin";
IncludePath = InstallPath + "/include";
LibDevicePath = InstallPath + "/nvvm/libdevice";
auto &FS = D.getVFS();
if (!(FS.exists(IncludePath) && FS.exists(BinPath)))
continue;
+ bool CheckLibDevice = (!NoCudaLib || Candidate.StrictChecking);
+ if (CheckLibDevice && !FS.exists(LibDevicePath))
+ continue;
// On Linux, we have both lib and lib64 directories, and we need to choose
// based on our triple. On MacOS, we have only a lib directory.
@@ -180,7 +215,7 @@ CudaInstallationDetector::CudaInstallationDetector(
// Check that we have found at least one libdevice that we can link in if
// -nocudalib hasn't been specified.
- if (LibDeviceMap.empty() && !Args.hasArg(options::OPT_nocudalib))
+ if (LibDeviceMap.empty() && !NoCudaLib)
continue;
IsValid = true;
OpenPOWER on IntegriCloud