Skip to content

Commit ae31bf1

Browse files
committed
[CUDA][HIP] Support CUID in new driver
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 clang 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 ac604b2 commit ae31bf1

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
//
@@ -3156,19 +3203,15 @@ class OffloadingActionBuilder final {
31563203
/// Default GPU architecture if there's no one specified.
31573204
OffloadArch DefaultOffloadArch = OffloadArch::UNKNOWN;
31583205

3159-
/// Method to generate compilation unit ID specified by option
3160-
/// '-fuse-cuid='.
3161-
enum UseCUIDKind { CUID_Hash, CUID_Random, CUID_None, CUID_Invalid };
3162-
UseCUIDKind UseCUID = CUID_Hash;
3163-
3164-
/// Compilation unit ID specified by option '-cuid='.
3165-
StringRef FixedCUID;
3206+
/// Compilation unit ID specified by option '-fuse-cuid=' or'-cuid='.
3207+
const CUIDOptions &CUIDOpts;
31663208

31673209
public:
31683210
CudaActionBuilderBase(Compilation &C, DerivedArgList &Args,
31693211
const Driver::InputList &Inputs,
31703212
Action::OffloadKind OFKind)
3171-
: DeviceActionBuilder(C, Args, Inputs, OFKind) {
3213+
: DeviceActionBuilder(C, Args, Inputs, OFKind),
3214+
CUIDOpts(C.getDriver().getCUIDOpts()) {
31723215

31733216
CompileDeviceOnly = C.getDriver().offloadDeviceOnly();
31743217
Relocatable = Args.hasFlag(options::OPT_fgpu_rdc,
@@ -3199,28 +3242,8 @@ class OffloadingActionBuilder final {
31993242
// Set the flag to true, so that the builder acts on the current input.
32003243
IsActive = true;
32013244

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

32253248
if (CompileHostOnly)
32263249
return ABRT_Success;
@@ -3346,21 +3369,6 @@ class OffloadingActionBuilder final {
33463369
CompileHostOnly = C.getDriver().offloadHostOnly();
33473370
EmitLLVM = Args.getLastArg(options::OPT_emit_llvm);
33483371
EmitAsm = Args.getLastArg(options::OPT_S);
3349-
FixedCUID = Args.getLastArgValue(options::OPT_cuid_EQ);
3350-
if (Arg *A = Args.getLastArg(options::OPT_fuse_cuid_EQ)) {
3351-
StringRef UseCUIDStr = A->getValue();
3352-
UseCUID = llvm::StringSwitch<UseCUIDKind>(UseCUIDStr)
3353-
.Case("hash", CUID_Hash)
3354-
.Case("random", CUID_Random)
3355-
.Case("none", CUID_None)
3356-
.Default(CUID_Invalid);
3357-
if (UseCUID == CUID_Invalid) {
3358-
C.getDriver().Diag(diag::err_drv_invalid_value)
3359-
<< A->getAsString(Args) << UseCUIDStr;
3360-
C.setContainsError();
3361-
return true;
3362-
}
3363-
}
33643372

33653373
// --offload and --offload-arch options are mutually exclusive.
33663374
if (Args.hasArgNoClaim(options::OPT_offload_EQ) &&
@@ -4360,6 +4368,12 @@ void Driver::BuildActions(Compilation &C, DerivedArgList &Args,
43604368
// Build the pipeline for this file.
43614369
Action *Current = C.MakeAction<InputAction>(*InputArg, InputType);
43624370

4371+
std::string CUID;
4372+
if (CUIDOpts.isEnabled() && types::isSrcFile(InputType)) {
4373+
CUID = CUIDOpts.getCUID(InputArg->getValue(), Args);
4374+
cast<InputAction>(Current)->setId(CUID);
4375+
}
4376+
43634377
// Use the current host action in any of the offloading actions, if
43644378
// required.
43654379
if (!UseNewOffloadingDriver)
@@ -4423,7 +4437,7 @@ void Driver::BuildActions(Compilation &C, DerivedArgList &Args,
44234437
// Try to build the offloading actions and add the result as a dependency
44244438
// to the host.
44254439
if (UseNewOffloadingDriver)
4426-
Current = BuildOffloadingActions(C, Args, I, Current);
4440+
Current = BuildOffloadingActions(C, Args, I, CUID, Current);
44274441
// Use the current host action in any of the offloading actions, if
44284442
// required.
44294443
else if (OffloadBuilder->addHostDependenceToDeviceActions(Current,
@@ -4760,7 +4774,7 @@ Driver::getOffloadArchs(Compilation &C, const llvm::opt::DerivedArgList &Args,
47604774

47614775
Action *Driver::BuildOffloadingActions(Compilation &C,
47624776
llvm::opt::DerivedArgList &Args,
4763-
const InputTy &Input,
4777+
const InputTy &Input, StringRef CUID,
47644778
Action *HostAction) const {
47654779
// Don't build offloading actions if explicitly disabled or we do not have a
47664780
// valid source input and compile action to embed it in. If preprocessing only
@@ -4801,13 +4815,13 @@ Action *Driver::BuildOffloadingActions(Compilation &C,
48014815
llvm::DenseSet<StringRef> Arches = getOffloadArchs(C, Args, Kind, TC);
48024816
SmallVector<StringRef, 0> Sorted(Arches.begin(), Arches.end());
48034817
llvm::sort(Sorted);
4804-
for (StringRef Arch : Sorted)
4818+
for (StringRef Arch : Sorted) {
48054819
TCAndArchs.push_back(std::make_pair(TC, Arch));
4820+
DeviceActions.push_back(
4821+
C.MakeAction<InputAction>(*InputArg, InputType, CUID));
4822+
}
48064823
}
48074824

4808-
for (unsigned I = 0, E = TCAndArchs.size(); I != E; ++I)
4809-
DeviceActions.push_back(C.MakeAction<InputAction>(*InputArg, InputType));
4810-
48114825
if (DeviceActions.empty())
48124826
return HostAction;
48134827

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)