diff --git a/clang/CMakeLists.txt b/clang/CMakeLists.txt --- a/clang/CMakeLists.txt +++ b/clang/CMakeLists.txt @@ -309,7 +309,11 @@ # Try to find the highest Nvidia GPU architecture the system supports if (NOT DEFINED CLANG_OPENMP_NVPTX_DEFAULT_ARCH) - find_package(CUDA QUIET) + # How CUDA is detected should be consistent with libomptarget. + # + # /usr/lib/cuda is a special case for Debian/Ubuntu to have nvidia-cuda-toolkit + # work out of the box. More info on http://bugs.debian.org/882505 + find_package(CUDA QUIET PATHS "/usr/lib/cuda") if (CUDA_FOUND) cuda_select_nvcc_arch_flags(CUDA_ARCH_FLAGS) endif() diff --git a/clang/include/clang/Config/config.h.cmake b/clang/include/clang/Config/config.h.cmake --- a/clang/include/clang/Config/config.h.cmake +++ b/clang/include/clang/Config/config.h.cmake @@ -57,6 +57,9 @@ /* Directory where gcc is installed. */ #define GCC_INSTALL_PREFIX "${GCC_INSTALL_PREFIX}" +/* Directory where CUDA is installed. */ +#define CLANG_CUDA_TOOLKIT_ROOT_DIR "${CUDA_TOOLKIT_ROOT_DIR}" + /* Define if we have libxml2 */ #cmakedefine CLANG_HAVE_LIBXML ${CLANG_HAVE_LIBXML} diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -639,6 +639,8 @@ def no_cuda_noopt_device_debug : Flag<["--"], "no-cuda-noopt-device-debug">; def cuda_path_EQ : Joined<["--"], "cuda-path=">, Group, HelpText<"CUDA installation path">; +def cuda_path_ignore_cmake : Flag<["--"], "cuda-path-ignore-cmake">, Group, + HelpText<"Ignore clang's build-time introspection to detect CUDA installation">; def cuda_path_ignore_env : Flag<["--"], "cuda-path-ignore-env">, Group, HelpText<"Ignore environment variables to detect CUDA installation">; def ptxas_path_EQ : Joined<["--"], "ptxas-path=">, Group, diff --git a/clang/lib/Driver/ToolChains/Cuda.cpp b/clang/lib/Driver/ToolChains/Cuda.cpp --- a/clang/lib/Driver/ToolChains/Cuda.cpp +++ b/clang/lib/Driver/ToolChains/Cuda.cpp @@ -83,43 +83,54 @@ if (Args.hasArg(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) - Candidates.emplace_back( - D.SysRoot + "/Program Files/NVIDIA GPU Computing Toolkit/CUDA/v" + - Ver); } else { - 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 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( - std::string(llvm::sys::path::parent_path(ptxasDir)), - /*StrictChecking=*/true); - } + // Use the CUDA installation detected by CMake as the first candidate. This + // also the one used to compile libomptarget's CUDA plugin and its + // regression tests. + if (!Args.hasArg(clang::driver::options::OPT_cuda_path_ignore_cmake)) { + std::string CMakeCudaPath = CLANG_CUDA_TOOLKIT_ROOT_DIR; + if (!CMakeCudaPath.empty()) + Candidates.emplace_back(CMakeCudaPath); } - Candidates.emplace_back(D.SysRoot + "/usr/local/cuda"); - for (const char *Ver : Versions) - Candidates.emplace_back(D.SysRoot + "/usr/local/cuda-" + Ver); + if (HostTriple.isOSWindows()) { + for (const char *Ver : Versions) + Candidates.emplace_back( + D.SysRoot + "/Program Files/NVIDIA GPU Computing Toolkit/CUDA/v" + + Ver); + } else { + 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 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( + std::string(llvm::sys::path::parent_path(ptxasDir)), + /*StrictChecking=*/true); + } + } + + Candidates.emplace_back(D.SysRoot + "/usr/local/cuda"); + for (const char *Ver : Versions) + Candidates.emplace_back(D.SysRoot + "/usr/local/cuda-" + Ver); - Distro Dist(FS, llvm::Triple(llvm::sys::getProcessTriple())); - if (Dist.IsDebian() || Dist.IsUbuntu()) - // Special case for Debian to have nvidia-cuda-toolkit work - // out of the box. More info on http://bugs.debian.org/882505 - Candidates.emplace_back(D.SysRoot + "/usr/lib/cuda"); + Distro Dist(FS, llvm::Triple(llvm::sys::getProcessTriple())); + if (Dist.IsDebian() || Dist.IsUbuntu()) + // Special case for Debian to have nvidia-cuda-toolkit work + // out of the box. More info on http://bugs.debian.org/882505 + Candidates.emplace_back(D.SysRoot + "/usr/lib/cuda"); + } } bool NoCudaLib = Args.hasArg(options::OPT_nogpulib); diff --git a/clang/test/Driver/cuda-detect-path.cu b/clang/test/Driver/cuda-detect-path.cu --- a/clang/test/Driver/cuda-detect-path.cu +++ b/clang/test/Driver/cuda-detect-path.cu @@ -5,77 +5,77 @@ // REQUIRES: !system-windows // RUN: env PATH=%S/Inputs/CUDA/usr/local/cuda/bin \ -// RUN: %clang -v --target=i386-unknown-linux --sysroot=%S/no-cuda-there \ +// RUN: %clang -v --target=i386-unknown-linux --sysroot=%S/no-cuda-there --cuda-path-ignore-cmake \ // RUN: 2>&1 | FileCheck %s // RUN: env PATH=%S/Inputs/CUDA/usr/local/cuda/bin \ -// RUN: %clang -v --target=i386-apple-macosx --sysroot=%S/no-cuda-there \ +// RUN: %clang -v --target=i386-apple-macosx --sysroot=%S/no-cuda-there --cuda-path-ignore-cmake \ // RUN: 2>&1 | FileCheck %s // RUN: env PATH=%S/Inputs/CUDA/usr/local/cuda/bin \ -// RUN: %clang -v --target=x86_64-unknown-linux --sysroot=%S/no-cuda-there \ +// RUN: %clang -v --target=x86_64-unknown-linux --sysroot=%S/no-cuda-there --cuda-path-ignore-cmake \ // RUN: 2>&1 | FileCheck %s // RUN: env PATH=%S/Inputs/CUDA/usr/local/cuda/bin \ -// RUN: %clang -v --target=x86_64-apple-macosx --sysroot=%S/no-cuda-there \ +// RUN: %clang -v --target=x86_64-apple-macosx --sysroot=%S/no-cuda-there --cuda-path-ignore-cmake \ // RUN: 2>&1 | FileCheck %s // Check that we follow ptxas binaries that are symlinks. // RUN: env PATH=%S/Inputs/CUDA-symlinks/usr/bin \ -// RUN: %clang -v --target=i386-unknown-linux --sysroot=%S/no-cuda-there \ +// RUN: %clang -v --target=i386-unknown-linux --sysroot=%S/no-cuda-there --cuda-path-ignore-cmake \ // RUN: 2>&1 | FileCheck %s --check-prefix SYMLINKS // RUN: env PATH=%S/Inputs/CUDA-symlinks/usr/bin \ -// RUN: %clang -v --target=i386-apple-macosx --sysroot=%S/no-cuda-there \ +// RUN: %clang -v --target=i386-apple-macosx --sysroot=%S/no-cuda-there --cuda-path-ignore-cmake \ // RUN: 2>&1 | FileCheck %s --check-prefix SYMLINKS // RUN: env PATH=%S/Inputs/CUDA-symlinks/usr/bin \ -// RUN: %clang -v --target=x86_64-unknown-linux --sysroot=%S/no-cuda-there \ +// RUN: %clang -v --target=x86_64-unknown-linux --sysroot=%S/no-cuda-there --cuda-path-ignore-cmake \ // RUN: 2>&1 | FileCheck %s --check-prefix SYMLINKS // RUN: env PATH=%S/Inputs/CUDA-symlinks/usr/bin \ -// RUN: %clang -v --target=x86_64-apple-macosx --sysroot=%S/no-cuda-there \ +// RUN: %clang -v --target=x86_64-apple-macosx --sysroot=%S/no-cuda-there --cuda-path-ignore-cmake \ // RUN: 2>&1 | FileCheck %s --check-prefix SYMLINKS // We only take a CUDA installation from PATH if it contains libdevice. // RUN: env PATH=%S/Inputs/CUDA-nolibdevice/usr/local/cuda/bin \ -// RUN: %clang -v --target=i386-unknown-linux --sysroot=%S/no-cuda-there \ +// RUN: %clang -v --target=i386-unknown-linux --sysroot=%S/no-cuda-there --cuda-path-ignore-cmake \ // RUN: 2>&1 | FileCheck %s --check-prefix NOCUDA // RUN: env PATH=%S/Inputs/CUDA-nolibdevice/usr/local/cuda/bin \ -// RUN: %clang -v --target=i386-apple-macosx --sysroot=%S/no-cuda-there \ +// RUN: %clang -v --target=i386-apple-macosx --sysroot=%S/no-cuda-there --cuda-path-ignore-cmake \ // RUN: 2>&1 | FileCheck %s --check-prefix NOCUDA // RUN: env PATH=%S/Inputs/CUDA-nolibdevice/usr/local/cuda/bin \ -// RUN: %clang -v --target=x86_64-unknown-linux --sysroot=%S/no-cuda-there \ +// RUN: %clang -v --target=x86_64-unknown-linux --sysroot=%S/no-cuda-there --cuda-path-ignore-cmake \ // RUN: 2>&1 | FileCheck %s --check-prefix NOCUDA // RUN: env PATH=%S/Inputs/CUDA-nolibdevice/usr/local/cuda/bin \ -// RUN: %clang -v --target=x86_64-apple-macosx --sysroot=%S/no-cuda-there \ +// RUN: %clang -v --target=x86_64-apple-macosx --sysroot=%S/no-cuda-there --cuda-path-ignore-cmake \ // RUN: 2>&1 | FileCheck %s --check-prefix NOCUDA // We even require libdevice if -nocudalib is passed to avoid false positives // if the distribution merges CUDA into /usr and ptxas ends up /usr/bin. // RUN: env PATH=%S/Inputs/CUDA-nolibdevice/usr/local/cuda/bin \ -// RUN: %clang -v --target=i386-unknown-linux --sysroot=%S/no-cuda-there -nocudalib \ +// RUN: %clang -v --target=i386-unknown-linux --sysroot=%S/no-cuda-there --cuda-path-ignore-cmake -nocudalib \ // RUN: 2>&1 | FileCheck %s --check-prefix NOCUDA // RUN: env PATH=%S/Inputs/CUDA-nolibdevice/usr/local/cuda/bin \ -// RUN: %clang -v --target=i386-apple-macosx --sysroot=%S/no-cuda-there -nocudalib \ +// RUN: %clang -v --target=i386-apple-macosx --sysroot=%S/no-cuda-there --cuda-path-ignore-cmake -nocudalib \ // RUN: 2>&1 | FileCheck %s --check-prefix NOCUDA // RUN: env PATH=%S/Inputs/CUDA-nolibdevice/usr/local/cuda/bin \ -// RUN: %clang -v --target=x86_64-unknown-linux --sysroot=%S/no-cuda-there -nocudalib \ +// RUN: %clang -v --target=x86_64-unknown-linux --sysroot=%S/no-cuda-there --cuda-path-ignore-cmake -nocudalib \ // RUN: 2>&1 | FileCheck %s --check-prefix NOCUDA // RUN: env PATH=%S/Inputs/CUDA-nolibdevice/usr/local/cuda/bin \ -// RUN: %clang -v --target=x86_64-apple-macosx --sysroot=%S/no-cuda-there -nocudalib \ +// RUN: %clang -v --target=x86_64-apple-macosx --sysroot=%S/no-cuda-there --cuda-path-ignore-cmake -nocudalib \ // RUN: 2>&1 | FileCheck %s --check-prefix NOCUDA // Check that the CUDA installation in PATH is not taken when passing // the option --cuda-path-ignore-env. // RUN: env PATH=%S/Inputs/CUDA/usr/local/cuda/bin \ -// RUN: %clang -v --target=i386-unknown-linux --sysroot=%S/no-cuda-there --cuda-path-ignore-env \ +// RUN: %clang -v --target=i386-unknown-linux --sysroot=%S/no-cuda-there --cuda-path-ignore-cmake --cuda-path-ignore-env \ // RUN: 2>&1 | FileCheck %s --check-prefix NOCUDA // RUN: env PATH=%S/Inputs/CUDA/usr/local/cuda/bin \ -// RUN: %clang -v --target=i386-apple-macosx --sysroot=%S/no-cuda-there --cuda-path-ignore-env \ +// RUN: %clang -v --target=i386-apple-macosx --sysroot=%S/no-cuda-there --cuda-path-ignore-cmake --cuda-path-ignore-env \ // RUN: 2>&1 | FileCheck %s --check-prefix NOCUDA // RUN: env PATH=%S/Inputs/CUDA/usr/local/cuda/bin \ -// RUN: %clang -v --target=x86_64-unknown-linux --sysroot=%S/no-cuda-there --cuda-path-ignore-env \ +// RUN: %clang -v --target=x86_64-unknown-linux --sysroot=%S/no-cuda-there --cuda-path-ignore-cmake --cuda-path-ignore-env \ // RUN: 2>&1 | FileCheck %s --check-prefix NOCUDA // RUN: env PATH=%S/Inputs/CUDA/usr/local/cuda/bin \ -// RUN: %clang -v --target=x86_64-apple-macosx --sysroot=%S/no-cuda-there --cuda-path-ignore-env \ +// RUN: %clang -v --target=x86_64-apple-macosx --sysroot=%S/no-cuda-there --cuda-path-ignore-cmake --cuda-path-ignore-env \ // RUN: 2>&1 | FileCheck %s --check-prefix NOCUDA // CHECK: Found CUDA installation: {{.*}}/Inputs/CUDA/usr/local/cuda diff --git a/clang/test/Driver/cuda-detect.cu b/clang/test/Driver/cuda-detect.cu --- a/clang/test/Driver/cuda-detect.cu +++ b/clang/test/Driver/cuda-detect.cu @@ -3,19 +3,18 @@ // REQUIRES: nvptx-registered-target // // Check that we properly detect CUDA installation. -// RUN: %clang -v --target=i386-unknown-linux \ +// RUN: %clang -v --target=i386-unknown-linux --cuda-path-ignore-cmake \ // RUN: --sysroot=%S/no-cuda-there --cuda-path-ignore-env 2>&1 | FileCheck %s -check-prefix NOCUDA -// RUN: %clang -v --target=i386-apple-macosx \ +// RUN: %clang -v --target=i386-apple-macosx --cuda-path-ignore-cmake \ // RUN: --sysroot=%S/no-cuda-there --cuda-path-ignore-env 2>&1 | FileCheck %s -check-prefix NOCUDA -// RUN: %clang -v --target=x86_64-unknown-linux \ +// RUN: %clang -v --target=x86_64-unknown-linux --cuda-path-ignore-cmake \ // RUN: --sysroot=%S/no-cuda-there --cuda-path-ignore-env 2>&1 | FileCheck %s -check-prefix NOCUDA -// RUN: %clang -v --target=x86_64-apple-macosx \ +// RUN: %clang -v --target=x86_64-apple-macosx --cuda-path-ignore-cmake \ // RUN: --sysroot=%S/no-cuda-there --cuda-path-ignore-env 2>&1 | FileCheck %s -check-prefix NOCUDA - -// RUN: %clang -v --target=i386-unknown-linux \ +// RUN: %clang -v --target=i386-unknown-linux --cuda-path-ignore-cmake \ // RUN: --sysroot=%S/Inputs/CUDA --cuda-path-ignore-env 2>&1 | FileCheck %s -// RUN: %clang -v --target=i386-apple-macosx \ +// RUN: %clang -v --target=i386-apple-macosx --cuda-path-ignore-cmake \ // RUN: --sysroot=%S/Inputs/CUDA --cuda-path-ignore-env 2>&1 | FileCheck %s // RUN: %clang -v --target=i386-unknown-linux \ @@ -24,23 +23,23 @@ // RUN: --cuda-path=%S/Inputs/CUDA/usr/local/cuda 2>&1 | FileCheck %s // Check that we don't find a CUDA installation without libdevice ... -// RUN: %clang -v --target=i386-unknown-linux \ +// RUN: %clang -v --target=i386-unknown-linux --cuda-path-ignore-cmake \ // RUN: --sysroot=%S/Inputs/CUDA-nolibdevice --cuda-path-ignore-env 2>&1 | FileCheck %s -check-prefix NOCUDA -// RUN: %clang -v --target=i386-apple-macosx \ +// RUN: %clang -v --target=i386-apple-macosx --cuda-path-ignore-cmake \ // RUN: --sysroot=%S/Inputs/CUDA-nolibdevice --cuda-path-ignore-env 2>&1 | FileCheck %s -check-prefix NOCUDA -// RUN: %clang -v --target=x86_64-unknown-linux \ +// RUN: %clang -v --target=x86_64-unknown-linux --cuda-path-ignore-cmake \ // RUN: --sysroot=%S/Inputs/CUDA-nolibdevice --cuda-path-ignore-env 2>&1 | FileCheck %s -check-prefix NOCUDA -// RUN: %clang -v --target=x84_64-apple-macosx \ +// RUN: %clang -v --target=x84_64-apple-macosx --cuda-path-ignore-cmake \ // RUN: --sysroot=%S/Inputs/CUDA-nolibdevice --cuda-path-ignore-env 2>&1 | FileCheck %s -check-prefix NOCUDA // ... unless the user doesn't need libdevice -// RUN: %clang -v --target=i386-unknown-linux -nocudalib \ +// RUN: %clang -v --target=i386-unknown-linux -nocudalib --cuda-path-ignore-cmake \ // RUN: --sysroot=%S/Inputs/CUDA-nolibdevice --cuda-path-ignore-env 2>&1 | FileCheck %s -check-prefix NO-LIBDEVICE -// RUN: %clang -v --target=i386-apple-macosx -nocudalib \ +// RUN: %clang -v --target=i386-apple-macosx -nocudalib --cuda-path-ignore-cmake \ // RUN: --sysroot=%S/Inputs/CUDA-nolibdevice --cuda-path-ignore-env 2>&1 | FileCheck %s -check-prefix NO-LIBDEVICE -// RUN: %clang -v --target=x86_64-unknown-linux -nocudalib \ +// RUN: %clang -v --target=x86_64-unknown-linux -nocudalib --cuda-path-ignore-cmake \ // RUN: --sysroot=%S/Inputs/CUDA-nolibdevice --cuda-path-ignore-env 2>&1 | FileCheck %s -check-prefix NO-LIBDEVICE -// RUN: %clang -v --target=x86_64-apple-macosx -nocudalib \ +// RUN: %clang -v --target=x86_64-apple-macosx -nocudalib --cuda-path-ignore-cmake \ // RUN: --sysroot=%S/Inputs/CUDA-nolibdevice --cuda-path-ignore-env 2>&1 | FileCheck %s -check-prefix NO-LIBDEVICE diff --git a/openmp/libomptarget/cmake/Modules/LibomptargetGetDependencies.cmake b/openmp/libomptarget/cmake/Modules/LibomptargetGetDependencies.cmake --- a/openmp/libomptarget/cmake/Modules/LibomptargetGetDependencies.cmake +++ b/openmp/libomptarget/cmake/Modules/LibomptargetGetDependencies.cmake @@ -112,10 +112,12 @@ ################################################################################ # Looking for CUDA... ################################################################################ -if (CUDA_TOOLKIT_ROOT_DIR) - set(LIBOMPTARGET_CUDA_TOOLKIT_ROOT_DIR_PRESET TRUE) -endif() -find_package(CUDA QUIET) + +# How CUDA is detected should be consistent with Clang. +# +# /usr/lib/cuda is a special case for Debian/Ubuntu to have nvidia-cuda-toolkit +# work out of the box. More info on http://bugs.debian.org/882505 +find_package(CUDA QUIET PATHS "/usr/lib/cuda") # Try to get the highest Nvidia GPU architecture the system supports if (CUDA_FOUND) @@ -221,31 +223,3 @@ LIBOMPTARGET_DEP_VEO_FOUND LIBOMPTARGET_DEP_VEO_INCLUDE_DIRS) -# Looking for CUDA libdevice subdirectory -# -# Special case for Debian/Ubuntu to have nvidia-cuda-toolkit work -# out of the box. More info on http://bugs.debian.org/882505 -################################################################################ - -set(LIBOMPTARGET_CUDA_LIBDEVICE_SUBDIR nvvm/libdevice) - -# Don't alter CUDA_TOOLKIT_ROOT_DIR if the user specified it, if a value was -# already cached for it, or if it already has libdevice. Otherwise, on -# Debian/Ubuntu, look where the nvidia-cuda-toolkit package normally installs -# libdevice. -if (NOT LIBOMPTARGET_CUDA_TOOLKIT_ROOT_DIR_PRESET AND - NOT EXISTS - "${CUDA_TOOLKIT_ROOT_DIR}/${LIBOMPTARGET_CUDA_LIBDEVICE_SUBDIR}") - find_program(LSB_RELEASE lsb_release) - if (LSB_RELEASE) - execute_process(COMMAND ${LSB_RELEASE} -is - OUTPUT_VARIABLE LSB_RELEASE_ID - OUTPUT_STRIP_TRAILING_WHITESPACE) - set(candidate_dir /usr/lib/cuda) - if ((LSB_RELEASE_ID STREQUAL "Debian" OR LSB_RELEASE_ID STREQUAL "Ubuntu") - AND EXISTS "${candidate_dir}/${LIBOMPTARGET_CUDA_LIBDEVICE_SUBDIR}") - set(CUDA_TOOLKIT_ROOT_DIR "${candidate_dir}" CACHE PATH - "Toolkit location." FORCE) - endif() - endif() -endif()