Skip to content

Commit 38939c7

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 38939c7

File tree

3 files changed

+122
-55
lines changed

3 files changed

+122
-55
lines changed

clang/include/clang/Driver/Driver.h

Lines changed: 29 additions & 0 deletions
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
@@ -728,6 +754,9 @@ class Driver {
728754
/// Get the specific kind of offload LTO being performed.
729755
LTOKind getOffloadLTOMode() const { return OffloadLTOMode; }
730756

757+
/// Get the CUID option.
758+
const CUIDOptions &getCUIDOpts() const { return CUIDOpts; }
759+
731760
private:
732761

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

clang/lib/Driver/Driver.cpp

Lines changed: 64 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,51 @@ 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+
215+
FixedCUID = Args.getLastArgValue(options::OPT_cuid_EQ);
216+
if (!FixedCUID.empty())
217+
UseCUID = Kind::Fixed;
218+
}
219+
220+
std::string CUIDOptions::getCUID(StringRef InputFile,
221+
llvm::opt::DerivedArgList &Args) const {
222+
std::string CUID = FixedCUID.str();
223+
if (CUID.empty()) {
224+
if (UseCUID == Kind::Random)
225+
CUID = llvm::utohexstr(llvm::sys::Process::GetRandomNumber(),
226+
/*LowerCase=*/true);
227+
else if (UseCUID == Kind::Hash) {
228+
llvm::MD5 Hasher;
229+
llvm::MD5::MD5Result Hash;
230+
SmallString<256> RealPath;
231+
llvm::sys::fs::real_path(InputFile, RealPath,
232+
/*expand_tilde=*/true);
233+
Hasher.update(RealPath);
234+
for (auto *A : Args) {
235+
if (A->getOption().matches(options::OPT_INPUT))
236+
continue;
237+
Hasher.update(A->getAsString(Args));
238+
}
239+
Hasher.final(Hash);
240+
CUID = llvm::utohexstr(Hash.low(), /*LowerCase=*/true);
241+
}
242+
}
243+
return CUID;
244+
}
200245
Driver::Driver(StringRef ClangExecutable, StringRef TargetTriple,
201246
DiagnosticsEngine &Diags, std::string Title,
202247
IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS)
@@ -875,6 +920,9 @@ void Driver::CreateOffloadingDeviceToolChains(Compilation &C,
875920
C.addOffloadDeviceToolChain(HIPTC, OFK);
876921
}
877922

923+
if (IsCuda || IsHIP)
924+
CUIDOpts = CUIDOptions(C.getArgs(), *this);
925+
878926
//
879927
// OpenMP
880928
//
@@ -3156,19 +3204,15 @@ class OffloadingActionBuilder final {
31563204
/// Default GPU architecture if there's no one specified.
31573205
OffloadArch DefaultOffloadArch = OffloadArch::UNKNOWN;
31583206

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;
3207+
/// Compilation unit ID specified by option '-fuse-cuid=' or'-cuid='.
3208+
const CUIDOptions &CUIDOpts;
31663209

31673210
public:
31683211
CudaActionBuilderBase(Compilation &C, DerivedArgList &Args,
31693212
const Driver::InputList &Inputs,
31703213
Action::OffloadKind OFKind)
3171-
: DeviceActionBuilder(C, Args, Inputs, OFKind) {
3214+
: DeviceActionBuilder(C, Args, Inputs, OFKind),
3215+
CUIDOpts(C.getDriver().getCUIDOpts()) {
31723216

31733217
CompileDeviceOnly = C.getDriver().offloadDeviceOnly();
31743218
Relocatable = Args.hasFlag(options::OPT_fgpu_rdc,
@@ -3199,28 +3243,8 @@ class OffloadingActionBuilder final {
31993243
// Set the flag to true, so that the builder acts on the current input.
32003244
IsActive = true;
32013245

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);
3246+
if (CUIDOpts.isEnabled())
3247+
IA->setId(CUIDOpts.getCUID(IA->getInputArg().getValue(), Args));
32243248

32253249
if (CompileHostOnly)
32263250
return ABRT_Success;
@@ -3346,21 +3370,6 @@ class OffloadingActionBuilder final {
33463370
CompileHostOnly = C.getDriver().offloadHostOnly();
33473371
EmitLLVM = Args.getLastArg(options::OPT_emit_llvm);
33483372
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-
}
33643373

33653374
// --offload and --offload-arch options are mutually exclusive.
33663375
if (Args.hasArgNoClaim(options::OPT_offload_EQ) &&
@@ -4360,6 +4369,10 @@ void Driver::BuildActions(Compilation &C, DerivedArgList &Args,
43604369
// Build the pipeline for this file.
43614370
Action *Current = C.MakeAction<InputAction>(*InputArg, InputType);
43624371

4372+
if (CUIDOpts.isEnabled() && types::isSrcFile(InputType))
4373+
cast<InputAction>(Current)->setId(
4374+
CUIDOpts.getCUID(InputArg->getValue(), Args));
4375+
43634376
// Use the current host action in any of the offloading actions, if
43644377
// required.
43654378
if (!UseNewOffloadingDriver)
@@ -4805,8 +4818,12 @@ Action *Driver::BuildOffloadingActions(Compilation &C,
48054818
TCAndArchs.push_back(std::make_pair(TC, Arch));
48064819
}
48074820

4808-
for (unsigned I = 0, E = TCAndArchs.size(); I != E; ++I)
4809-
DeviceActions.push_back(C.MakeAction<InputAction>(*InputArg, InputType));
4821+
for (unsigned I = 0, E = TCAndArchs.size(); I != E; ++I) {
4822+
auto *IA = C.MakeAction<InputAction>(*InputArg, InputType);
4823+
if (CUIDOpts.isEnabled())
4824+
IA->setId(CUIDOpts.getCUID(IA->getInputArg().getValue(), Args));
4825+
DeviceActions.push_back(IA);
4826+
}
48104827

48114828
if (DeviceActions.empty())
48124829
return HostAction;

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)