[HIP] Fix rocm detection

Do not detect device library by default in rocm detector.
Only detect device library in Rocm and HIP toolchain.

Separate detection of HIP runtime and Rocm device library.

Detect rocm path by version file in host toolchains.

Also added detecting rocm version and printing rocm
installation path and version with -v.

Fixed include path and device library detection for
ROCm 3.5.

Added --hip-version option. Renamed --hip-device-lib-path
to --rocm-device-lib-path.

Fixed default value for -fhip-new-launch-api.

Added default -std option for HIP.

Differential Revision: https://reviews.llvm.org/D82930
This commit is contained in:
Yaxun (Sam) Liu 2020-07-01 00:00:04 -04:00
parent e628092524
commit 849d4405f5
17 changed files with 385 additions and 126 deletions

View File

@ -56,12 +56,12 @@ def err_drv_no_cuda_libdevice : Error<
"cannot find libdevice for %0. Provide path to different CUDA installation "
"via --cuda-path, or pass -nocudalib to build without linking with libdevice.">;
def err_drv_no_rocm_installation : Error<
"cannot find ROCm installation. Provide its path via --rocm-path, or pass "
"-nogpulib and -nogpuinc to build without ROCm device library and HIP includes.">;
def err_drv_no_rocm_device_lib : Error<
"cannot find device library for %0. Provide path to different ROCm installation "
"via --rocm-path, or pass -nogpulib to build without linking default libraries.">;
"cannot find ROCm device library%select{| for %1}0. Provide its path via --rocm-path or "
"--rocm-device-lib-path, or pass -nogpulib to build without ROCm device library.">;
def err_drv_no_hip_runtime : Error<
"cannot find HIP runtime. Provide its path via --rocm-path, or pass "
"-nogpuinc to build without HIP runtime.">;
def err_drv_cuda_version_unsupported : Error<
"GPU arch %0 is supported by CUDA versions between %1 and %2 (inclusive), "

View File

@ -637,15 +637,19 @@ defm cuda_short_ptr : OptInFFlag<"cuda-short-ptr",
"Use 32-bit pointers for accessing const/local/shared address spaces">;
def rocm_path_EQ : Joined<["--"], "rocm-path=">, Group<i_Group>,
HelpText<"ROCm installation path, used for finding and automatically linking required bitcode libraries.">;
def hip_device_lib_path_EQ : Joined<["--"], "hip-device-lib-path=">, Group<Link_Group>,
HelpText<"HIP device library path. Alternative to rocm-path.">;
def rocm_device_lib_path_EQ : Joined<["--"], "rocm-device-lib-path=">, Group<Link_Group>,
HelpText<"ROCm device library path. Alternative to rocm-path.">;
def : Joined<["--"], "hip-device-lib-path=">, Alias<rocm_device_lib_path_EQ>;
def hip_device_lib_EQ : Joined<["--"], "hip-device-lib=">, Group<Link_Group>,
HelpText<"HIP device library">;
def hip_version_EQ : Joined<["--"], "hip-version=">,
HelpText<"HIP version in the format of major.minor.patch">;
def fhip_dump_offload_linker_script : Flag<["-"], "fhip-dump-offload-linker-script">,
Group<f_Group>, Flags<[NoArgumentUnused, HelpHidden]>;
defm hip_new_launch_api : OptInFFlag<"hip-new-launch-api",
"Use new kernel launching API for HIP">;
defm gpu_allow_device_init : OptInFFlag<"gpu-allow-device-init", "Allow device side init function in HIP">;
"Use", "Don't use", " new kernel launching API for HIP">;
defm gpu_allow_device_init : OptInFFlag<"gpu-allow-device-init",
"Allow", "Don't allow", " device side init function in HIP">;
def gpu_max_threads_per_block_EQ : Joined<["--"], "gpu-max-threads-per-block=">,
Flags<[CC1Option]>,
HelpText<"Default max threads per block for kernel launch bounds for HIP">;

View File

@ -242,7 +242,7 @@ void CGNVCUDARuntime::emitDeviceStub(CodeGenFunction &CGF,
EmittedKernels.push_back({CGF.CurFn, CGF.CurFuncDecl});
if (CudaFeatureEnabled(CGM.getTarget().getSDKVersion(),
CudaFeature::CUDA_USES_NEW_LAUNCH) ||
CGF.getLangOpts().HIPUseNewLaunchAPI)
(CGF.getLangOpts().HIP && CGF.getLangOpts().HIPUseNewLaunchAPI))
emitDeviceStubBodyNew(CGF, Args);
else
emitDeviceStubBodyLegacy(CGF, Args);

