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 @@ -904,6 +904,8 @@ NegFlag>; def rocm_path_EQ : Joined<["--"], "rocm-path=">, Group, HelpText<"ROCm installation path, used for finding and automatically linking required bitcode libraries.">; +def hip_path_EQ : Joined<["--"], "hip-path=">, Group, + HelpText<"HIP runtime installation path, used for finding HIP version and adding HIP include path.">; def rocm_device_lib_path_EQ : Joined<["--"], "rocm-device-lib-path=">, Group, HelpText<"ROCm device library path. Alternative to rocm-path.">; def : Joined<["--"], "hip-device-lib-path=">, Alias; @@ -3561,6 +3563,8 @@ HelpText<"Print the paths used for finding libraries and programs">; def print_targets : Flag<["-", "--"], "print-targets">, HelpText<"Print the registered targets">; +def print_rocm_search_dirs : Flag<["-", "--"], "print-rocm-search-dirs">, + HelpText<"Print the paths used for finding ROCm installation">; def private__bundle : Flag<["-"], "private_bundle">; def pthreads : Flag<["-"], "pthreads">; defm pthread : BoolOption<"", "pthread", diff --git a/clang/lib/Driver/ToolChains/AMDGPU.cpp b/clang/lib/Driver/ToolChains/AMDGPU.cpp --- a/clang/lib/Driver/ToolChains/AMDGPU.cpp +++ b/clang/lib/Driver/ToolChains/AMDGPU.cpp @@ -22,6 +22,51 @@ using namespace clang; using namespace llvm::opt; +// Look for sub-directory starts with PackageName under ROCm candidate path. +// If there is one and only one matching sub-directory found, append the +// sub-directory to Path. If there is no matching sub-directory or there are +// more than one matching sub-directories, diagnose them. Returns the full +// path of the package if there is only one matching sub-directory, otherwise +// returns an empty string. +llvm::SmallString<0> +RocmInstallationDetector::findSPACKPackage(const Candidate &Cand, + StringRef PackageName) { + if (!Cand.isSPACK()) + return {}; + std::error_code EC; + std::string Prefix = Twine(PackageName + "-" + Cand.SPACKReleaseStr).str(); + llvm::SmallVector> SubDirs; + for (llvm::vfs::directory_iterator File = D.getVFS().dir_begin(Cand.Path, EC), + FileEnd; + File != FileEnd && !EC; File.increment(EC)) { + llvm::StringRef FileName = llvm::sys::path::filename(File->path()); + if (FileName.startswith(Prefix)) { + SubDirs.push_back(FileName); + if (SubDirs.size() > 1) + break; + } + } + if (SubDirs.size() == 1) { + auto PackagePath = Cand.Path; + llvm::sys::path::append(PackagePath, SubDirs[0]); + return PackagePath; + } + if (SubDirs.size() == 0) { + unsigned DiagID = D.getDiags().getCustomDiagID( + DiagnosticsEngine::Error, + "Expecting SPACK package %0 at %1 but not found"); + D.Diag(DiagID) << Prefix << Cand.Path; + return {}; + } + + assert(SubDirs.size() > 1); + unsigned DiagID = D.getDiags().getCustomDiagID( + DiagnosticsEngine::Error, + "Expecting one SPACK package %0 at %1 but found more"); + D.Diag(DiagID) << Prefix << Cand.Path; + return {}; +} + void RocmInstallationDetector::scanLibDevicePath(llvm::StringRef Path) { assert(!Path.empty()); @@ -116,13 +161,31 @@ return false; } -// For candidate specified by --rocm-path we do not do strict check. -SmallVector +/// \returns a list of candidate directories for ROCm installation, which is +/// cached and populated only once. +const SmallVectorImpl & RocmInstallationDetector::getInstallationPathCandidates() { - SmallVector Candidates; + + // Return the cached candidate list if it has already been populated. + if (!ROCmSearchDirs.empty()) + return ROCmSearchDirs; + + auto DoPrintROCmSearchDirs = [&]() { + if (PrintROCmSearchDirs) + for (auto Cand : ROCmSearchDirs) { + llvm::errs() << "ROCm installation search path"; + if (Cand.isSPACK()) + llvm::errs() << " (Spack " << Cand.SPACKReleaseStr << ")"; + llvm::errs() << ": " << Cand.Path << '\n'; + } + }; + + // For candidate specified by --rocm-path we do not do strict check, i.e., + // checking existence of HIP version file and device library files. if (!RocmPathArg.empty()) { - Candidates.emplace_back(RocmPathArg.str()); - return Candidates; + ROCmSearchDirs.emplace_back(RocmPathArg.str()); + DoPrintROCmSearchDirs(); + return ROCmSearchDirs; } // Try to find relative to the compiler binary. @@ -131,28 +194,61 @@ // Check both a normal Unix prefix position of the clang binary, as well as // the Windows-esque layout the ROCm packages use with the host architecture // subdirectory of bin. + auto DeduceROCmPath = [](StringRef ClangPath) { + // Strip off directory (usually bin) + StringRef ParentDir = llvm::sys::path::parent_path(ClangPath); + StringRef ParentName = llvm::sys::path::filename(ParentDir); + + // Some builds use bin/{host arch}, so go up again. + if (ParentName == "bin") { + ParentDir = llvm::sys::path::parent_path(ParentDir); + ParentName = llvm::sys::path::filename(ParentDir); + } - // Strip off directory (usually bin) - StringRef ParentDir = llvm::sys::path::parent_path(InstallDir); - StringRef ParentName = llvm::sys::path::filename(ParentDir); + // Detect ROCm packages built with SPACK. + // clang is installed at + // /llvm-amdgpu--/bin directory. + // We only consider the parent directory of llvm-amdgpu package as ROCm + // installation candidate for SPACK. + if (ParentName.startswith("llvm-amdgpu-")) { + auto SPACKPostfix = + ParentName.drop_front(strlen("llvm-amdgpu-")).split('-'); + auto SPACKReleaseStr = SPACKPostfix.first; + if (!SPACKReleaseStr.empty()) { + ParentDir = llvm::sys::path::parent_path(ParentDir); + return Candidate(ParentDir.str(), /*StrictChecking=*/true, + SPACKReleaseStr); + } + } - // Some builds use bin/{host arch}, so go up again. - if (ParentName == "bin") { - ParentDir = llvm::sys::path::parent_path(ParentDir); - ParentName = llvm::sys::path::filename(ParentDir); - } + // Some versions of the rocm llvm package install to /opt/rocm/llvm/bin + // Some versions of the aomp package install to /opt/rocm/aomp/bin + if (ParentName == "llvm" || ParentName.startswith("aomp")) + ParentDir = llvm::sys::path::parent_path(ParentDir); + + return Candidate(ParentDir.str(), /*StrictChecking=*/true); + }; - // Some versions of the rocm llvm package install to /opt/rocm/llvm/bin - if (ParentName == "llvm") - ParentDir = llvm::sys::path::parent_path(ParentDir); + // Deduce ROCm path by the path used to invoke clang. Do not resolve symbolic + // link of clang itself. + ROCmSearchDirs.emplace_back(DeduceROCmPath(InstallDir)); - Candidates.emplace_back(ParentDir.str(), /*StrictChecking=*/true); + // Deduce ROCm path by the real path of the invoked clang, resolving symbolic + // link of clang itself. + llvm::SmallString<256> RealClangPath; + llvm::sys::fs::real_path(D.getClangProgramPath(), RealClangPath); + auto ParentPath = llvm::sys::path::parent_path(RealClangPath); + if (ParentPath != InstallDir) + ROCmSearchDirs.emplace_back(DeduceROCmPath(ParentPath)); // Device library may be installed in clang resource directory. - Candidates.emplace_back(D.ResourceDir, /*StrictChecking=*/true); + ROCmSearchDirs.emplace_back(D.ResourceDir, + /*StrictChecking=*/true); - Candidates.emplace_back(D.SysRoot + "/opt/rocm", /*StrictChecking=*/true); - return Candidates; + ROCmSearchDirs.emplace_back(D.SysRoot + "/opt/rocm", + /*StrictChecking=*/true); + DoPrintROCmSearchDirs(); + return ROCmSearchDirs; } RocmInstallationDetector::RocmInstallationDetector( @@ -160,8 +256,11 @@ const llvm::opt::ArgList &Args, bool DetectHIPRuntime, bool DetectDeviceLib) : D(D) { RocmPathArg = Args.getLastArgValue(clang::driver::options::OPT_rocm_path_EQ); + PrintROCmSearchDirs = + Args.hasArg(clang::driver::options::OPT_print_rocm_search_dirs); RocmDeviceLibPathArg = Args.getAllArgValues(clang::driver::options::OPT_rocm_device_lib_path_EQ); + HIPPathArg = Args.getLastArgValue(clang::driver::options::OPT_hip_path_EQ); if (auto *A = Args.getLastArg(clang::driver::options::OPT_hip_version_EQ)) { HIPVersionArg = A->getValue(); unsigned Major = 0; @@ -224,8 +323,8 @@ // exist for each frontend project, and differ depending on which build // system produced the packages. Standalone OpenCL builds also have a // different directory structure from the ROCm OpenCL package. - auto Candidates = getInstallationPathCandidates(); - for (const auto &Candidate : Candidates) { + auto &ROCmDirs = getInstallationPathCandidates(); + for (const auto &Candidate : ROCmDirs) { auto CandidatePath = Candidate.Path; // Check device library exists at the given path. @@ -262,7 +361,10 @@ // Make a path by appending sub-directories to InstallPath. auto MakePath = [&](const llvm::ArrayRef &SubDirs) { - auto Path = CandidatePath; + // Device library built by SPACK is installed to + // /rocm-device-libs-- directory. + auto SPACKPath = findSPACKPackage(Candidate, "rocm-device-libs"); + auto Path = SPACKPath.empty() ? CandidatePath : SPACKPath; for (auto SubDir : SubDirs) llvm::sys::path::append(Path, SubDir); return Path; @@ -278,13 +380,21 @@ } void RocmInstallationDetector::detectHIPRuntime() { - auto Candidates = getInstallationPathCandidates(); + SmallVector HIPSearchDirs; + if (!HIPPathArg.empty()) + HIPSearchDirs.emplace_back(HIPPathArg.str(), /*StrictChecking=*/true); + else + HIPSearchDirs.append(getInstallationPathCandidates()); auto &FS = D.getVFS(); - for (const auto &Candidate : Candidates) { + for (const auto &Candidate : HIPSearchDirs) { InstallPath = Candidate.Path; if (InstallPath.empty() || !FS.exists(InstallPath)) continue; + // HIP runtime built by SPACK is installed to + // /hip-- directory. + auto SPACKPath = findSPACKPackage(Candidate, "hip"); + InstallPath = SPACKPath.empty() ? InstallPath : SPACKPath; BinPath = InstallPath; llvm::sys::path::append(BinPath, "bin"); diff --git a/clang/lib/Driver/ToolChains/ROCm.h b/clang/lib/Driver/ToolChains/ROCm.h --- a/clang/lib/Driver/ToolChains/ROCm.h +++ b/clang/lib/Driver/ToolChains/ROCm.h @@ -42,9 +42,16 @@ struct Candidate { llvm::SmallString<0> Path; bool StrictChecking; - - Candidate(std::string Path, bool StrictChecking = false) - : Path(Path), StrictChecking(StrictChecking) {} + // Release string for ROCm packages built with SPACK if not empty. The + // installation directories of ROCm packages built with SPACK follow the + // convention --. + std::string SPACKReleaseStr; + + bool isSPACK() const { return !SPACKReleaseStr.empty(); } + Candidate(std::string Path, bool StrictChecking = false, + StringRef SPACKReleaseStr = {}) + : Path(Path), StrictChecking(StrictChecking), + SPACKReleaseStr(SPACKReleaseStr.str()) {} }; const Driver &D; @@ -67,6 +74,8 @@ StringRef RocmPathArg; // ROCm device library paths specified by --rocm-device-lib-path. std::vector RocmDeviceLibPathArg; + // HIP runtime path specified by --hip-path. + StringRef HIPPathArg; // HIP version specified by --hip-version. StringRef HIPVersionArg; // Wheter -nogpulib is specified. @@ -98,6 +107,10 @@ ConditionalLibrary DenormalsAreZero; ConditionalLibrary CorrectlyRoundedSqrt; + // Cache ROCm installation search paths. + SmallVector ROCmSearchDirs; + bool PrintROCmSearchDirs; + bool allGenericLibsValid() const { return !OCML.empty() && !OCKL.empty() && !OpenCL.empty() && !HIP.empty() && WavefrontSize64.isValid() && FiniteOnly.isValid() && @@ -107,7 +120,14 @@ void scanLibDevicePath(llvm::StringRef Path); bool parseHIPVersionFile(llvm::StringRef V); - SmallVector getInstallationPathCandidates(); + const SmallVectorImpl &getInstallationPathCandidates(); + + /// Find the path to a SPACK package under the ROCm candidate installation + /// directory if the candidate is a SPACK ROCm candidate. \returns empty + /// string if the candidate is not SPACK ROCm candidate or the requested + /// package is not found. + llvm::SmallString<0> findSPACKPackage(const Candidate &Cand, + StringRef PackageName); public: RocmInstallationDetector(const Driver &D, const llvm::Triple &HostTriple, diff --git a/clang/test/Driver/Inputs/rocm-spack/hip-4.0.0-5f63slrursbrvfe2txrrjkynbsywsob5/bin/.hipVersion b/clang/test/Driver/Inputs/rocm-spack/hip-4.0.0-5f63slrursbrvfe2txrrjkynbsywsob5/bin/.hipVersion new file mode 100644 --- /dev/null +++ b/clang/test/Driver/Inputs/rocm-spack/hip-4.0.0-5f63slrursbrvfe2txrrjkynbsywsob5/bin/.hipVersion @@ -0,0 +1,5 @@ +# NOTE: The trailing whitespace is added on purpose to verify that these +# whitespaces are trimmed before paring. +HIP_VERSION_MAJOR=4 +HIP_VERSION_MINOR=0 +HIP_VERSION_PATCH=20214-a2917cd diff --git a/clang/test/Driver/Inputs/rocm-spack/hip-4.0.0-5f63slrursbrvfe2txrrjkynbsywsob5/include/hip/hip_runtime.h b/clang/test/Driver/Inputs/rocm-spack/hip-4.0.0-5f63slrursbrvfe2txrrjkynbsywsob5/include/hip/hip_runtime.h new file mode 100644 diff --git a/clang/test/Driver/Inputs/rocm-spack/llvm-amdgpu-4.0.0-ieagcs7inf7runpyfvepqkurasoglq4z/bin/.keep b/clang/test/Driver/Inputs/rocm-spack/llvm-amdgpu-4.0.0-ieagcs7inf7runpyfvepqkurasoglq4z/bin/.keep new file mode 100644 diff --git a/clang/test/Driver/Inputs/rocm-spack/rocm-device-libs-4.0.0-6wnyzz4hgl3hr7uswasnagt7j2adctbs/amdgcn/bitcode/asanrtl.bc b/clang/test/Driver/Inputs/rocm-spack/rocm-device-libs-4.0.0-6wnyzz4hgl3hr7uswasnagt7j2adctbs/amdgcn/bitcode/asanrtl.bc new file mode 100644 diff --git a/clang/test/Driver/Inputs/rocm-spack/rocm-device-libs-4.0.0-6wnyzz4hgl3hr7uswasnagt7j2adctbs/amdgcn/bitcode/hip.bc b/clang/test/Driver/Inputs/rocm-spack/rocm-device-libs-4.0.0-6wnyzz4hgl3hr7uswasnagt7j2adctbs/amdgcn/bitcode/hip.bc new file mode 100644 diff --git a/clang/test/Driver/Inputs/rocm-spack/rocm-device-libs-4.0.0-6wnyzz4hgl3hr7uswasnagt7j2adctbs/amdgcn/bitcode/ockl.bc b/clang/test/Driver/Inputs/rocm-spack/rocm-device-libs-4.0.0-6wnyzz4hgl3hr7uswasnagt7j2adctbs/amdgcn/bitcode/ockl.bc new file mode 100644 diff --git a/clang/test/Driver/Inputs/rocm-spack/rocm-device-libs-4.0.0-6wnyzz4hgl3hr7uswasnagt7j2adctbs/amdgcn/bitcode/oclc_correctly_rounded_sqrt_off.bc b/clang/test/Driver/Inputs/rocm-spack/rocm-device-libs-4.0.0-6wnyzz4hgl3hr7uswasnagt7j2adctbs/amdgcn/bitcode/oclc_correctly_rounded_sqrt_off.bc new file mode 100644 diff --git a/clang/test/Driver/Inputs/rocm-spack/rocm-device-libs-4.0.0-6wnyzz4hgl3hr7uswasnagt7j2adctbs/amdgcn/bitcode/oclc_correctly_rounded_sqrt_on.bc b/clang/test/Driver/Inputs/rocm-spack/rocm-device-libs-4.0.0-6wnyzz4hgl3hr7uswasnagt7j2adctbs/amdgcn/bitcode/oclc_correctly_rounded_sqrt_on.bc new file mode 100644 diff --git a/clang/test/Driver/Inputs/rocm-spack/rocm-device-libs-4.0.0-6wnyzz4hgl3hr7uswasnagt7j2adctbs/amdgcn/bitcode/oclc_daz_opt_off.bc b/clang/test/Driver/Inputs/rocm-spack/rocm-device-libs-4.0.0-6wnyzz4hgl3hr7uswasnagt7j2adctbs/amdgcn/bitcode/oclc_daz_opt_off.bc new file mode 100644 diff --git a/clang/test/Driver/Inputs/rocm-spack/rocm-device-libs-4.0.0-6wnyzz4hgl3hr7uswasnagt7j2adctbs/amdgcn/bitcode/oclc_daz_opt_on.bc b/clang/test/Driver/Inputs/rocm-spack/rocm-device-libs-4.0.0-6wnyzz4hgl3hr7uswasnagt7j2adctbs/amdgcn/bitcode/oclc_daz_opt_on.bc new file mode 100644 diff --git a/clang/test/Driver/Inputs/rocm-spack/rocm-device-libs-4.0.0-6wnyzz4hgl3hr7uswasnagt7j2adctbs/amdgcn/bitcode/oclc_finite_only_off.bc b/clang/test/Driver/Inputs/rocm-spack/rocm-device-libs-4.0.0-6wnyzz4hgl3hr7uswasnagt7j2adctbs/amdgcn/bitcode/oclc_finite_only_off.bc new file mode 100644 diff --git a/clang/test/Driver/Inputs/rocm-spack/rocm-device-libs-4.0.0-6wnyzz4hgl3hr7uswasnagt7j2adctbs/amdgcn/bitcode/oclc_finite_only_on.bc b/clang/test/Driver/Inputs/rocm-spack/rocm-device-libs-4.0.0-6wnyzz4hgl3hr7uswasnagt7j2adctbs/amdgcn/bitcode/oclc_finite_only_on.bc new file mode 100644 diff --git a/clang/test/Driver/Inputs/rocm-spack/rocm-device-libs-4.0.0-6wnyzz4hgl3hr7uswasnagt7j2adctbs/amdgcn/bitcode/oclc_isa_version_1010.bc b/clang/test/Driver/Inputs/rocm-spack/rocm-device-libs-4.0.0-6wnyzz4hgl3hr7uswasnagt7j2adctbs/amdgcn/bitcode/oclc_isa_version_1010.bc new file mode 100644 diff --git a/clang/test/Driver/Inputs/rocm-spack/rocm-device-libs-4.0.0-6wnyzz4hgl3hr7uswasnagt7j2adctbs/amdgcn/bitcode/oclc_isa_version_1011.bc b/clang/test/Driver/Inputs/rocm-spack/rocm-device-libs-4.0.0-6wnyzz4hgl3hr7uswasnagt7j2adctbs/amdgcn/bitcode/oclc_isa_version_1011.bc new file mode 100644 diff --git a/clang/test/Driver/Inputs/rocm-spack/rocm-device-libs-4.0.0-6wnyzz4hgl3hr7uswasnagt7j2adctbs/amdgcn/bitcode/oclc_isa_version_1012.bc b/clang/test/Driver/Inputs/rocm-spack/rocm-device-libs-4.0.0-6wnyzz4hgl3hr7uswasnagt7j2adctbs/amdgcn/bitcode/oclc_isa_version_1012.bc new file mode 100644 diff --git a/clang/test/Driver/Inputs/rocm-spack/rocm-device-libs-4.0.0-6wnyzz4hgl3hr7uswasnagt7j2adctbs/amdgcn/bitcode/oclc_isa_version_803.bc b/clang/test/Driver/Inputs/rocm-spack/rocm-device-libs-4.0.0-6wnyzz4hgl3hr7uswasnagt7j2adctbs/amdgcn/bitcode/oclc_isa_version_803.bc new file mode 100644 diff --git a/clang/test/Driver/Inputs/rocm-spack/rocm-device-libs-4.0.0-6wnyzz4hgl3hr7uswasnagt7j2adctbs/amdgcn/bitcode/oclc_isa_version_900.bc b/clang/test/Driver/Inputs/rocm-spack/rocm-device-libs-4.0.0-6wnyzz4hgl3hr7uswasnagt7j2adctbs/amdgcn/bitcode/oclc_isa_version_900.bc new file mode 100644 diff --git a/clang/test/Driver/Inputs/rocm-spack/rocm-device-libs-4.0.0-6wnyzz4hgl3hr7uswasnagt7j2adctbs/amdgcn/bitcode/oclc_isa_version_908.bc b/clang/test/Driver/Inputs/rocm-spack/rocm-device-libs-4.0.0-6wnyzz4hgl3hr7uswasnagt7j2adctbs/amdgcn/bitcode/oclc_isa_version_908.bc new file mode 100644 diff --git a/clang/test/Driver/Inputs/rocm-spack/rocm-device-libs-4.0.0-6wnyzz4hgl3hr7uswasnagt7j2adctbs/amdgcn/bitcode/oclc_unsafe_math_off.bc b/clang/test/Driver/Inputs/rocm-spack/rocm-device-libs-4.0.0-6wnyzz4hgl3hr7uswasnagt7j2adctbs/amdgcn/bitcode/oclc_unsafe_math_off.bc new file mode 100644 diff --git a/clang/test/Driver/Inputs/rocm-spack/rocm-device-libs-4.0.0-6wnyzz4hgl3hr7uswasnagt7j2adctbs/amdgcn/bitcode/oclc_unsafe_math_on.bc b/clang/test/Driver/Inputs/rocm-spack/rocm-device-libs-4.0.0-6wnyzz4hgl3hr7uswasnagt7j2adctbs/amdgcn/bitcode/oclc_unsafe_math_on.bc new file mode 100644 diff --git a/clang/test/Driver/Inputs/rocm-spack/rocm-device-libs-4.0.0-6wnyzz4hgl3hr7uswasnagt7j2adctbs/amdgcn/bitcode/oclc_wavefrontsize64_off.bc b/clang/test/Driver/Inputs/rocm-spack/rocm-device-libs-4.0.0-6wnyzz4hgl3hr7uswasnagt7j2adctbs/amdgcn/bitcode/oclc_wavefrontsize64_off.bc new file mode 100644 diff --git a/clang/test/Driver/Inputs/rocm-spack/rocm-device-libs-4.0.0-6wnyzz4hgl3hr7uswasnagt7j2adctbs/amdgcn/bitcode/oclc_wavefrontsize64_on.bc b/clang/test/Driver/Inputs/rocm-spack/rocm-device-libs-4.0.0-6wnyzz4hgl3hr7uswasnagt7j2adctbs/amdgcn/bitcode/oclc_wavefrontsize64_on.bc new file mode 100644 diff --git a/clang/test/Driver/Inputs/rocm-spack/rocm-device-libs-4.0.0-6wnyzz4hgl3hr7uswasnagt7j2adctbs/amdgcn/bitcode/ocml.bc b/clang/test/Driver/Inputs/rocm-spack/rocm-device-libs-4.0.0-6wnyzz4hgl3hr7uswasnagt7j2adctbs/amdgcn/bitcode/ocml.bc new file mode 100644 diff --git a/clang/test/Driver/Inputs/rocm-spack/rocm-device-libs-4.0.0-6wnyzz4hgl3hr7uswasnagt7j2adctbs/amdgcn/bitcode/opencl.bc b/clang/test/Driver/Inputs/rocm-spack/rocm-device-libs-4.0.0-6wnyzz4hgl3hr7uswasnagt7j2adctbs/amdgcn/bitcode/opencl.bc new file mode 100644 diff --git a/clang/test/Driver/rocm-detect.hip b/clang/test/Driver/rocm-detect.hip --- a/clang/test/Driver/rocm-detect.hip +++ b/clang/test/Driver/rocm-detect.hip @@ -1,6 +1,7 @@ // REQUIRES: clang-driver // REQUIRES: x86-registered-target // REQUIRES: amdgpu-registered-target +// UNSUPPORTED: system-windows // Make sure the appropriate device specific library is available. @@ -16,14 +17,75 @@ // RUN: --rocm-path=%S/Inputs/rocm %s 2>&1 \ // RUN: | FileCheck -check-prefixes=COMMON,GFX902-DEFAULTLIBS %s - // RUN: %clang -### -v -target x86_64-linux-gnu --cuda-gpu-arch=gfx902 -nogpulib \ // RUN: --rocm-path=%S/Inputs/rocm %s 2>&1 \ // RUN: | FileCheck -check-prefixes=COMMON,NODEFAULTLIBS %s +// Test ROCm installation built by SPACK by invoke clang at %T/rocm-spack/llvm-amdgpu-* +// directory through a soft link. + +// RUN: rm -rf %T/rocm-spack +// RUN: cp -r %S/Inputs/rocm-spack %T +// RUN: ln -fs %clang %T/rocm-spack/llvm-amdgpu-4.0.0-ieagcs7inf7runpyfvepqkurasoglq4z/bin/clang +// RUN: %T/rocm-spack/llvm-amdgpu-4.0.0-ieagcs7inf7runpyfvepqkurasoglq4z/bin/clang -### -v \ +// RUN: -target x86_64-linux-gnu --cuda-gpu-arch=gfx900 --print-rocm-search-dirs %s 2>&1 \ +// RUN: | FileCheck -check-prefixes=SPACK %s + +// Test SPACK installation with multiple hip and rocm-device-libs packages of the same +// ROCm release. Clang cannot determine which one to use and emit diagnostics. --hip-path +// and --rocm-device-lib-path can be used to specify them. + +// RUN: cp -r %T/rocm-spack/hip-* %T/rocm-spack/hip-4.0.0-abcd +// RUN: cp -r %T/rocm-spack/rocm-device-libs-* %T/rocm-spack/rocm-device-libs-4.0.0-efgh +// RUN: %T/rocm-spack/llvm-amdgpu-4.0.0-ieagcs7inf7runpyfvepqkurasoglq4z/bin/clang -### -v \ +// RUN: -target x86_64-linux-gnu --cuda-gpu-arch=gfx900 %s 2>&1 \ +// RUN: | FileCheck -check-prefixes=SPACK-MULT %s +// RUN: %T/rocm-spack/llvm-amdgpu-4.0.0-ieagcs7inf7runpyfvepqkurasoglq4z/bin/clang -### -v \ +// RUN: -target x86_64-linux-gnu --cuda-gpu-arch=gfx900 \ +// RUN: --hip-path=%T/rocm-spack/hip-4.0.0-abcd \ +// RUN: --rocm-device-lib-path=%T/rocm-spack/rocm-device-libs-4.0.0-efgh/amdgcn/bitcode \ +// RUN: %s 2>&1 | FileCheck -check-prefixes=SPACK-SET %s + +// Test invalid SPACK ROCm installation missing hip and rocm-device-libs packages. + +// RUN: rm -rf %T/rocm-spack/hip-* +// RUN: rm -rf %T/rocm-spack/rocm-device-libs-* +// RUN: %T/rocm-spack/llvm-amdgpu-4.0.0-ieagcs7inf7runpyfvepqkurasoglq4z/bin/clang -### -v \ +// RUN: -target x86_64-linux-gnu --cuda-gpu-arch=gfx900 %s 2>&1 \ +// RUN: | FileCheck -check-prefixes=SPACK-MISS %s // GFX902-DEFAULTLIBS: error: cannot find ROCm device library for gfx902. Provide its path via --rocm-path or --rocm-device-lib-path, or pass -nogpulib to build without ROCm device library // NODEFAULTLIBS-NOT: error: cannot find // COMMON: "-triple" "amdgcn-amd-amdhsa" + +// SPACK: ROCm installation search path (Spack 4.0.0): [[DIR:.*]] +// SPACK: ROCm installation search path: [[CLANG:.*]] +// SPACK: ROCm installation search path: [[CLANG]]/lib/clang/{{[0-9.]+}} +// SPACK: ROCm installation search path: /opt/rocm +// SPACK: InstalledDir: [[DIR]]/llvm-amdgpu-4.0.0-ieagcs7inf7runpyfvepqkurasoglq4z/bin +// SPACK: Found HIP installation: [[DIR]]/hip-4.0.0-5f63slrursbrvfe2txrrjkynbsywsob5, version 4.0.20214-a2917cd +// SPACK: "-triple" "amdgcn-amd-amdhsa" +// SPACK-SAME: "-mlink-builtin-bitcode" "[[DIR]]/rocm-device-libs-4.0.0-6wnyzz4hgl3hr7uswasnagt7j2adctbs/amdgcn/bitcode/hip.bc" +// SPACK-SAME: "-internal-isystem" "[[DIR]]/hip-4.0.0-5f63slrursbrvfe2txrrjkynbsywsob5/include" + +// SPACK-MULT: InstalledDir: [[DIR:.*]]/llvm-amdgpu-4.0.0-ieagcs7inf7runpyfvepqkurasoglq4z/bin +// SPACK-MULT-DAG: Expecting one SPACK package hip-4.0.0 at [[DIR]] but found more +// SPACK-MULT-DAG: Expecting one SPACK package rocm-device-libs-4.0.0 at [[DIR]] but found more +// SPACK-MULT-NOT: Found HIP installation: [[DIR]]/hip-4.0.0-5f63slrursbrvfe2txrrjkynbsywsob5, version 4.0.20214-a2917cd +// SPACK-MULT-NOT: "-mlink-builtin-bitcode" "[[DIR]]/rocm-device-libs-4.0.0-6wnyzz4hgl3hr7uswasnagt7j2adctbs/amdgcn/bitcode/hip.bc" +// SPACK-MULT-NOT: "-internal-isystem" "[[DIR]]/hip-4.0.0-5f63slrursbrvfe2txrrjkynbsywsob5/include" + +// SPACK-SET: InstalledDir: [[DIR:.*]]/llvm-amdgpu-4.0.0-ieagcs7inf7runpyfvepqkurasoglq4z/bin +// SPACK-SET: Found HIP installation: [[DIR]]/hip-4.0.0-abcd, version 4.0.20214-a2917cd +// SPACK-SET: "-triple" "amdgcn-amd-amdhsa" +// SPACK-SET-SAME: "-mlink-builtin-bitcode" "[[DIR]]/rocm-device-libs-4.0.0-efgh/amdgcn/bitcode/hip.bc" +// SPACK-SET-SAME: "-internal-isystem" "[[DIR]]/hip-4.0.0-abcd/include" + +// SPACK-MISS: InstalledDir: [[DIR:.*]]/llvm-amdgpu-4.0.0-ieagcs7inf7runpyfvepqkurasoglq4z/bin +// SPACK-MISS-DAG: Expecting SPACK package hip-4.0.0 at [[DIR]] but not found +// SPACK-MISS-DAG: Expecting SPACK package rocm-device-libs-4.0.0 at [[DIR]] but not found +// SPACK-MISS-NOT: Found HIP installation: [[DIR]]/hip-4.0.0-5f63slrursbrvfe2txrrjkynbsywsob5, version 4.0.20214-a2917cd +// SPACK-MISS-NOT: "-mlink-builtin-bitcode" "[[DIR]]/rocm-device-libs-4.0.0-6wnyzz4hgl3hr7uswasnagt7j2adctbs/amdgcn/bitcode/hip.bc" +// SPACK-MISS-NOT: "-internal-isystem" "[[DIR]]/hip-4.0.0-5f63slrursbrvfe2txrrjkynbsywsob5/include"