Skip to content

Commit 8ac35bd

Browse files
authored
[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.
1 parent 618ac90 commit 8ac35bd

File tree

3 files changed

+125
-60
lines changed

3 files changed

+125
-60
lines changed

clang/include/clang/Driver/Driver.h

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,29 @@ enum ModuleHeaderMode {
7272
HeaderMode_System
7373
};
7474

75+
/// Options for specifying CUID used by CUDA/HIP for uniquely identifying
76+
/// compilation units.
77+
class CUIDOptions {
78+
public:
79+
enum class Kind { Hash, Random, Fixed, None, Invalid };
80+
81+
CUIDOptions() = default;
82+
CUIDOptions(const CUIDOptions &) = default;
83+
CUIDOptions(llvm::opt::DerivedArgList &Args, const Driver &D);
84+
85+
// Get the CUID for an input string
86+
std::string getCUID(StringRef InputFile,
87+
llvm::opt::DerivedArgList &Args) const;
88+
89+
bool isEnabled() const {
90+
return UseCUID != Kind::None && UseCUID != Kind::Invalid;
91+
}
92+
93+
private:
94+
Kind UseCUID = Kind::None;
95+
StringRef FixedCUID;
96+
};
97+
7598
/// Driver - Encapsulate logic for constructing compilation processes
7699
/// from a set of gcc-driver-like command line arguments.
77100
class Driver {
@@ -119,6 +142,9 @@ class Driver {
119142
/// LTO mode selected via -f(no-offload-)?lto(=.*)? options.
120143
LTOKind OffloadLTOMode;
121144

145+
/// Options for CUID
146+
CUIDOptions CUIDOpts;
147+
122148
public:
123149
enum OpenMPRuntimeKind {
124150
/// An unknown OpenMP runtime. We can't generate effective OpenMP code
@@ -501,10 +527,11 @@ class Driver {
501527
/// \param C - The compilation that is being built.
502528
/// \param Args - The input arguments.
503529
/// \param Input - The input type and arguments
530+
/// \param CUID - The CUID for \p Input
504531
/// \param HostAction - The host action used in the offloading toolchain.
505532
Action *BuildOffloadingActions(Compilation &C,
506533
llvm::opt::DerivedArgList &Args,
507-
const InputTy &Input,
534+
const InputTy &Input, StringRef CUID,
508535
Action *HostAction) const;
509536

510537
/// Returns the set of bound architectures active for this offload kind.
@@ -728,6 +755,9 @@ class Driver {
728755
/// Get the specific kind of offload LTO being performed.
729756
LTOKind getOffloadLTOMode() const { return OffloadLTOMode; }
730757

758+
/// Get the CUID option.
759+
const CUIDOptions &getCUIDOpts() const { return CUIDOpts; }
760+
731761
private:
732762

733763
/// Tries to load options from configuration files.

clang/lib/Driver/Driver.cpp

Lines changed: 65 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,50 @@ std::string Driver::GetResourcesPath(StringRef BinaryPath) {
197197
return std::string(P);
198198
}
199199

200+
CUIDOptions::CUIDOptions(llvm::opt::DerivedArgList &Args, const Driver &D)
201+
: UseCUID(Kind::Hash) {
202+
if (Arg *A = Args.getLastArg(options::OPT_fuse_cuid_EQ)) {
203+
StringRef UseCUIDStr = A->getValue();
204+
UseCUID = llvm::StringSwitch<Kind>(UseCUIDStr)
205+
.Case("hash", Kind::Hash)
206+
.Case("random", Kind::Random)
207+
.Case("none", Kind::None)
208+
.Default(Kind::Invalid);
209+
if (UseCUID == Kind::Invalid)
210+
D.Diag(clang::diag::err_drv_invalid_value)
211+
<< A->getAsString(Args) << UseCUIDStr;
212+
}
213+
214+
FixedCUID = Args.getLastArgValue(options::OPT_cuid_EQ);
215+
if (!FixedCUID.empty())
216+
UseCUID = Kind::Fixed;
217+
}
218+
219+
std::string CUIDOptions::getCUID(StringRef InputFile,
220+
llvm::opt::DerivedArgList &Args) const {
221+
std::string CUID = FixedCUID.str();
222+
if (CUID.empty()) {
223+
if (UseCUID == Kind::Random)
224+
CUID = llvm::utohexstr(llvm::sys::Process::GetRandomNumber(),
225+
/*LowerCase=*/true);
226+
else if (UseCUID == Kind::Hash) {
227+
llvm::MD5 Hasher;
228+
llvm::MD5::MD5Result Hash;
229+
SmallString<256> RealPath;
230+
llvm::sys::fs::real_path(InputFile, RealPath,
231+
/*expand_tilde=*/true);
232+
Hasher.update(RealPath);
233+
for (auto *A : Args) {
234+
if (A->getOption().matches(options::OPT_INPUT))
235+
continue;
236+
Hasher.update(A->getAsString(Args));
237+
}
238+
Hasher.final(Hash);
239+
CUID = llvm::utohexstr(Hash.low(), /*LowerCase=*/true);
240+
}
241+
}
242+
return CUID;
243+
}
200244
Driver::Driver(StringRef ClangExecutable, StringRef TargetTriple,
201245
DiagnosticsEngine &Diags, std::string Title,
202246
IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS)
@@ -875,6 +919,9 @@ void Driver::CreateOffloadingDeviceToolChains(Compilation &C,
875919
C.addOffloadDeviceToolChain(HIPTC, OFK);
876920
}
877921

922+
if (IsCuda || IsHIP)
923+
CUIDOpts = CUIDOptions(C.getArgs(), *this);
924+
878925
//
879926
// OpenMP
880927
//
@@ -3161,19 +3208,15 @@ class OffloadingActionBuilder final {
31613208
/// Default GPU architecture if there's no one specified.
31623209
OffloadArch DefaultOffloadArch = OffloadArch::UNKNOWN;
31633210

3164-
/// Method to generate compilation unit ID specified by option
3165-
/// '-fuse-cuid='.
3166-
enum UseCUIDKind { CUID_Hash, CUID_Random, CUID_None, CUID_Invalid };
3167-
UseCUIDKind UseCUID = CUID_Hash;
3168-
3169-
/// Compilation unit ID specified by option '-cuid='.
3170-
StringRef FixedCUID;
3211+
/// Compilation unit ID specified by option '-fuse-cuid=' or'-cuid='.
3212+
const CUIDOptions &CUIDOpts;
31713213

31723214
public:
31733215
CudaActionBuilderBase(Compilation &C, DerivedArgList &Args,
31743216
const Driver::InputList &Inputs,
31753217
Action::OffloadKind OFKind)
3176-
: DeviceActionBuilder(C, Args, Inputs, OFKind) {
3218+
: DeviceActionBuilder(C, Args, Inputs, OFKind),
3219+
CUIDOpts(C.getDriver().getCUIDOpts()) {
31773220

31783221
CompileDeviceOnly = C.getDriver().offloadDeviceOnly();
31793222
Relocatable = Args.hasFlag(options::OPT_fgpu_rdc,
@@ -3204,28 +3247,8 @@ class OffloadingActionBuilder final {
32043247
// Set the flag to true, so that the builder acts on the current input.
32053248
IsActive = true;
32063249

3207-
std::string CUID = FixedCUID.str();
3208-
if (CUID.empty()) {
3209-
if (UseCUID == CUID_Random)
3210-
CUID = llvm::utohexstr(llvm::sys::Process::GetRandomNumber(),
3211-
/*LowerCase=*/true);
3212-
else if (UseCUID == CUID_Hash) {
3213-
llvm::MD5 Hasher;
3214-
llvm::MD5::MD5Result Hash;
3215-
SmallString<256> RealPath;
3216-
llvm::sys::fs::real_path(IA->getInputArg().getValue(), RealPath,
3217-
/*expand_tilde=*/true);
3218-
Hasher.update(RealPath);
3219-
for (auto *A : Args) {
3220-
if (A->getOption().matches(options::OPT_INPUT))
3221-
continue;
3222-
Hasher.update(A->getAsString(Args));
3223-
}
3224-
Hasher.final(Hash);
3225-
CUID = llvm::utohexstr(Hash.low(), /*LowerCase=*/true);
3226-
}
3227-
}
3228-
IA->setId(CUID);
3250+
if (CUIDOpts.isEnabled())
3251+
IA->setId(CUIDOpts.getCUID(IA->getInputArg().getValue(), Args));
32293252

32303253
if (CompileHostOnly)
32313254
return ABRT_Success;
@@ -3351,21 +3374,6 @@ class OffloadingActionBuilder final {
33513374
CompileHostOnly = C.getDriver().offloadHostOnly();
33523375
EmitLLVM = Args.getLastArg(options::OPT_emit_llvm);
33533376
EmitAsm = Args.getLastArg(options::OPT_S);
3354-
FixedCUID = Args.getLastArgValue(options::OPT_cuid_EQ);
3355-
if (Arg *A = Args.getLastArg(options::OPT_fuse_cuid_EQ)) {
3356-
StringRef UseCUIDStr = A->getValue();
3357-
UseCUID = llvm::StringSwitch<UseCUIDKind>(UseCUIDStr)
3358-
.Case("hash", CUID_Hash)
3359-
.Case("random", CUID_Random)
3360-
.Case("none", CUID_None)
3361-
.Default(CUID_Invalid);
3362-
if (UseCUID == CUID_Invalid) {
3363-
C.getDriver().Diag(diag::err_drv_invalid_value)
3364-
<< A->getAsString(Args) << UseCUIDStr;
3365-
C.setContainsError();
3366-
return true;
3367-
}
3368-
}
33693377

33703378
// --offload and --offload-arch options are mutually exclusive.
33713379
if (Args.hasArgNoClaim(options::OPT_offload_EQ) &&
@@ -4366,6 +4374,12 @@ void Driver::BuildActions(Compilation &C, DerivedArgList &Args,
43664374
// Build the pipeline for this file.
43674375
Action *Current = C.MakeAction<InputAction>(*InputArg, InputType);
43684376

4377+
std::string CUID;
4378+
if (CUIDOpts.isEnabled() && types::isSrcFile(InputType)) {
4379+
CUID = CUIDOpts.getCUID(InputArg->getValue(), Args);
4380+
cast<InputAction>(Current)->setId(CUID);
4381+
}
4382+
43694383
// Use the current host action in any of the offloading actions, if
43704384
// required.
43714385
if (!UseNewOffloadingDriver)
@@ -4429,7 +4443,7 @@ void Driver::BuildActions(Compilation &C, DerivedArgList &Args,
44294443
// Try to build the offloading actions and add the result as a dependency
44304444
// to the host.
44314445
if (UseNewOffloadingDriver)
4432-
Current = BuildOffloadingActions(C, Args, I, Current);
4446+
Current = BuildOffloadingActions(C, Args, I, CUID, Current);
44334447
// Use the current host action in any of the offloading actions, if
44344448
// required.
44354449
else if (OffloadBuilder->addHostDependenceToDeviceActions(Current,
@@ -4766,7 +4780,7 @@ Driver::getOffloadArchs(Compilation &C, const llvm::opt::DerivedArgList &Args,
47664780

47674781
Action *Driver::BuildOffloadingActions(Compilation &C,
47684782
llvm::opt::DerivedArgList &Args,
4769-
const InputTy &Input,
4783+
const InputTy &Input, StringRef CUID,
47704784
Action *HostAction) const {
47714785
// Don't build offloading actions if explicitly disabled or we do not have a
47724786
// valid source input and compile action to embed it in. If preprocessing only
@@ -4807,13 +4821,13 @@ Action *Driver::BuildOffloadingActions(Compilation &C,
48074821
llvm::DenseSet<StringRef> Arches = getOffloadArchs(C, Args, Kind, TC);
48084822
SmallVector<StringRef, 0> Sorted(Arches.begin(), Arches.end());
48094823
llvm::sort(Sorted);
4810-
for (StringRef Arch : Sorted)
4824+
for (StringRef Arch : Sorted) {
48114825
TCAndArchs.push_back(std::make_pair(TC, Arch));
4826+
DeviceActions.push_back(
4827+
C.MakeAction<InputAction>(*InputArg, InputType, CUID));
4828+
}
48124829
}
48134830

4814-
for (unsigned I = 0, E = TCAndArchs.size(); I != E; ++I)
4815-
DeviceActions.push_back(C.MakeAction<InputAction>(*InputArg, InputType));
4816-
48174831
if (DeviceActions.empty())
48184832
return HostAction;
48194833

clang/test/Driver/hip-cuid.hip

Lines changed: 29 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -80,32 +80,53 @@
8080
// RUN: %S/Inputs/hip_multiple_inputs/b.hip \
8181
// RUN: 2>&1 | FileCheck -check-prefixes=DEVICE %s
8282

83+
// Check cuid is supported by the new driver.
84+
// RUN: %clang -### -x hip \
85+
// RUN: --target=x86_64-unknown-linux-gnu \
86+
// RUN: --no-offload-new-driver \
87+
// RUN: --offload-arch=gfx900 \
88+
// RUN: --offload-arch=gfx906 \
89+
// RUN: -c -nogpuinc -nogpulib --offload-new-driver \
90+
// RUN: %S/Inputs/hip_multiple_inputs/a.cu \
91+
// RUN: %S/Inputs/hip_multiple_inputs/b.hip \
92+
// RUN: 2>&1 | FileCheck -check-prefixes=COMMON,HEX %s
93+
94+
// Check cuid is supported by CUDA by the default new driver.
95+
// RUN: %clang -### -x cu \
96+
// RUN: --target=x86_64-unknown-linux-gnu \
97+
// RUN: --offload-arch=sm_60 \
98+
// RUN: --offload-arch=sm_70 \
99+
// RUN: -c -nogpuinc -nogpulib \
100+
// RUN: %S/Inputs/hip_multiple_inputs/a.cu \
101+
// RUN: %S/Inputs/hip_multiple_inputs/b.hip \
102+
// RUN: 2>&1 | FileCheck -check-prefixes=COMMON,HEX %s
103+
83104
// INVALID: invalid value 'invalid' in '-fuse-cuid=invalid'
84105

85-
// COMMON: "-cc1"{{.*}} "-triple" "amdgcn-amd-amdhsa"
86-
// COMMON-SAME: "-target-cpu" "gfx900"
106+
// COMMON: "-cc1"{{.*}} "-triple" "[[TRIP:(amdgcn-amd-amdhsa|nvptx64-nvidia-cuda)]]"
107+
// COMMON-SAME: "-target-cpu" "[[G1:(gfx900|sm_60)]]"
87108
// HEX-SAME: "-cuid=[[CUID:[0-9a-f]+]]"
88109
// FIXED-SAME: "-cuid=[[CUID:xyz_123]]"
89110
// COMMON-SAME: "{{.*}}a.cu"
90111

91-
// COMMON: "-cc1"{{.*}} "-triple" "amdgcn-amd-amdhsa"
92-
// COMMON-SAME: "-target-cpu" "gfx906"
112+
// COMMON: "-cc1"{{.*}} "-triple" "[[TRIP]]"
113+
// COMMON-SAME: "-target-cpu" "[[G2:(gfx906|sm_70)]]"
93114
// COMMON-SAME: "-cuid=[[CUID]]"
94115
// COMMON-SAME: "{{.*}}a.cu"
95116

96117
// COMMON: "-cc1"{{.*}} "-triple" "x86_64-unknown-linux-gnu"
97118
// COMMON-SAME: "-cuid=[[CUID]]"
98119
// COMMON-SAME: "{{.*}}a.cu"
99120

100-
// COMMON: "-cc1"{{.*}} "-triple" "amdgcn-amd-amdhsa"
101-
// COMMON-SAME: "-target-cpu" "gfx900"
121+
// COMMON: "-cc1"{{.*}} "-triple" "[[TRIP]]"
122+
// COMMON-SAME: "-target-cpu" "[[G1]]"
102123
// HEX-NOT: "-cuid=[[CUID]]"
103124
// HEX-SAME: "-cuid=[[CUID2:[0-9a-f]+]]"
104125
// FIXED-SAME: "-cuid=[[CUID2:xyz_123]]"
105126
// COMMON-SAME: "{{.*}}b.hip"
106127

107-
// COMMON: "-cc1"{{.*}} "-triple" "amdgcn-amd-amdhsa"
108-
// COMMON-SAME: "-target-cpu" "gfx906"
128+
// COMMON: "-cc1"{{.*}} "-triple" "[[TRIP]]"
129+
// COMMON-SAME: "-target-cpu" "[[G2]]"
109130
// HEX-NOT: "-cuid=[[CUID]]"
110131
// COMMON-SAME: "-cuid=[[CUID2]]"
111132
// COMMON-SAME: "{{.*}}b.hip"

0 commit comments

Comments
 (0)