Skip to content

Commit

Permalink
[Driver][SYCL] Introduce gpu specific device targets for AOT (#6775)
Browse files Browse the repository at this point in the history
Expands spir64_gen target capabilities with -fsycl by introducing a
number of GPU specific targets that can be specified via -fsycl-targets.
These targets (intel_gpu_* in format) are a set of reserved values which
will correspond to spir64_gen target compilations with implied -device
values.

Example:  -fsycl-targets=intel_gpu_skl
  - Passes '-device skl' to ocloc
  - Adds -D__SYCL_TARGET_INTEL_GPU_SKL__ to the device compilation step

For each value passed in -fsycl-targets, additional device specific
compilations will be performed. When bundling (using -c) the
corresponding fat object will be generated with
spir64_gen-unknown-unknown-skl to continue to be unique for extraction
at a later time.
  • Loading branch information
mdtoguchi authored Sep 23, 2022
1 parent 99bdc82 commit 5bd5c87
Show file tree
Hide file tree
Showing 6 changed files with 431 additions and 29 deletions.
83 changes: 72 additions & 11 deletions clang/lib/Driver/Driver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -802,6 +802,19 @@ static bool addSYCLDefaultTriple(Compilation &C,
return true;
}

// Prefix for Intel GPU specific targets used for -fsycl-targets
constexpr char IntelGPU[] = "intel_gpu_";

static llvm::Optional<StringRef> isIntelGPUTarget(StringRef Target) {
// Handle target specifications that resemble 'intel_gpu_*' here. These are
// 'spir64_gen' based.
if (Target.startswith(IntelGPU)) {
return tools::SYCL::gen::resolveGenDevice(
Target.drop_front(sizeof(IntelGPU) - 1));
}
return llvm::None;
}

void Driver::CreateOffloadingDeviceToolChains(Compilation &C,
InputList &Inputs) {

Expand Down Expand Up @@ -1086,8 +1099,17 @@ void Driver::CreateOffloadingDeviceToolChains(Compilation &C,
<< SYCLForceTarget->getAsString(C.getInputArgs());

for (StringRef Val : SYCLTargetsValues->getValues()) {
StringRef UserTargetName(Val);
if (auto Device = isIntelGPUTarget(Val)) {
if (Device->empty()) {
Diag(clang::diag::err_drv_invalid_sycl_target) << Val;
continue;
}
UserTargetName = "spir64_gen";
}

llvm::Triple TT(MakeSYCLDeviceTriple(Val));
if (!isValidSYCLTriple(TT)) {
if (!isValidSYCLTriple(MakeSYCLDeviceTriple(UserTargetName))) {
Diag(clang::diag::err_drv_invalid_sycl_target) << Val;
continue;
}
Expand Down Expand Up @@ -1125,7 +1147,7 @@ void Driver::CreateOffloadingDeviceToolChains(Compilation &C,
// Store the current triple so that we can check for duplicates in
// the following iterations.
FoundNormalizedTriples[NormalizedName] = Val;
UniqueSYCLTriplesVec.push_back(TT);
UniqueSYCLTriplesVec.push_back(MakeSYCLDeviceTriple(UserTargetName));
}
addSYCLDefaultTriple(C, UniqueSYCLTriplesVec);
} else
Expand Down Expand Up @@ -3576,8 +3598,16 @@ void Driver::checkForOffloadMismatch(Compilation &C,
// each target individually.
SmallVector<StringRef, 4> Targets;
if (const Arg *A = Args.getLastArg(options::OPT_fsycl_targets_EQ)) {
for (const char *Val : A->getValues())
for (StringRef Val : A->getValues()) {
if (auto ValidDevice = isIntelGPUTarget(Val)) {
if (!ValidDevice->empty())
Targets.push_back(Args.MakeArgString(
C.getDriver().MakeSYCLDeviceTriple("spir64_gen").str() + "-" +
*ValidDevice));
continue;
}
Targets.push_back(Val);
}
} else { // Implied targets
// No -fsycl-targets given, check based on -fintelfpga or default device
bool SYCLfpga = C.getInputArgs().hasArg(options::OPT_fintelfpga);
Expand Down Expand Up @@ -4722,7 +4752,7 @@ class OffloadingActionBuilder final {
llvm::function_ref<void(const char *)> Op) {
for (auto &A : GpuArchList) {
if (TC->getTriple() == A.first) {
Op(Args.MakeArgString(A.second));
Op(A.second ? Args.MakeArgString(A.second) : nullptr);
return;
}
}
Expand Down Expand Up @@ -5500,10 +5530,12 @@ class OffloadingActionBuilder final {
auto *DeviceWrappingAction = C.MakeAction<OffloadWrapperJobAction>(
WrapperInputs, types::TY_Object);

if (isSpirvAOT)
DA.add(*DeviceWrappingAction, *TC, /*BoundArch=*/nullptr,
if (isSpirvAOT) {
bool AddBA = (TT.getSubArch() == llvm::Triple::SPIRSubArch_gen &&
BoundArch != nullptr);
DA.add(*DeviceWrappingAction, *TC, AddBA ? BoundArch : nullptr,
Action::OFK_SYCL);
else
} else
withBoundArchForToolChain(TC, [&](const char *BoundArch) {
DA.add(*DeviceWrappingAction, *TC, BoundArch, Action::OFK_SYCL);
});
Expand Down Expand Up @@ -5675,7 +5707,17 @@ class OffloadingActionBuilder final {
Arg *SYCLTargetsValues = SYCLTargets ? SYCLTargets : SYCLLinkTargets;
// Fill SYCLTripleList
llvm::StringMap<StringRef> FoundNormalizedTriples;
for (const char *Val : SYCLTargetsValues->getValues()) {
for (StringRef Val : SYCLTargetsValues->getValues()) {
StringRef UserTargetName(Val);
if (auto ValidDevice = isIntelGPUTarget(Val)) {
if (ValidDevice->empty())
// Unrecognized, we have already diagnosed this earlier; skip.
continue;
// Add the proper -device value to the list.
GpuArchList.emplace_back(C.getDriver().MakeSYCLDeviceTriple(
"spir64_gen"), ValidDevice->data());
UserTargetName = "spir64_gen";
}
llvm::Triple TT(C.getDriver().MakeSYCLDeviceTriple(Val));
std::string NormalizedName = TT.normalize();

Expand All @@ -5688,9 +5730,14 @@ class OffloadingActionBuilder final {
// the following iterations.
FoundNormalizedTriples[NormalizedName] = Val;

SYCLTripleList.push_back(TT);
SYCLTripleList.push_back(
C.getDriver().MakeSYCLDeviceTriple(UserTargetName));
if (TT.getSubArch() == llvm::Triple::SPIRSubArch_fpga)
SYCLfpgaTriple = true;
// For user specified spir64_gen, add an empty device value as a
// placeholder.
if (TT.getSubArch() == llvm::Triple::SPIRSubArch_gen)
GpuArchList.emplace_back(TT, nullptr);
}

// Fill GpuArchList, end if there are issues in initializingGpuArchMap
Expand All @@ -5705,9 +5752,20 @@ class OffloadingActionBuilder final {
ToolChains, [&](auto &TC) { return TT == TC->getTriple(); });
assert(TCIt != ToolChains.end() &&
"Toolchain was not created for this platform");
if (!TT.isNVPTX() && !TT.isAMDGCN())
if (!TT.isNVPTX() && !TT.isAMDGCN()) {
// When users specify the target as 'intel_gpu_*', the proper
// triple is 'spir64_gen'. The given string from intel_gpu_*
// is the target device.
if (TT.isSPIR() &&
TT.getSubArch() == llvm::Triple::SPIRSubArch_gen) {
StringRef Device(GpuArchList[I].second);
SYCLTargetInfoList.emplace_back(
*TCIt, Device.empty() ? nullptr : Device.data());
++I;
continue;
}
SYCLTargetInfoList.emplace_back(*TCIt, nullptr);
else {
} else {
SYCLTargetInfoList.emplace_back(*TCIt, GpuArchList[I].second);
++I;
}
Expand All @@ -5731,6 +5789,9 @@ class OffloadingActionBuilder final {
// populate the AOT binary inputs vector.
SYCLAOTInputs.push_back(std::make_pair(TT, TF));
ShouldAddDefaultTriple = false;
// Add an empty entry to the Device list
if (TT.getSubArch() == llvm::Triple::SPIRSubArch_gen)
GpuArchList.emplace_back(TT, nullptr);
}
}
} else if (HasValidSYCLRuntime) {
Expand Down
15 changes: 14 additions & 1 deletion clang/lib/Driver/ToolChains/Clang.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5003,6 +5003,19 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,

// Forward -fsycl-default-sub-group-size if in SYCL mode.
Args.AddLastArg(CmdArgs, options::OPT_fsycl_default_sub_group_size);

// Add any predefined macros associated with intel_gpu* type targets
// passed in with -fsycl-targets
if (RawTriple.isSPIR() &&
RawTriple.getSubArch() == llvm::Triple::SPIRSubArch_gen) {
StringRef Device = JA.getOffloadingArch();
if (!Device.empty())
CmdArgs.push_back(Args.MakeArgString(
Twine("-D") + SYCL::gen::getGenDeviceMacro(Device)));
}
if (RawTriple.isSPIR() &&
RawTriple.getSubArch() == llvm::Triple::SPIRSubArch_x86_64)
CmdArgs.push_back("-D__SYCL_TARGET_INTEL_X86_64__");
}

if (IsSYCL) {
Expand Down Expand Up @@ -9070,7 +9083,7 @@ void OffloadWrapper::ConstructJob(Compilation &C, const JobAction &JA,
if (TC.getTriple().getSubArch() == llvm::Triple::NoSubArch) {
// Only store compile/link opts in the image descriptor for the SPIR-V
// target; AOT compilation has already been performed otherwise.
TC.AddImpliedTargetArgs(TT, TCArgs, BuildArgs);
TC.AddImpliedTargetArgs(TT, TCArgs, BuildArgs, JA);
TC.TranslateBackendTargetArgs(TT, TCArgs, BuildArgs);
createArgString("-compile-opts=");
BuildArgs.clear();
Expand Down
Loading

0 comments on commit 5bd5c87

Please sign in to comment.