[clang] 8ac35bd - [CUDA][HIP] Support CUID in new driver (#122859)
via cfe-commits
cfe-commits at lists.llvm.org
Wed Jan 15 07:58:29 PST 2025
Author: Yaxun (Sam) Liu
Date: 2025-01-15T10:58:25-05:00
New Revision: 8ac35bda18229e28e1638756a5187aa2608a4b50
URL: https://github.com/llvm/llvm-project/commit/8ac35bda18229e28e1638756a5187aa2608a4b50
DIFF: https://github.com/llvm/llvm-project/commit/8ac35bda18229e28e1638756a5187aa2608a4b50.diff
LOG: [CUDA][HIP] Support CUID in new driver (#122859)
CUID is needed by CUDA/HIP for supporting accessing static device
variables in host function.
Currently CUID is only supported by the old driver for CUDA/HIP. The new
driver does not support it, which causes CUDA/HIP programs using static
device variables in host functions to fail with the new driver for
CUDA/HIP.
This patch refactors the CUID support in the old driver so that CUID is
supported by both the old and the new drivers for CUDA/HIP.
Added:
Modified:
clang/include/clang/Driver/Driver.h
clang/lib/Driver/Driver.cpp
clang/test/Driver/hip-cuid.hip
Removed:
################################################################################
diff --git a/clang/include/clang/Driver/Driver.h b/clang/include/clang/Driver/Driver.h
index 80bce574a3b647..e6d1e1f888f255 100644
--- a/clang/include/clang/Driver/Driver.h
+++ b/clang/include/clang/Driver/Driver.h
@@ -72,6 +72,29 @@ enum ModuleHeaderMode {
HeaderMode_System
};
+/// Options for specifying CUID used by CUDA/HIP for uniquely identifying
+/// compilation units.
+class CUIDOptions {
+public:
+ enum class Kind { Hash, Random, Fixed, None, Invalid };
+
+ CUIDOptions() = default;
+ CUIDOptions(const CUIDOptions &) = default;
+ CUIDOptions(llvm::opt::DerivedArgList &Args, const Driver &D);
+
+ // Get the CUID for an input string
+ std::string getCUID(StringRef InputFile,
+ llvm::opt::DerivedArgList &Args) const;
+
+ bool isEnabled() const {
+ return UseCUID != Kind::None && UseCUID != Kind::Invalid;
+ }
+
+private:
+ Kind UseCUID = Kind::None;
+ StringRef FixedCUID;
+};
+
/// Driver - Encapsulate logic for constructing compilation processes
/// from a set of gcc-driver-like command line arguments.
class Driver {
@@ -119,6 +142,9 @@ class Driver {
/// LTO mode selected via -f(no-offload-)?lto(=.*)? options.
LTOKind OffloadLTOMode;
+ /// Options for CUID
+ CUIDOptions CUIDOpts;
+
public:
enum OpenMPRuntimeKind {
/// An unknown OpenMP runtime. We can't generate effective OpenMP code
@@ -501,10 +527,11 @@ class Driver {
/// \param C - The compilation that is being built.
/// \param Args - The input arguments.
/// \param Input - The input type and arguments
+ /// \param CUID - The CUID for \p Input
/// \param HostAction - The host action used in the offloading toolchain.
Action *BuildOffloadingActions(Compilation &C,
llvm::opt::DerivedArgList &Args,
- const InputTy &Input,
+ const InputTy &Input, StringRef CUID,
Action *HostAction) const;
/// Returns the set of bound architectures active for this offload kind.
@@ -728,6 +755,9 @@ class Driver {
/// Get the specific kind of offload LTO being performed.
LTOKind getOffloadLTOMode() const { return OffloadLTOMode; }
+ /// Get the CUID option.
+ const CUIDOptions &getCUIDOpts() const { return CUIDOpts; }
+
private:
/// Tries to load options from configuration files.
diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp
index eefbdca805739e..7767c81d654dc3 100644
--- a/clang/lib/Driver/Driver.cpp
+++ b/clang/lib/Driver/Driver.cpp
@@ -197,6 +197,50 @@ std::string Driver::GetResourcesPath(StringRef BinaryPath) {
return std::string(P);
}
+CUIDOptions::CUIDOptions(llvm::opt::DerivedArgList &Args, const Driver &D)
+ : UseCUID(Kind::Hash) {
+ if (Arg *A = Args.getLastArg(options::OPT_fuse_cuid_EQ)) {
+ StringRef UseCUIDStr = A->getValue();
+ UseCUID = llvm::StringSwitch<Kind>(UseCUIDStr)
+ .Case("hash", Kind::Hash)
+ .Case("random", Kind::Random)
+ .Case("none", Kind::None)
+ .Default(Kind::Invalid);
+ if (UseCUID == Kind::Invalid)
+ D.Diag(clang::diag::err_drv_invalid_value)
+ << A->getAsString(Args) << UseCUIDStr;
+ }
+
+ FixedCUID = Args.getLastArgValue(options::OPT_cuid_EQ);
+ if (!FixedCUID.empty())
+ UseCUID = Kind::Fixed;
+}
+
+std::string CUIDOptions::getCUID(StringRef InputFile,
+ llvm::opt::DerivedArgList &Args) const {
+ std::string CUID = FixedCUID.str();
+ if (CUID.empty()) {
+ if (UseCUID == Kind::Random)
+ CUID = llvm::utohexstr(llvm::sys::Process::GetRandomNumber(),
+ /*LowerCase=*/true);
+ else if (UseCUID == Kind::Hash) {
+ llvm::MD5 Hasher;
+ llvm::MD5::MD5Result Hash;
+ SmallString<256> RealPath;
+ llvm::sys::fs::real_path(InputFile, RealPath,
+ /*expand_tilde=*/true);
+ Hasher.update(RealPath);
+ for (auto *A : Args) {
+ if (A->getOption().matches(options::OPT_INPUT))
+ continue;
+ Hasher.update(A->getAsString(Args));
+ }
+ Hasher.final(Hash);
+ CUID = llvm::utohexstr(Hash.low(), /*LowerCase=*/true);
+ }
+ }
+ return CUID;
+}
Driver::Driver(StringRef ClangExecutable, StringRef TargetTriple,
DiagnosticsEngine &Diags, std::string Title,
IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS)
@@ -875,6 +919,9 @@ void Driver::CreateOffloadingDeviceToolChains(Compilation &C,
C.addOffloadDeviceToolChain(HIPTC, OFK);
}
+ if (IsCuda || IsHIP)
+ CUIDOpts = CUIDOptions(C.getArgs(), *this);
+
//
// OpenMP
//
@@ -3161,19 +3208,15 @@ class OffloadingActionBuilder final {
/// Default GPU architecture if there's no one specified.
OffloadArch DefaultOffloadArch = OffloadArch::UNKNOWN;
- /// Method to generate compilation unit ID specified by option
- /// '-fuse-cuid='.
- enum UseCUIDKind { CUID_Hash, CUID_Random, CUID_None, CUID_Invalid };
- UseCUIDKind UseCUID = CUID_Hash;
-
- /// Compilation unit ID specified by option '-cuid='.
- StringRef FixedCUID;
+ /// Compilation unit ID specified by option '-fuse-cuid=' or'-cuid='.
+ const CUIDOptions &CUIDOpts;
public:
CudaActionBuilderBase(Compilation &C, DerivedArgList &Args,
const Driver::InputList &Inputs,
Action::OffloadKind OFKind)
- : DeviceActionBuilder(C, Args, Inputs, OFKind) {
+ : DeviceActionBuilder(C, Args, Inputs, OFKind),
+ CUIDOpts(C.getDriver().getCUIDOpts()) {
CompileDeviceOnly = C.getDriver().offloadDeviceOnly();
Relocatable = Args.hasFlag(options::OPT_fgpu_rdc,
@@ -3204,28 +3247,8 @@ class OffloadingActionBuilder final {
// Set the flag to true, so that the builder acts on the current input.
IsActive = true;
- std::string CUID = FixedCUID.str();
- if (CUID.empty()) {
- if (UseCUID == CUID_Random)
- CUID = llvm::utohexstr(llvm::sys::Process::GetRandomNumber(),
- /*LowerCase=*/true);
- else if (UseCUID == CUID_Hash) {
- llvm::MD5 Hasher;
- llvm::MD5::MD5Result Hash;
- SmallString<256> RealPath;
- llvm::sys::fs::real_path(IA->getInputArg().getValue(), RealPath,
- /*expand_tilde=*/true);
- Hasher.update(RealPath);
- for (auto *A : Args) {
- if (A->getOption().matches(options::OPT_INPUT))
- continue;
- Hasher.update(A->getAsString(Args));
- }
- Hasher.final(Hash);
- CUID = llvm::utohexstr(Hash.low(), /*LowerCase=*/true);
- }
- }
- IA->setId(CUID);
+ if (CUIDOpts.isEnabled())
+ IA->setId(CUIDOpts.getCUID(IA->getInputArg().getValue(), Args));
if (CompileHostOnly)
return ABRT_Success;
@@ -3351,21 +3374,6 @@ class OffloadingActionBuilder final {
CompileHostOnly = C.getDriver().offloadHostOnly();
EmitLLVM = Args.getLastArg(options::OPT_emit_llvm);
EmitAsm = Args.getLastArg(options::OPT_S);
- FixedCUID = Args.getLastArgValue(options::OPT_cuid_EQ);
- if (Arg *A = Args.getLastArg(options::OPT_fuse_cuid_EQ)) {
- StringRef UseCUIDStr = A->getValue();
- UseCUID = llvm::StringSwitch<UseCUIDKind>(UseCUIDStr)
- .Case("hash", CUID_Hash)
- .Case("random", CUID_Random)
- .Case("none", CUID_None)
- .Default(CUID_Invalid);
- if (UseCUID == CUID_Invalid) {
- C.getDriver().Diag(diag::err_drv_invalid_value)
- << A->getAsString(Args) << UseCUIDStr;
- C.setContainsError();
- return true;
- }
- }
// --offload and --offload-arch options are mutually exclusive.
if (Args.hasArgNoClaim(options::OPT_offload_EQ) &&
@@ -4366,6 +4374,12 @@ void Driver::BuildActions(Compilation &C, DerivedArgList &Args,
// Build the pipeline for this file.
Action *Current = C.MakeAction<InputAction>(*InputArg, InputType);
+ std::string CUID;
+ if (CUIDOpts.isEnabled() && types::isSrcFile(InputType)) {
+ CUID = CUIDOpts.getCUID(InputArg->getValue(), Args);
+ cast<InputAction>(Current)->setId(CUID);
+ }
+
// Use the current host action in any of the offloading actions, if
// required.
if (!UseNewOffloadingDriver)
@@ -4429,7 +4443,7 @@ void Driver::BuildActions(Compilation &C, DerivedArgList &Args,
// Try to build the offloading actions and add the result as a dependency
// to the host.
if (UseNewOffloadingDriver)
- Current = BuildOffloadingActions(C, Args, I, Current);
+ Current = BuildOffloadingActions(C, Args, I, CUID, Current);
// Use the current host action in any of the offloading actions, if
// required.
else if (OffloadBuilder->addHostDependenceToDeviceActions(Current,
@@ -4766,7 +4780,7 @@ Driver::getOffloadArchs(Compilation &C, const llvm::opt::DerivedArgList &Args,
Action *Driver::BuildOffloadingActions(Compilation &C,
llvm::opt::DerivedArgList &Args,
- const InputTy &Input,
+ const InputTy &Input, StringRef CUID,
Action *HostAction) const {
// Don't build offloading actions if explicitly disabled or we do not have a
// valid source input and compile action to embed it in. If preprocessing only
@@ -4807,13 +4821,13 @@ Action *Driver::BuildOffloadingActions(Compilation &C,
llvm::DenseSet<StringRef> Arches = getOffloadArchs(C, Args, Kind, TC);
SmallVector<StringRef, 0> Sorted(Arches.begin(), Arches.end());
llvm::sort(Sorted);
- for (StringRef Arch : Sorted)
+ for (StringRef Arch : Sorted) {
TCAndArchs.push_back(std::make_pair(TC, Arch));
+ DeviceActions.push_back(
+ C.MakeAction<InputAction>(*InputArg, InputType, CUID));
+ }
}
- for (unsigned I = 0, E = TCAndArchs.size(); I != E; ++I)
- DeviceActions.push_back(C.MakeAction<InputAction>(*InputArg, InputType));
-
if (DeviceActions.empty())
return HostAction;
diff --git a/clang/test/Driver/hip-cuid.hip b/clang/test/Driver/hip-cuid.hip
index 2e38c59ccf5ef1..78c391c966e2ad 100644
--- a/clang/test/Driver/hip-cuid.hip
+++ b/clang/test/Driver/hip-cuid.hip
@@ -80,16 +80,37 @@
// RUN: %S/Inputs/hip_multiple_inputs/b.hip \
// RUN: 2>&1 | FileCheck -check-prefixes=DEVICE %s
+// Check cuid is supported by the new driver.
+// RUN: %clang -### -x hip \
+// RUN: --target=x86_64-unknown-linux-gnu \
+// RUN: --no-offload-new-driver \
+// RUN: --offload-arch=gfx900 \
+// RUN: --offload-arch=gfx906 \
+// RUN: -c -nogpuinc -nogpulib --offload-new-driver \
+// RUN: %S/Inputs/hip_multiple_inputs/a.cu \
+// RUN: %S/Inputs/hip_multiple_inputs/b.hip \
+// RUN: 2>&1 | FileCheck -check-prefixes=COMMON,HEX %s
+
+// Check cuid is supported by CUDA by the default new driver.
+// RUN: %clang -### -x cu \
+// RUN: --target=x86_64-unknown-linux-gnu \
+// RUN: --offload-arch=sm_60 \
+// RUN: --offload-arch=sm_70 \
+// RUN: -c -nogpuinc -nogpulib \
+// RUN: %S/Inputs/hip_multiple_inputs/a.cu \
+// RUN: %S/Inputs/hip_multiple_inputs/b.hip \
+// RUN: 2>&1 | FileCheck -check-prefixes=COMMON,HEX %s
+
// INVALID: invalid value 'invalid' in '-fuse-cuid=invalid'
-// COMMON: "-cc1"{{.*}} "-triple" "amdgcn-amd-amdhsa"
-// COMMON-SAME: "-target-cpu" "gfx900"
+// COMMON: "-cc1"{{.*}} "-triple" "[[TRIP:(amdgcn-amd-amdhsa|nvptx64-nvidia-cuda)]]"
+// COMMON-SAME: "-target-cpu" "[[G1:(gfx900|sm_60)]]"
// HEX-SAME: "-cuid=[[CUID:[0-9a-f]+]]"
// FIXED-SAME: "-cuid=[[CUID:xyz_123]]"
// COMMON-SAME: "{{.*}}a.cu"
-// COMMON: "-cc1"{{.*}} "-triple" "amdgcn-amd-amdhsa"
-// COMMON-SAME: "-target-cpu" "gfx906"
+// COMMON: "-cc1"{{.*}} "-triple" "[[TRIP]]"
+// COMMON-SAME: "-target-cpu" "[[G2:(gfx906|sm_70)]]"
// COMMON-SAME: "-cuid=[[CUID]]"
// COMMON-SAME: "{{.*}}a.cu"
@@ -97,15 +118,15 @@
// COMMON-SAME: "-cuid=[[CUID]]"
// COMMON-SAME: "{{.*}}a.cu"
-// COMMON: "-cc1"{{.*}} "-triple" "amdgcn-amd-amdhsa"
-// COMMON-SAME: "-target-cpu" "gfx900"
+// COMMON: "-cc1"{{.*}} "-triple" "[[TRIP]]"
+// COMMON-SAME: "-target-cpu" "[[G1]]"
// HEX-NOT: "-cuid=[[CUID]]"
// HEX-SAME: "-cuid=[[CUID2:[0-9a-f]+]]"
// FIXED-SAME: "-cuid=[[CUID2:xyz_123]]"
// COMMON-SAME: "{{.*}}b.hip"
-// COMMON: "-cc1"{{.*}} "-triple" "amdgcn-amd-amdhsa"
-// COMMON-SAME: "-target-cpu" "gfx906"
+// COMMON: "-cc1"{{.*}} "-triple" "[[TRIP]]"
+// COMMON-SAME: "-target-cpu" "[[G2]]"
// HEX-NOT: "-cuid=[[CUID]]"
// COMMON-SAME: "-cuid=[[CUID2]]"
// COMMON-SAME: "{{.*}}b.hip"
More information about the cfe-commits
mailing list