mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2025-01-15 20:51:35 +00:00
[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:
parent
e628092524
commit
849d4405f5
@ -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), "
|
||||
|
@ -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">;
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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)) {
|
||||
|
@ -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 {
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
4
clang/test/Driver/Inputs/rocm/bin/.hipVersion
Normal file
4
clang/test/Driver/Inputs/rocm/bin/.hipVersion
Normal file
@ -0,0 +1,4 @@
|
||||
# Auto-generated by cmake
|
||||
HIP_VERSION_MAJOR=3
|
||||
HIP_VERSION_MINOR=6
|
||||
HIP_VERSION_PATCH=20214-a2917cd
|
@ -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"
|
||||
|
17
clang/test/Driver/hip-launch-api.hip
Normal file
17
clang/test/Driver/hip-launch-api.hip
Normal 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"
|
23
clang/test/Driver/hip-std.hip
Normal file
23
clang/test/Driver/hip-std.hip
Normal 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"
|
30
clang/test/Driver/hip-version.hip
Normal file
30
clang/test/Driver/hip-version.hip
Normal 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'
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user