View File

@ -21,16 +21,14 @@ using namespace clang::driver::toolchains;
using namespace clang;
using namespace llvm::opt;
void RocmInstallationDetector::scanLibDevicePath() {
assert(!LibDevicePath.empty());
void RocmInstallationDetector::scanLibDevicePath(llvm::StringRef Path) {
assert(!Path.empty());
const StringRef Suffix(".bc");
const StringRef Suffix2(".amdgcn.bc");
std::error_code EC;
for (llvm::vfs::directory_iterator
LI = D.getVFS().dir_begin(LibDevicePath, EC),
LE;
for (llvm::vfs::directory_iterator LI = D.getVFS().dir_begin(Path, EC), LE;
!EC && LI != LE; LI = LI.increment(EC)) {
StringRef FilePath = LI->path();
StringRef FileName = llvm::sys::path::filename(FilePath);
@ -89,24 +87,34 @@ void RocmInstallationDetector::scanLibDevicePath() {
}
}
RocmInstallationDetector::RocmInstallationDetector(
const Driver &D, const llvm::Triple &HostTriple,
const llvm::opt::ArgList &Args)
: D(D) {
struct Candidate {
std::string Path;
bool StrictChecking;
Candidate(std::string Path, bool StrictChecking = false)
: Path(Path), StrictChecking(StrictChecking) {}
};
void RocmInstallationDetector::ParseHIPVersionFile(llvm::StringRef V) {
SmallVector<StringRef, 4> VersionParts;
V.split(VersionParts, '\n');
unsigned Major;
unsigned Minor;
for (auto Part : VersionParts) {
auto Splits = Part.split('=');
if (Splits.first == "HIP_VERSION_MAJOR")
Splits.second.getAsInteger(0, Major);
else if (Splits.first == "HIP_VERSION_MINOR")
Splits.second.getAsInteger(0, Minor);
else if (Splits.first == "HIP_VERSION_PATCH")
VersionPatch = Splits.second.str();
}
VersionMajorMinor = llvm::VersionTuple(Major, Minor);
DetectedVersion =
(Twine(Major) + "." + Twine(Minor) + "." + VersionPatch).str();
}
// For candidate specified by --rocm-path we do not do strict check.
SmallVector<RocmInstallationDetector::Candidate, 4>
RocmInstallationDetector::getInstallationPathCandidates() {
SmallVector<Candidate, 4> Candidates;
if (!RocmPathArg.empty()) {
Candidates.emplace_back(RocmPathArg.str());
return Candidates;
}
if (Args.hasArg(clang::driver::options::OPT_rocm_path_EQ)) {
Candidates.emplace_back(
Args.getLastArgValue(clang::driver::options::OPT_rocm_path_EQ).str());
} else {
// Try to find relative to the compiler binary.
const char *InstallDir = D.getInstalledDir();
@ -124,25 +132,69 @@ RocmInstallationDetector::RocmInstallationDetector(
ParentName = llvm::sys::path::filename(ParentDir);
}
if (ParentName == "llvm") {
// Some versions of the rocm llvm package install to /opt/rocm/llvm/bin
Candidates.emplace_back(llvm::sys::path::parent_path(ParentDir).str(),
/*StrictChecking=*/true);
if (ParentName == "llvm")
ParentDir = llvm::sys::path::parent_path(ParentDir);
Candidates.emplace_back(ParentDir.str(), /*StrictChecking=*/true);
// Device library may be installed in clang resource directory.
Candidates.emplace_back(D.ResourceDir, /*StrictChecking=*/true);
Candidates.emplace_back(D.SysRoot + "/opt/rocm", /*StrictChecking=*/true);
return Candidates;
}
RocmInstallationDetector::RocmInstallationDetector(
const Driver &D, const llvm::Triple &HostTriple,
const llvm::opt::ArgList &Args, bool DetectHIPRuntime, bool DetectDeviceLib)
: D(D) {
RocmPathArg = Args.getLastArgValue(clang::driver::options::OPT_rocm_path_EQ);
RocmDeviceLibPathArg =
Args.getAllArgValues(clang::driver::options::OPT_rocm_device_lib_path_EQ);
if (auto *A = Args.getLastArg(clang::driver::options::OPT_hip_version_EQ)) {
HIPVersionArg = A->getValue();
unsigned Major = 0;
unsigned Minor = 0;
SmallVector<StringRef, 3> Parts;
HIPVersionArg.split(Parts, '.');
if (Parts.size())
Parts[0].getAsInteger(0, Major);
if (Parts.size() > 1)
Parts[1].getAsInteger(0, Minor);
if (Parts.size() > 2)
VersionPatch = Parts[2].str();
if (VersionPatch.empty())
VersionPatch = "0";
if (Major == 0 || Minor == 0)
D.Diag(diag::err_drv_invalid_value)
<< A->getAsString(Args) << HIPVersionArg;
VersionMajorMinor = llvm::VersionTuple(Major, Minor);
DetectedVersion =
(Twine(Major) + "." + Twine(Minor) + "." + VersionPatch).str();
} else {
VersionPatch = DefaultVersionPatch;
VersionMajorMinor =
llvm::VersionTuple(DefaultVersionMajor, DefaultVersionMinor);
DetectedVersion = (Twine(DefaultVersionMajor) + "." +
Twine(DefaultVersionMinor) + "." + VersionPatch)
.str();
}
Candidates.emplace_back(D.SysRoot + "/opt/rocm");
}
bool NoBuiltinLibs = Args.hasArg(options::OPT_nogpulib);
if (DetectHIPRuntime)
detectHIPRuntime();
if (DetectDeviceLib)
detectDeviceLibrary();
}
void RocmInstallationDetector::detectDeviceLibrary() {
assert(LibDevicePath.empty());
if (Args.hasArg(clang::driver::options::OPT_hip_device_lib_path_EQ)) {
LibDevicePath
= Args.getLastArgValue(clang::driver::options::OPT_hip_device_lib_path_EQ);
} else if (const char *LibPathEnv = ::getenv("HIP_DEVICE_LIB_PATH")) {
if (!RocmDeviceLibPathArg.empty())
LibDevicePath = RocmDeviceLibPathArg[RocmDeviceLibPathArg.size() - 1];
else if (const char *LibPathEnv = ::getenv("HIP_DEVICE_LIB_PATH"))
LibDevicePath = LibPathEnv;
}
auto &FS = D.getVFS();
if (!LibDevicePath.empty()) {
@ -152,61 +204,109 @@ RocmInstallationDetector::RocmInstallationDetector(
if (!FS.exists(LibDevicePath))
return;
scanLibDevicePath();
IsValid = allGenericLibsValid() && !LibDeviceMap.empty();
scanLibDevicePath(LibDevicePath);
HasDeviceLibrary = allGenericLibsValid() && !LibDeviceMap.empty();
return;
}
for (const auto &Candidate : Candidates) {
InstallPath = Candidate.Path;
if (InstallPath.empty() || !FS.exists(InstallPath))
continue;
// The install path situation in old versions of ROCm is a real mess, and
// use a different install layout. Multiple copies of the device libraries
// 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.
//
// The desired structure is (${ROCM_ROOT} or
// ${OPENCL_ROOT})/amdgcn/bitcode/*, so try to detect this layout.
// BinPath = InstallPath + "/bin";
llvm::sys::path::append(IncludePath, InstallPath, "include");
llvm::sys::path::append(LibDevicePath, InstallPath, "amdgcn", "bitcode");
// We don't need the include path for OpenCL, since clang already ships with
// the default header.
auto Candidates = getInstallationPathCandidates();
for (const auto &Candidate : Candidates) {
auto CandidatePath = Candidate.Path;
// Check device library exists at the given path.
auto CheckDeviceLib = [&](StringRef Path) {
bool CheckLibDevice = (!NoBuiltinLibs || Candidate.StrictChecking);
if (CheckLibDevice && !FS.exists(LibDevicePath))
continue;
if (CheckLibDevice && !FS.exists(Path))
return false;
scanLibDevicePath();
scanLibDevicePath(Path);
if (!NoBuiltinLibs) {
// Check that the required non-target libraries are all available.
if (!allGenericLibsValid())
continue;
return false;
// Check that we have found at least one libdevice that we can link in if
// -nobuiltinlib hasn't been specified.
// Check that we have found at least one libdevice that we can link in
// if -nobuiltinlib hasn't been specified.
if (LibDeviceMap.empty())
continue;
return false;
}
return true;
};
IsValid = true;
break;
// The possible structures are:
// - ${ROCM_ROOT}/amdgcn/bitcode/*
// - ${ROCM_ROOT}/lib/*
// - ${ROCM_ROOT}/lib/bitcode/*
// so try to detect these layouts.
static llvm::SmallVector<const char *, 2> SubDirsList[] = {
{"amdgcn", "bitcode"},
{"lib"},
{"lib", "bitcode"},
};
// Make a path by appending sub-directories to InstallPath.
auto MakePath = [&](const llvm::ArrayRef<const char *> &SubDirs) {
auto Path = CandidatePath;
for (auto SubDir : SubDirs)
llvm::sys::path::append(Path, SubDir);
return Path;
};
for (auto SubDirs : SubDirsList) {
LibDevicePath = MakePath(SubDirs);
HasDeviceLibrary = CheckDeviceLib(LibDevicePath);
if (HasDeviceLibrary)
return;
}
}
}
void RocmInstallationDetector::detectHIPRuntime() {
auto Candidates = getInstallationPathCandidates();
auto &FS = D.getVFS();
for (const auto &Candidate : Candidates) {
InstallPath = Candidate.Path;
if (InstallPath.empty() || !FS.exists(InstallPath))
continue;
BinPath = InstallPath;
llvm::sys::path::append(BinPath, "bin");
IncludePath = InstallPath;
llvm::sys::path::append(IncludePath, "include");
LibPath = InstallPath;
llvm::sys::path::append(LibPath, "lib");
llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> VersionFile =
FS.getBufferForFile(BinPath + "/.hipVersion");
if (!VersionFile && Candidate.StrictChecking)
continue;
if (HIPVersionArg.empty() && VersionFile)
ParseHIPVersionFile((*VersionFile)->getBuffer());
HasHIPRuntime = true;
return;
}
HasHIPRuntime = false;
}
void RocmInstallationDetector::print(raw_ostream &OS) const {
if (isValid())
OS << "Found ROCm installation: " << InstallPath << '\n';
if (hasHIPRuntime())
OS << "Found HIP installation: " << InstallPath << ", version "
<< DetectedVersion << '\n';
}
void RocmInstallationDetector::AddHIPIncludeArgs(const ArgList &DriverArgs,
ArgStringList &CC1Args) const {
bool UsesRuntimeWrapper = VersionMajorMinor > llvm::VersionTuple(3, 5);
if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) {
// HIP header includes standard library wrapper headers under clang
// cuda_wrappers directory. Since these wrapper headers include_next
@ -218,9 +318,12 @@ void RocmInstallationDetector::AddHIPIncludeArgs(const ArgList &DriverArgs,
// Since standard C++ and other clang include paths are added in other
// places after this function, here we only need to make sure wrapper
// include path is added.
//
// ROCm 3.5 does not fully support the wrapper headers. Therefore it needs
// a workaround.
SmallString<128> P(D.ResourceDir);
llvm::sys::path::append(P, "include");
llvm::sys::path::append(P, "cuda_wrappers");
if (UsesRuntimeWrapper)
llvm::sys::path::append(P, "include", "cuda_wrappers");
CC1Args.push_back("-internal-isystem");
CC1Args.push_back(DriverArgs.MakeArgString(P));
}
@ -228,15 +331,15 @@ void RocmInstallationDetector::AddHIPIncludeArgs(const ArgList &DriverArgs,
if (DriverArgs.hasArg(options::OPT_nogpuinc))
return;
if (!isValid()) {
D.Diag(diag::err_drv_no_rocm_installation);
if (!hasHIPRuntime()) {
D.Diag(diag::err_drv_no_hip_runtime);
return;
}
CC1Args.push_back("-internal-isystem");
CC1Args.push_back(DriverArgs.MakeArgString(getIncludePath()));
CC1Args.push_back("-include");
CC1Args.push_back("__clang_hip_runtime_wrapper.h");
if (UsesRuntimeWrapper)
CC1Args.append({"-include", "__clang_hip_runtime_wrapper.h"});
}
void amdgpu::Linker::ConstructJob(Compilation &C, const JobAction &JA,
@ -387,7 +490,8 @@ bool AMDGPUToolChain::isWave64(const llvm::opt::ArgList &DriverArgs,
ROCMToolChain::ROCMToolChain(const Driver &D, const llvm::Triple &Triple,
const ArgList &Args)
: AMDGPUToolChain(D, Triple, Args),
RocmInstallation(D, Triple, Args) { }
RocmInstallation(D, Triple, Args, /*DetectHIPRuntime=*/false,
/*DetectDeviceLib=*/true) {}
void AMDGPUToolChain::addClangTargetOptions(
const llvm::opt::ArgList &DriverArgs,
@ -418,8 +522,8 @@ void ROCMToolChain::addClangTargetOptions(
if (DriverArgs.hasArg(options::OPT_nogpulib))
return;
if (!RocmInstallation.isValid()) {
getDriver().Diag(diag::err_drv_no_rocm_installation);
if (!RocmInstallation.hasDeviceLibrary()) {
getDriver().Diag(diag::err_drv_no_rocm_device_lib) << 0;
return;
}
@ -429,7 +533,7 @@ void ROCMToolChain::addClangTargetOptions(
const StringRef CanonArch = llvm::AMDGPU::getArchNameAMDGCN(Kind);
std::string LibDeviceFile = RocmInstallation.getLibDeviceFile(CanonArch);
if (LibDeviceFile.empty()) {
getDriver().Diag(diag::err_drv_no_rocm_device_lib) << GpuArch;
getDriver().Diag(diag::err_drv_no_rocm_device_lib) << 1 << GpuArch;
return;
}

View File

@ -3953,7 +3953,8 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
}
}
const llvm::Triple *AuxTriple = IsCuda ? TC.getAuxTriple() : nullptr;
const llvm::Triple *AuxTriple =
(IsCuda || IsHIP) ? TC.getAuxTriple() : nullptr;
bool IsWindowsMSVC = RawTriple.isWindowsMSVCEnvironment();
bool IsIAMCU = RawTriple.isOSIAMCU();
@ -4868,10 +4869,10 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
options::OPT_finstrument_functions_after_inlining,
options::OPT_finstrument_function_entry_bare);
// NVPTX doesn't support PGO or coverage. There's no runtime support for
// sampling, overhead of call arc collection is way too high and there's no
// way to collect the output.
if (!Triple.isNVPTX())
// NVPTX/AMDGCN doesn't support PGO or coverage. There's no runtime support
// for sampling, overhead of call arc collection is way too high and there's
// no way to collect the output.
if (!Triple.isNVPTX() && !Triple.isAMDGCN())
addPGOAndCoverageFlags(TC, C, D, Output, Args, CmdArgs);
Args.AddLastArg(CmdArgs, options::OPT_fclang_abi_compat_EQ);
@ -4990,6 +4991,11 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
Args.AddLastArg(CmdArgs, options::OPT_ftrigraphs,
options::OPT_fno_trigraphs);
// HIP headers has minimum C++ standard requirements. Therefore set the
// default language standard.
if (IsHIP)
CmdArgs.push_back(IsWindowsMSVC ? "-std=c++14" : "-std=c++11");
}
// GCC's behavior for -Wwrite-strings is a bit strange:
@ -5398,8 +5404,8 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
// Forward -cl options to -cc1
RenderOpenCLOptions(Args, CmdArgs);
if (Args.hasFlag(options::OPT_fhip_new_launch_api,
options::OPT_fno_hip_new_launch_api, false))
if (IsHIP && Args.hasFlag(options::OPT_fhip_new_launch_api,
options::OPT_fno_hip_new_launch_api, true))
CmdArgs.push_back("-fhip-new-launch-api");
if (Arg *A = Args.getLastArg(options::OPT_fcf_protection_EQ)) {

View File

@ -2658,6 +2658,7 @@ void Generic_GCC::printVerboseInfo(raw_ostream &OS) const {
// Print the information about how we detected the GCC installation.
GCCInstallation.print(OS);
CudaInstallation.print(OS);
RocmInstallation.print(OS);
}
bool Generic_GCC::IsUnwindTablesDefault(const ArgList &Args) const {

View File

@ -224,6 +224,7 @@ HIPToolChain::HIPToolChain(const Driver &D, const llvm::Triple &Triple,
// Lookup binaries into the driver directory, this is used to
// discover the clang-offload-bundler executable.
getProgramPaths().push_back(getDriver().Dir);
RocmInstallation.detectHIPRuntime();
}
void HIPToolChain::addClangTargetOptions(
@ -279,8 +280,7 @@ void HIPToolChain::addClangTargetOptions(
ArgStringList LibraryPaths;
// Find in --hip-device-lib-path and HIP_LIBRARY_PATH.
for (auto Path :
DriverArgs.getAllArgValues(options::OPT_hip_device_lib_path_EQ))
for (auto Path : RocmInstallation.getRocmDeviceLibPathArg())
LibraryPaths.push_back(DriverArgs.MakeArgString(Path));
addDirectoryList(DriverArgs, LibraryPaths, "", "HIP_DEVICE_LIB_PATH");
@ -291,14 +291,14 @@ void HIPToolChain::addClangTargetOptions(
for (auto Lib : BCLibs)
addBCLib(getDriver(), DriverArgs, CC1Args, LibraryPaths, Lib);
} else {
if (!RocmInstallation.isValid()) {
getDriver().Diag(diag::err_drv_no_rocm_installation);
if (!RocmInstallation.hasDeviceLibrary()) {
getDriver().Diag(diag::err_drv_no_rocm_device_lib) << 0;
return;
}
std::string LibDeviceFile = RocmInstallation.getLibDeviceFile(CanonArch);
if (LibDeviceFile.empty()) {
getDriver().Diag(diag::err_drv_no_rocm_device_lib) << GpuArch;
getDriver().Diag(diag::err_drv_no_rocm_device_lib) << 1 << GpuArch;
return;
}

View File

@ -807,6 +807,7 @@ void MSVCToolChain::AddHIPIncludeArgs(const ArgList &DriverArgs,
void MSVCToolChain::printVerboseInfo(raw_ostream &OS) const {
CudaInstallation.print(OS);
RocmInstallation.print(OS);
}
// Windows SDKs and VC Toolchains group their contents into subdirectories based

View File

@ -18,6 +18,7 @@
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/Triple.h"
#include "llvm/Option/ArgList.h"
#include "llvm/Support/VersionTuple.h"
namespace clang {
namespace driver {
@ -38,11 +39,43 @@ private:
}
};
// Installation path candidate.
struct Candidate {
llvm::SmallString<0> Path;
bool StrictChecking;
Candidate(std::string Path, bool StrictChecking = false)
: Path(Path), StrictChecking(StrictChecking) {}
};
const Driver &D;
bool IsValid = false;
// RocmVersion Version = RocmVersion::UNKNOWN;
bool HasHIPRuntime = false;
bool HasDeviceLibrary = false;
// Default version if not detected or specified.
const unsigned DefaultVersionMajor = 3;
const unsigned DefaultVersionMinor = 5;
const char *DefaultVersionPatch = "0";
// The version string in Major.Minor.Patch format.
std::string DetectedVersion;
// Version containing major and minor.
llvm::VersionTuple VersionMajorMinor;
// Version containing patch.
std::string VersionPatch;
// ROCm path specified by --rocm-path.
StringRef RocmPathArg;
// ROCm device library paths specified by --rocm-device-lib-path.
std::vector<std::string> RocmDeviceLibPathArg;
// HIP version specified by --hip-version.
StringRef HIPVersionArg;
// Wheter -nogpulib is specified.
bool NoBuiltinLibs = false;
// Paths
SmallString<0> InstallPath;
// SmallString<0> BinPath;
SmallString<0> BinPath;
SmallString<0> LibPath;
SmallString<0> LibDevicePath;
SmallString<0> IncludePath;
@ -74,11 +107,15 @@ private:
// CheckRocmVersionSupportsArch.
mutable llvm::SmallSet<CudaArch, 4> ArchsWithBadVersion;
void scanLibDevicePath();
void scanLibDevicePath(llvm::StringRef Path);
void ParseHIPVersionFile(llvm::StringRef V);
SmallVector<Candidate, 4> getInstallationPathCandidates();
public:
RocmInstallationDetector(const Driver &D, const llvm::Triple &HostTriple,
const llvm::opt::ArgList &Args);
const llvm::opt::ArgList &Args,
bool DetectHIPRuntime = true,
bool DetectDeviceLib = false);
/// Add arguments needed to link default bitcode libraries.
void addCommonBitcodeLibCC1Args(const llvm::opt::ArgList &DriverArgs,
@ -93,8 +130,12 @@ public:
/// most one error per Arch.
void CheckRocmVersionSupportsArch(CudaArch Arch) const;
/// Check whether we detected a valid Rocm install.
bool isValid() const { return IsValid; }
/// Check whether we detected a valid HIP runtime.
bool hasHIPRuntime() const { return HasHIPRuntime; }
/// Check whether we detected a valid ROCm device library.
bool hasDeviceLibrary() const { return HasDeviceLibrary; }
/// Print information about the detected ROCm installation.
void print(raw_ostream &OS) const;
@ -163,6 +204,22 @@ public:
void AddHIPIncludeArgs(const llvm::opt::ArgList &DriverArgs,
llvm::opt::ArgStringList &CC1Args) const;
void detectDeviceLibrary();
void detectHIPRuntime();
/// Get the values for --rocm-device-lib-path arguments
std::vector<std::string> getRocmDeviceLibPathArg() const {
return RocmDeviceLibPathArg;
}
/// Get the value for --rocm-path argument
StringRef getRocmPathArg() const { return RocmPathArg; }
/// Get the value for --hip-version argument
StringRef getHIPVersionArg() const { return HIPVersionArg; }
std::string getHIPVersion() const { return DetectedVersion; }
};
} // end namespace driver

View File

@ -0,0 +1,4 @@
# Auto-generated by cmake
HIP_VERSION_MAJOR=3
HIP_VERSION_MINOR=6
HIP_VERSION_PATCH=20214-a2917cd

View File

@ -37,3 +37,15 @@
// skip check of standard C++ include path
// CLANG-SAME: "-internal-isystem" "{{.*}}clang/{{.*}}/include"
// NOCLANG-NOT: "{{.*}}clang/{{.*}}/include"
// RUN: %clang -c -### -target x86_64-unknown-linux-gnu --cuda-gpu-arch=gfx900 \
// RUN: -std=c++11 --rocm-path=%S/Inputs/rocm -nogpulib %s 2>&1 \
// RUN: --hip-version=3.5 | FileCheck -check-prefixes=ROCM35 %s
// ROCM35-LABEL: "{{[^"]*}}clang{{[^"]*}}" "-cc1"
// ROCM35-NOT: "{{.*}}clang/{{.*}}/include/cuda_wrappers"
// ROCM35-SAME: "-internal-isystem" "{{[^"]*}}clang/{{[^"]*}}"
// ROCM35-SAME: "-internal-isystem" "{{[^"]*}}Inputs/rocm/include"
// ROCM35-NOT: "-include" "__clang_hip_runtime_wrapper.h"
// skip check of standard C++ include path
// ROCM35-SAME: "-internal-isystem" "{{[^"]*}}clang/{{[^"]*}}/include"

View File

@ -0,0 +1,17 @@
// REQUIRES: clang-driver
// REQUIRES: x86-registered-target
// REQUIRES: amdgpu-registered-target
// By default FE assumes -fhip-new-launch-api.
// RUN: %clang -### -target x86_64-unknown-linux-gnu -offload-arch=gfx906 %s \
// RUN: 2>&1 | FileCheck -check-prefixes=NEW %s
// NEW: "-fhip-new-launch-api"
// RUN: %clang -### -target x86_64-unknown-linux-gnu -offload-arch=gfx906 %s \
// RUN: -fhip-new-launch-api 2>&1 | FileCheck -check-prefixes=NEW %s
// NEW: "-fhip-new-launch-api"
// RUN: %clang -### -target x86_64-unknown-linux-gnu -offload-arch=gfx906 %s \
// RUN: -fno-hip-new-launch-api 2>&1 | FileCheck -check-prefixes=OLD %s
// OLD-NOT: "-fhip-new-launch-api"

View File

@ -0,0 +1,23 @@
// REQUIRES: clang-driver
// REQUIRES: x86-registered-target
// REQUIRES: amdgpu-registered-target
// RUN: %clang -### -target x86_64-unknown-linux-gnu -offload-arch=gfx906 %s \
// RUN: 2>&1 | FileCheck -check-prefixes=DEFAULT %s
// DEFAULT: "{{.*}}clang{{.*}}" "-cc1"{{.*}}"-fcuda-is-device"{{.*}}"-std=c++11"
// DEFAULT: "{{.*}}clang{{.*}}" "-cc1"{{.*}}"-std=c++11"
// RUN: %clang -### -target x86_64-unknown-linux-gnu -offload-arch=gfx906 %s \
// RUN: -std=c++17 %s 2>&1 | FileCheck -check-prefixes=SPECIFIED %s
// SPECIFIED: "{{.*}}clang{{.*}}" "-cc1"{{.*}}"-fcuda-is-device"{{.*}}"-std=c++17"
// SPECIFIED: "{{.*}}clang{{.*}}" "-cc1"{{.*}}"-std=c++17"
// RUN: %clang -### -target x86_64-pc-windows-msvc -offload-arch=gfx906 %s \
// RUN: 2>&1 | FileCheck -check-prefixes=MSVC-DEF %s
// MSVC-DEF: "{{.*}}clang{{.*}}" "-cc1"{{.*}}"-fcuda-is-device"{{.*}}"-std=c++14"
// MSVC-DEF: "{{.*}}clang{{.*}}" "-cc1"{{.*}}"-std=c++14"
// RUN: %clang -### -target x86_64-pc-windows-msvc -offload-arch=gfx906 %s \
// RUN: -std=c++17 %s 2>&1 | FileCheck -check-prefixes=MSVC-SPEC %s
// MSVC-SPEC: "{{.*}}clang{{.*}}" "-cc1"{{.*}}"-fcuda-is-device"{{.*}}"-std=c++17"
// MSVC-SPEC: "{{.*}}clang{{.*}}" "-cc1"{{.*}}"-std=c++17"

View File

@ -0,0 +1,30 @@
// REQUIRES: clang-driver
// REQUIRES: x86-registered-target
// REQUIRES: amdgpu-registered-target
// RUN: %clang -v --rocm-path=%S/Inputs/rocm 2>&1 \
// RUN: | FileCheck -check-prefixes=FOUND %s
// FOUND: Found HIP installation: {{.*Inputs.*rocm}}, version 3.6.20214-a2917cd
// When --rocm-path is set and .hipVersion is not found, use default version
// RUN: %clang -v --rocm-path=%S 2>&1 \
// RUN: | FileCheck -check-prefixes=DEFAULT %s
// DEFAULT: Found HIP installation: {{.*Driver}}, version 3.5.
// RUN: %clang -v --rocm-path=%S --hip-version=3.7.0 2>&1 \
// RUN: | FileCheck -check-prefixes=SPECIFIED %s
// SPECIFIED: Found HIP installation: {{.*Driver}}, version 3.7.0
// RUN: %clang -v --rocm-path=%S --hip-version=3.7 2>&1 \
// RUN: | FileCheck -check-prefixes=SPECIFIED2 %s
// SPECIFIED2: Found HIP installation: {{.*Driver}}, version 3.7.0
// RUN: not %clang -v --rocm-path=%S --hip-version=x.y 2>&1 \
// RUN: | FileCheck -check-prefixes=INVALID %s
// INVALID: error: invalid value 'x.y' in '--hip-version=x.y'

View File

@ -16,6 +16,6 @@
// RUN: | FileCheck -check-prefixes=COMMON,GFX902,NODEFAULTLIBS %s
// GFX902-DEFAULTLIBS: error: cannot find device library for gfx902. Provide path to different ROCm installation via --rocm-path, or pass -nogpulib to build without linking default libraries.
// 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

View File

@ -22,6 +22,6 @@
// RUN: | FileCheck -check-prefixes=COMMON,GFX902,NODEFAULTLIBS %s
// GFX902-DEFAULTLIBS: error: cannot find device library for gfx902. Provide path to different ROCm installation via --rocm-path, or pass -nogpulib to build without linking default libraries.
// 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

View File

@ -5,7 +5,7 @@
// RUN: %clang -### --sysroot=%s/no-rocm-there -target amdgcn--amdhsa %s 2>&1 | FileCheck %s --check-prefix ERR
// RUN: %clang -### --rocm-path=%s/no-rocm-there -target amdgcn--amdhsa %s 2>&1 | FileCheck %s --check-prefix ERR
// ERR: cannot find ROCm installation. Provide its path via --rocm-path, or pass -nogpulib and -nogpuinc to build without ROCm device library and HIP includes.
// ERR: cannot find ROCm device library. Provide its path via --rocm-path or --rocm-device-lib-path, or pass -nogpulib to build without ROCm device library
// Accept nogpulib or nostdlib for OpenCL.
// RUN: %clang -### -nogpulib --rocm-path=%s/no-rocm-there %s 2>&1 | FileCheck %s --check-prefix OK