Skip to content

[Driver][SYCL] Update default offload device settings with -fsycl #14208

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 8 commits into
base: sycl
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 0 additions & 16 deletions clang/include/clang/Driver/Driver.h
Original file line number Diff line number Diff line change
Expand Up @@ -875,11 +875,6 @@ class Driver {
/// targets.
mutable llvm::StringMap<StringRef> SYCLUniqueIDList;

/// Vector of Macros that need to be added to the Host compilation in a
/// SYCL based offloading scenario. These macros are gathered during
/// construction of the device compilations.
mutable std::vector<std::string> SYCLTargetMacroArgs;

/// Vector of Macros related to Device Traits that need to be added to the
/// device compilation in a SYCL based offloading scenario. These macros are
/// gathered during creation of offloading device toolchains.
Expand Down Expand Up @@ -951,17 +946,6 @@ class Driver {
void createAppendedFooterInput(Action *&Input, Compilation &C,
const llvm::opt::ArgList &Args) const;

/// addSYCLTargetMacroArg - Add the given macro to the vector of args to be
/// added to the host compilation step.
void addSYCLTargetMacroArg(const llvm::opt::ArgList &Args,
StringRef Macro) const {
SYCLTargetMacroArgs.push_back(Args.MakeArgString(Macro));
}
/// getSYCLTargetMacroArgs - return the previously gathered macro target args.
llvm::ArrayRef<std::string> getSYCLTargetMacroArgs() const {
return SYCLTargetMacroArgs;
}

/// setSYCLUniqueID - set the Unique ID that is used for all FE invocations
/// when performing compilations for SYCL.
void addSYCLUniqueID(StringRef UniqueID, StringRef FileName) const {
Expand Down
3 changes: 3 additions & 0 deletions clang/include/clang/Driver/Options.td
Original file line number Diff line number Diff line change
Expand Up @@ -4121,6 +4121,9 @@ def fsycl_optimize_non_user_code : Flag<["-"], "fsycl-optimize-non-user-code">,
MarshallingInfoFlag<CodeGenOpts<"OptimizeSYCLFramework">>,
HelpText<"Option used in conjunction with -O0 to "
"optimize SYCL framework utility functions and leave user's kernel code unoptimized. (experimental)">;
def fno_spirv : Flag<["-"], "fno-spirv">, Visibility<[ClangOption, CLOption, DXCOption]>,
HelpText<"Disable inclusion of default spir64 target when performing SYCL "
"offloading.">;
def fsyntax_only : Flag<["-"], "fsyntax-only">,
Flags<[NoXarchOption]>,
Visibility<[ClangOption, CLOption, DXCOption, CC1Option, FC1Option, FlangOption]>,
Expand Down
24 changes: 20 additions & 4 deletions clang/lib/Driver/Driver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -844,7 +844,10 @@ static const char *getDefaultSYCLArch(Compilation &C) {
static bool addSYCLDefaultTriple(Compilation &C,
SmallVectorImpl<llvm::Triple> &SYCLTriples) {
/// Returns true if a triple is added to SYCLTriples, false otherwise
if (!C.getDriver().isSYCLDefaultTripleImplied())
if (C.getInputArgs().hasArg(options::OPT_fno_spirv))
return false;
// No default triple with -fsycl-device-only
if (C.getInputArgs().hasArg(options::OPT_fsycl_device_only))
return false;
if (C.getInputArgs().hasArg(options::OPT_fsycl_force_target_EQ))
return false;
Expand All @@ -856,6 +859,14 @@ static bool addSYCLDefaultTriple(Compilation &C,
if (SYCLTriple.isNVPTX() || SYCLTriple.isAMDGCN())
return false;
}
// When FPGA is the only AOT target or SYCL Native is the only target, do
// not add the default triple.
if (SYCLTriples.size() == 1 &&
(SYCLTriples[0].getSubArch() == llvm::Triple::SPIRSubArch_fpga ||
driver::isSYCLNativeCPU(
C.getSingleOffloadToolChain<Action::OFK_Host>()->getTriple(),
SYCLTriples[0])))
return false;
// Add the default triple as it was not found.
llvm::Triple DefaultTriple =
C.getDriver().MakeSYCLDeviceTriple(getDefaultSYCLArch(C));
Expand Down Expand Up @@ -6392,6 +6403,7 @@ class OffloadingActionBuilder final {
llvm::StringMap<StringRef> FoundNormalizedTriples;
for (StringRef Val : SYCLTargetsValues->getValues()) {
StringRef UserTargetName(Val);
bool GPUHasArch = false;
if (auto ValidDevice = gen::isGPUTarget<gen::IntelGPU>(Val)) {
if (ValidDevice->empty())
// Unrecognized, we have already diagnosed this earlier; skip.
Expand All @@ -6400,6 +6412,7 @@ class OffloadingActionBuilder final {
GpuArchList.emplace_back(C.getDriver().MakeSYCLDeviceTriple(
"spir64_gen"), ValidDevice->data());
UserTargetName = "spir64_gen";
GPUHasArch = true;
} else if (auto ValidDevice =
gen::isGPUTarget<gen::NvidiaGPU>(Val)) {
if (ValidDevice->empty())
Expand Down Expand Up @@ -6427,8 +6440,11 @@ class OffloadingActionBuilder final {
continue;
}

llvm::Triple TT(C.getDriver().MakeSYCLDeviceTriple(Val));
std::string NormalizedName = TT.normalize();
llvm::Triple TT(C.getDriver().MakeSYCLDeviceTriple(UserTargetName));
if (!isValidSYCLTriple(TT))
continue;
std::string NormalizedName =
C.getDriver().MakeSYCLDeviceTriple(Val).normalize();

// Make sure we don't have a duplicate triple.
auto Duplicate = FoundNormalizedTriples.find(NormalizedName);
Expand All @@ -6445,7 +6461,7 @@ class OffloadingActionBuilder final {
SYCLfpgaTriple = true;
// For user specified spir64_gen, add an empty device value as a
// placeholder.
if (TT.getSubArch() == llvm::Triple::SPIRSubArch_gen)
if (TT.getSubArch() == llvm::Triple::SPIRSubArch_gen && !GPUHasArch)
GpuArchList.emplace_back(TT, nullptr);
}

Expand Down
33 changes: 24 additions & 9 deletions clang/lib/Driver/ToolChains/Clang.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5617,10 +5617,6 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
}
// Add any predefined macros associated with intel_gpu* type targets
// passed in with -fsycl-targets
// TODO: Macros are populated during device compilations and saved for
// addition to the host compilation. There is no dependence connection
// between device and host where we should be able to use the offloading
// arch to add the macro to the host compile.
auto addTargetMacros = [&](const llvm::Triple &Triple) {
if (!Triple.isSPIR() && !Triple.isNVPTX() && !Triple.isAMDGCN())
return;
Expand All @@ -5635,16 +5631,35 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
}
} else if (Triple.getSubArch() == llvm::Triple::SPIRSubArch_x86_64)
Macro = "-D__SYCL_TARGET_INTEL_X86_64__";
if (Macro.size()) {
if (Macro.size())
CmdArgs.push_back(Args.MakeArgString(Macro));
D.addSYCLTargetMacroArg(Args, Macro);
}
};
if (IsSYCLOffloadDevice)
addTargetMacros(RawTriple);
else {
for (auto &Macro : D.getSYCLTargetMacroArgs())
CmdArgs.push_back(Args.MakeArgString(Macro));
// Add the host side macros.
// TODO: There is some code duplication for adding the macros for the
// host and device side, find a way to clean this up.
auto SYCLTCRange = C.getOffloadToolChains<Action::OFK_SYCL>();
for (auto TI = SYCLTCRange.first, TE = SYCLTCRange.second; TI != TE;
++TI) {
auto TC = TI->second;
llvm::Triple SYCLTriple = TC->getTriple();
SmallString<64> Macro;
if (SYCLTriple.getSubArch() == llvm::Triple::SPIRSubArch_gen ||
SYCLTriple.isNVPTX() || SYCLTriple.isAMDGCN()) {
for (StringRef Arch : D.getOffloadArchs(
C, C.getArgs(), Action::OFK_SYCL, &*TC, true)) {
if (!SYCL::gen::getGenDeviceMacro(Arch).empty()) {
Macro = "-D";
Macro += SYCL::gen::getGenDeviceMacro(Arch);
}
}
} else if (SYCLTriple.getSubArch() == llvm::Triple::SPIRSubArch_x86_64)
Macro = "-D__SYCL_TARGET_INTEL_X86_64__";
if (Macro.size())
CmdArgs.push_back(Args.MakeArgString(Macro));
}
if (Args.hasArg(options::OPT_fno_sycl_esimd_build_host_code))
CmdArgs.push_back("-fno-sycl-esimd-build-host-code");
}
Expand Down
29 changes: 17 additions & 12 deletions clang/test/Driver/sycl-bfloat16-lib.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,30 +16,35 @@
// RUN: | FileCheck %s -check-prefix=BFLOAT16

// Test that a PVC AOT compilation uses the native library.
// RUN: %clangxx -fsycl -fsycl-targets=spir64_gen -Xsycl-target-backend \
// RUN: "-device pvc" %s --sysroot=%S/Inputs/SYCL -### 2>&1 \
// RUN: %clangxx -fsycl -fsycl-targets=spir64_gen -fno-spirv \
// RUN: -Xsycl-target-backend "-device pvc" %s --sysroot=%S/Inputs/SYCL \
// RUN: -### 2>&1 \
// RUN: | FileCheck %s -check-prefix=BFLOAT16-NATIVE

// Test that unless all targets support bfloat16, AOT compilation uses the
// fallback library.
// RUN: %clangxx -fsycl -fsycl-targets=spir64_gen -Xsycl-target-backend \
// RUN: "-device pvc,gen9" %s --sysroot=%S/Inputs/SYCL -### 2>&1 \
// RUN: %clangxx -fsycl -fsycl-targets=spir64_gen -fno-spirv \
// RUN: -Xsycl-target-backend "-device pvc,gen9" %s \
// RUN: --sysroot=%S/Inputs/SYCL -### 2>&1 \
// RUN: | FileCheck %s -check-prefix=BFLOAT16-FALLBACK

// Test that when all targets support bfloat16, AOT compilation uses the
// native library.
// RUN: %clangxx -fsycl -fsycl-targets=spir64_gen -Xsycl-target-backend \
// RUN: "-device pvc-sdv,ats-m75" %s --sysroot=%S/Inputs/SYCL -### 2>&1 \
// RUN: %clangxx -fsycl -fsycl-targets=spir64_gen -fno-spirv \
// RUN: -Xsycl-target-backend "-device pvc-sdv,ats-m75" %s \
// RUN: --sysroot=%S/Inputs/SYCL -### 2>&1 \
// RUN: | FileCheck %s -check-prefix=BFLOAT16-NATIVE

// Test that a gen9 AOT compilation uses the fallback library.
// RUN: %clangxx -fsycl -fsycl-targets=spir64_gen -Xsycl-target-backend \
// RUN: "-device gen9" %s --sysroot=%S/Inputs/SYCL -### 2>&1 \
// RUN: %clangxx -fsycl -fsycl-targets=spir64_gen -fno-spirv \
// RUN: -Xsycl-target-backend "-device gen9" %s --sysroot=%S/Inputs/SYCL \
// RUN: -### 2>&1 \
// RUN: | FileCheck %s -check-prefix=BFLOAT16-FALLBACK

// Test that a generic AOT compilation uses the fallback library.
// RUN: %clangxx -fsycl -fsycl-targets=spir64_gen -Xsycl-target-backend \
// RUN: "-device *" %s --sysroot=%S/Inputs/SYCL -### 2>&1 \
// RUN: %clangxx -fsycl -fsycl-targets=spir64_gen -fno-spirv \
// RUN: -Xsycl-target-backend "-device *" %s --sysroot=%S/Inputs/SYCL \
// RUN: -### 2>&1 \
// RUN: | FileCheck %s -check-prefix=BFLOAT16-FALLBACK

// Test that a mixed JIT + AOT-PVC compilation uses no libs + fallback libs.
Expand All @@ -55,13 +60,13 @@
// RUN: | FileCheck %s -check-prefix=BFLOAT16-NONE-FALLBACK

// Test that an AOT-CPU + AOT-PVC compilation fallback + fallback libs.
// RUN: %clangxx -fsycl -fsycl-targets=spir64_x86_64,spir64_gen \
// RUN: %clangxx -fsycl -fsycl-targets=spir64_x86_64,spir64_gen -fno-spirv \
// RUN: -Xsycl-target-backend=spir64_gen "-device pvc" %s \
// RUN: --sysroot=%S/Inputs/SYCL -### 2>&1 \
// RUN: | FileCheck %s -check-prefix=BFLOAT16-FALLBACK-NATIVE

// Test that an AOT-CPU + AOT-Gen9 compilation uses fallback + native libs.
// RUN: %clangxx -fsycl -fsycl-targets=spir64_x86_64,spir64_gen \
// RUN: %clangxx -fsycl -fsycl-targets=spir64_x86_64,spir64_gen -fno-spirv \
// RUN: -Xsycl-target-backend=spir64_gen "-device gen9" %s \
// RUN: --sysroot=%S/Inputs/SYCL -### 2>&1 \
// RUN: | FileCheck %s -check-prefix=BFLOAT16-FALLBACK-FALLBACK
Expand Down
4 changes: 2 additions & 2 deletions clang/test/Driver/sycl-early-device-link.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
// Behavior is restricted to spir64_gen targets for now.

// Create object that contains final device image
// RUN: %clangxx -c -fno-sycl-rdc -fsycl -fsycl-targets=spir64_gen \
// RUN: %clangxx -c -fno-sycl-rdc -fsycl -fsycl-targets=spir64_gen -fno-spirv \
// RUN: --target=x86_64-unknown-linux-gnu -Xsycl-target-backend \
// RUN: "-device skl" --sysroot=%S/Inputs/SYCL -### %s 2>&1 \
// RUN: | FileCheck %s -check-prefix=CREATE_IMAGE
Expand All @@ -21,7 +21,7 @@
// CREATE_IMAGE: clang{{.*}} "-fsycl-is-host"{{.*}} "-o" "[[HOST_OBJECT:.+\.o]]"{{.*}} "[[APPEND_SOURCE]]"
// CREATE_IMAGE: clang-offload-bundler{{.*}} "-targets=sycl-spir64_gen_image-unknown-unknown,host-x86_64-unknown-linux-gnu" "-output={{.*}}" "-input=[[DEVICE_OBJECT]]" "-input=[[HOST_OBJECT]]"

// RUN: %clangxx -c -fno-sycl-rdc -fsycl -fsycl-targets=spir64_gen \
// RUN: %clangxx -c -fno-sycl-rdc -fsycl -fsycl-targets=spir64_gen -fno-spirv \
// RUN: --target=x86_64-unknown-linux-gnu -Xsycl-target-backend \
// RUN: "-device skl" --sysroot=%S/Inputs/SYCL -ccc-print-phases %s \
// RUN: -fno-sycl-device-lib=all 2>&1 \
Expand Down
Loading
Loading