Skip to content

Commit ea0c067

Browse files
authored
[Driver][SYCL] Move traits macros settings to enable new model (#14635)
The SYCL device traits settings were being performed within the old model specific action builder class. Move this to the SYCL toolchain area to be accessible by both the new and old offloading model. Also hookup the new offloading model portion of this.
1 parent 1891dc3 commit ea0c067

File tree

4 files changed

+122
-98
lines changed

4 files changed

+122
-98
lines changed

clang/lib/Driver/Driver.cpp

Lines changed: 15 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,6 @@
7979
#include "llvm/Option/OptSpecifier.h"
8080
#include "llvm/Option/OptTable.h"
8181
#include "llvm/Option/Option.h"
82-
#include "llvm/SYCLLowerIR/DeviceConfigFile.hpp"
8382
#include "llvm/Support/CommandLine.h"
8483
#include "llvm/Support/ErrorHandling.h"
8584
#include "llvm/Support/ExitCodes.h"
@@ -6234,101 +6233,6 @@ class OffloadingActionBuilder final {
62346233
return FinalDeviceSections;
62356234
}
62366235

6237-
/// Reads device config file to find information about the SYCL targets in
6238-
/// `Targets`, and defines device traits macros accordingly.
6239-
void populateSYCLDeviceTraitsMacrosArgs(
6240-
Compilation &C, const DerivedArgList &Args,
6241-
const SmallVector<DeviceTargetInfo, 4> &Targets) const {
6242-
if (Targets.empty())
6243-
return;
6244-
6245-
const auto &TargetTable = DeviceConfigFile::TargetTable;
6246-
std::map<StringRef, unsigned int> AllDevicesHave;
6247-
std::map<StringRef, bool> AnyDeviceHas;
6248-
bool AnyDeviceHasAnyAspect = false;
6249-
unsigned int ValidTargets = 0;
6250-
for (const auto &[TC, BoundArch] : Targets) {
6251-
assert(TC && "Invalid SYCL Offload Toolchain");
6252-
// Try and find the device arch, if it's empty, try to search for either
6253-
// the whole Triple or just the 'ArchName' string.
6254-
auto TargetIt = TargetTable.end();
6255-
const llvm::Triple &TargetTriple = TC->getTriple();
6256-
const StringRef TargetArch{BoundArch};
6257-
if (!TargetArch.empty()) {
6258-
TargetIt = llvm::find_if(TargetTable, [&](const auto &Value) {
6259-
using namespace tools::SYCL;
6260-
StringRef Device{Value.first};
6261-
if (Device.consume_front(gen::AmdGPU))
6262-
return TargetArch == Device && TargetTriple.isAMDGCN();
6263-
if (Device.consume_front(gen::NvidiaGPU))
6264-
return TargetArch == Device && TargetTriple.isNVPTX();
6265-
if (Device.consume_front(gen::IntelGPU))
6266-
return TargetArch == Device && TargetTriple.isSPIRAOT();
6267-
return TargetArch == Device && isValidSYCLTriple(TargetTriple);
6268-
});
6269-
} else {
6270-
TargetIt = TargetTable.find(TargetTriple.str());
6271-
if (TargetIt == TargetTable.end())
6272-
TargetIt = TargetTable.find(TargetTriple.getArchName().str());
6273-
}
6274-
6275-
if (TargetIt != TargetTable.end()) {
6276-
const DeviceConfigFile::TargetInfo &Info = (*TargetIt).second;
6277-
++ValidTargets;
6278-
const auto &AspectList = Info.aspects;
6279-
const auto &MaySupportOtherAspects = Info.maySupportOtherAspects;
6280-
if (!AnyDeviceHasAnyAspect)
6281-
AnyDeviceHasAnyAspect = MaySupportOtherAspects;
6282-
for (const auto &Aspect : AspectList) {
6283-
// If target has an entry in the config file, the set of aspects
6284-
// supported by all devices supporting the target is 'AspectList'.
6285-
// If there's no entry, such set is empty.
6286-
const auto &AspectIt = AllDevicesHave.find(Aspect);
6287-
if (AspectIt != AllDevicesHave.end())
6288-
++AllDevicesHave[Aspect];
6289-
else
6290-
AllDevicesHave[Aspect] = 1;
6291-
// If target has an entry in the config file AND
6292-
// 'MaySupportOtherAspects' is false, the set of aspects supported
6293-
// by any device supporting the target is 'AspectList'. If there's
6294-
// no entry OR 'MaySupportOtherAspects' is true, such set contains
6295-
// all the aspects.
6296-
AnyDeviceHas[Aspect] = true;
6297-
}
6298-
}
6299-
}
6300-
6301-
// If there's no entry for the target in the device config file, the set
6302-
// of aspects supported by any device supporting the target contains all
6303-
// the aspects.
6304-
if (ValidTargets == 0)
6305-
AnyDeviceHasAnyAspect = true;
6306-
6307-
const Driver &D = C.getDriver();
6308-
if (AnyDeviceHasAnyAspect) {
6309-
// There exists some target that supports any given aspect.
6310-
constexpr static StringRef MacroAnyDeviceAnyAspect{
6311-
"-D__SYCL_ANY_DEVICE_HAS_ANY_ASPECT__=1"};
6312-
D.addSYCLDeviceTraitsMacroArg(Args, MacroAnyDeviceAnyAspect);
6313-
} else {
6314-
// Some of the aspects are not supported at all by any of the targets.
6315-
// Thus, we need to define individual macros for each supported aspect.
6316-
for (const auto &[TargetKey, SupportedTarget] : AnyDeviceHas) {
6317-
assert(SupportedTarget);
6318-
const SmallString<64> MacroAnyDevice{
6319-
{"-D__SYCL_ANY_DEVICE_HAS_", TargetKey, "__=1"}};
6320-
D.addSYCLDeviceTraitsMacroArg(Args, MacroAnyDevice);
6321-
}
6322-
}
6323-
for (const auto &[TargetKey, SupportedTargets] : AllDevicesHave) {
6324-
if (SupportedTargets != ValidTargets)
6325-
continue;
6326-
const SmallString<64> MacroAllDevices{
6327-
{"-D__SYCL_ALL_DEVICES_HAVE_", TargetKey, "__=1"}};
6328-
D.addSYCLDeviceTraitsMacroArg(Args, MacroAllDevices);
6329-
}
6330-
}
6331-
63326236
bool initialize() override {
63336237
using namespace tools::SYCL;
63346238
// Get the SYCL toolchains. If we don't get any, the action builder will
@@ -6563,7 +6467,17 @@ class OffloadingActionBuilder final {
65636467
// Define macros associated with `any_device_has/all_devices_have`
65646468
// according to the aspects defined in the DeviceConfigFile for the SYCL
65656469
// targets.
6566-
populateSYCLDeviceTraitsMacrosArgs(C, Args, SYCLTargetInfoList);
6470+
// We are using the Traits population function in multiple offloading
6471+
// models. These use different containers for the toolchain and arch
6472+
// values. Convert the list for usage with the new model expectations.
6473+
SmallVector<std::pair<const ToolChain *, StringRef>> TCAndArchs;
6474+
for (auto &TargetInfo : SYCLTargetInfoList) {
6475+
const ToolChain *TC = TargetInfo.TC;
6476+
StringRef Arch(TargetInfo.BoundArch);
6477+
std::pair<const ToolChain *, StringRef> TCAndArch(TC, Arch);
6478+
TCAndArchs.push_back(TCAndArch);
6479+
}
6480+
tools::SYCL::populateSYCLDeviceTraitsMacrosArgs(C, Args, TCAndArchs);
65676481

65686482
DeviceLinkerInputs.resize(SYCLTargetInfoList.size());
65696483
return false;
@@ -8003,6 +7917,10 @@ Action *Driver::BuildOffloadingActions(Compilation &C,
80037917

80047918
++TCAndArch;
80057919
}
7920+
// For SYCL based offloading, populate the device traits macros that are
7921+
// used during compilation.
7922+
if (Kind == Action::OFK_SYCL)
7923+
tools::SYCL::populateSYCLDeviceTraitsMacrosArgs(C, Args, TCAndArchs);
80067924
}
80077925

80087926
// HIP code in non-RDC mode will bundle the output if it invoked the linker.

clang/lib/Driver/ToolChains/SYCL.cpp

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include "llvm/Support/CommandLine.h"
1818
#include "llvm/Support/FileSystem.h"
1919
#include "llvm/Support/Path.h"
20+
#include "llvm/SYCLLowerIR/DeviceConfigFile.hpp"
2021
#include <algorithm>
2122
#include <sstream>
2223

@@ -384,6 +385,100 @@ SYCL::getDeviceLibraries(const Compilation &C, const llvm::Triple &TargetTriple,
384385
return LibraryList;
385386
}
386387

388+
/// Reads device config file to find information about the SYCL targets in
389+
/// `Targets`, and defines device traits macros accordingly.
390+
void SYCL::populateSYCLDeviceTraitsMacrosArgs(
391+
Compilation &C, const llvm::opt::ArgList &Args,
392+
const SmallVectorImpl<std::pair<const ToolChain *, StringRef>> &Targets) {
393+
if (Targets.empty())
394+
return;
395+
396+
const auto &TargetTable = DeviceConfigFile::TargetTable;
397+
std::map<StringRef, unsigned int> AllDevicesHave;
398+
std::map<StringRef, bool> AnyDeviceHas;
399+
bool AnyDeviceHasAnyAspect = false;
400+
unsigned int ValidTargets = 0;
401+
for (const auto &[TC, BoundArch] : Targets) {
402+
assert(TC && "Invalid SYCL Offload Toolchain");
403+
// Try and find the device arch, if it's empty, try to search for either
404+
// the whole Triple or just the 'ArchName' string.
405+
auto TargetIt = TargetTable.end();
406+
const llvm::Triple &TargetTriple = TC->getTriple();
407+
const StringRef TargetArch{BoundArch};
408+
if (!TargetArch.empty()) {
409+
TargetIt = llvm::find_if(TargetTable, [&](const auto &Value) {
410+
using namespace tools::SYCL;
411+
StringRef Device{Value.first};
412+
if (Device.consume_front(gen::AmdGPU))
413+
return TargetArch == Device && TargetTriple.isAMDGCN();
414+
if (Device.consume_front(gen::NvidiaGPU))
415+
return TargetArch == Device && TargetTriple.isNVPTX();
416+
if (Device.consume_front(gen::IntelGPU))
417+
return TargetArch == Device && TargetTriple.isSPIRAOT();
418+
return TargetArch == Device;
419+
});
420+
} else {
421+
TargetIt = TargetTable.find(TargetTriple.str());
422+
if (TargetIt == TargetTable.end())
423+
TargetIt = TargetTable.find(TargetTriple.getArchName().str());
424+
}
425+
426+
if (TargetIt != TargetTable.end()) {
427+
const DeviceConfigFile::TargetInfo &Info = (*TargetIt).second;
428+
++ValidTargets;
429+
const auto &AspectList = Info.aspects;
430+
const auto &MaySupportOtherAspects = Info.maySupportOtherAspects;
431+
if (!AnyDeviceHasAnyAspect)
432+
AnyDeviceHasAnyAspect = MaySupportOtherAspects;
433+
for (const auto &Aspect : AspectList) {
434+
// If target has an entry in the config file, the set of aspects
435+
// supported by all devices supporting the target is 'AspectList'.
436+
// If there's no entry, such set is empty.
437+
const auto &AspectIt = AllDevicesHave.find(Aspect);
438+
if (AspectIt != AllDevicesHave.end())
439+
++AllDevicesHave[Aspect];
440+
else
441+
AllDevicesHave[Aspect] = 1;
442+
// If target has an entry in the config file AND
443+
// 'MaySupportOtherAspects' is false, the set of aspects supported
444+
// by any device supporting the target is 'AspectList'. If there's
445+
// no entry OR 'MaySupportOtherAspects' is true, such set contains
446+
// all the aspects.
447+
AnyDeviceHas[Aspect] = true;
448+
}
449+
}
450+
}
451+
// If there's no entry for the target in the device config file, the set
452+
// of aspects supported by any device supporting the target contains all
453+
// the aspects.
454+
if (ValidTargets == 0)
455+
AnyDeviceHasAnyAspect = true;
456+
457+
const Driver &D = C.getDriver();
458+
if (AnyDeviceHasAnyAspect) {
459+
// There exists some target that supports any given aspect.
460+
constexpr static StringRef MacroAnyDeviceAnyAspect{
461+
"-D__SYCL_ANY_DEVICE_HAS_ANY_ASPECT__=1"};
462+
D.addSYCLDeviceTraitsMacroArg(Args, MacroAnyDeviceAnyAspect);
463+
} else {
464+
// Some of the aspects are not supported at all by any of the targets.
465+
// Thus, we need to define individual macros for each supported aspect.
466+
for (const auto &[TargetKey, SupportedTarget] : AnyDeviceHas) {
467+
assert(SupportedTarget);
468+
const SmallString<64> MacroAnyDevice{
469+
{"-D__SYCL_ANY_DEVICE_HAS_", TargetKey, "__=1"}};
470+
D.addSYCLDeviceTraitsMacroArg(Args, MacroAnyDevice);
471+
}
472+
}
473+
for (const auto &[TargetKey, SupportedTargets] : AllDevicesHave) {
474+
if (SupportedTargets != ValidTargets)
475+
continue;
476+
const SmallString<64> MacroAllDevices{
477+
{"-D__SYCL_ALL_DEVICES_HAVE_", TargetKey, "__=1"}};
478+
D.addSYCLDeviceTraitsMacroArg(Args, MacroAllDevices);
479+
}
480+
}
481+
387482
// The list should match pre-built SYCL device library files located in
388483
// compiler package. Once we add or remove any SYCL device library files,
389484
// the list should be updated accordingly.

clang/lib/Driver/ToolChains/SYCL.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,11 @@ SmallVector<std::string, 8> getDeviceLibraries(const Compilation &C,
4646
const llvm::Triple &TargetTriple,
4747
bool IsSpirvAOT);
4848

49+
// Populates the SYCL device traits macros.
50+
void populateSYCLDeviceTraitsMacrosArgs(Compilation &C,
51+
const llvm::opt::ArgList &Args,
52+
const SmallVectorImpl<std::pair<const ToolChain *, StringRef>> &Targets);
53+
4954
bool shouldDoPerObjectFileLinking(const Compilation &C);
5055
// Runs llvm-spirv to convert spirv to bc, llvm-link, which links multiple LLVM
5156
// bitcode. Converts generated bc back to spirv using llvm-spirv, wraps with

clang/test/Driver/sycl-device-traits-macros.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
/// TODO: macro settings only in old offloading model
21
/// Check that no device traits macros are defined if sycl is disabled:
32
// RUN: %clang -### %s 2>&1 \
43
// RUN: | FileCheck -check-prefix=CHECK-DISABLED %s
@@ -11,6 +10,8 @@
1110
/// occurrences of the macro definition, one for host and one for device.
1211
// RUN: %clang -fsycl --no-offload-new-driver -### %s 2>&1 \
1312
// RUN: | FileCheck -check-prefix=CHECK-ENABLED %s
13+
// RUN: %clang -fsycl --offload-new-driver -### %s 2>&1 \
14+
// RUN: | FileCheck -check-prefix=CHECK-ENABLED %s
1415
// CHECK-ENABLED-COUNT-2: "-D__SYCL_ANY_DEVICE_HAS_ANY_ASPECT__=1"
1516

1617
/// Check device traits macros are defined if sycl is enabled:
@@ -19,6 +20,8 @@
1920
/// definition, one for host and one for each of the two devices.
2021
// RUN: %clang -fsycl --no-offload-new-driver -fsycl-targets=spir64,spir64_gen -### %s 2>&1 \
2122
// RUN: | FileCheck -check-prefix=CHECK-SYCL-TARGETS %s
23+
// RUN: %clang -fsycl --offload-new-driver -fsycl-targets=spir64,spir64_gen -### %s 2>&1 \
24+
// RUN: | FileCheck -check-prefix=CHECK-SYCL-TARGETS %s
2225
// CHECK-SYCL-TARGETS-COUNT-3: "-D__SYCL_ANY_DEVICE_HAS_ANY_ASPECT__=1"
2326

2427
/// Check device traits macros are defined if sycl is enabled:
@@ -39,6 +42,9 @@
3942
// RUN: %clangxx -fsycl --no-offload-new-driver -nogpulib -fsycl-targets=intel_gpu_pvc,amd_gpu_gfx906 \
4043
// RUN: -fsycl-libspirv-path=%S/Inputs/SYCL/libspirv.bc -### %s 2>&1 \
4144
// RUN: | FileCheck -check-prefix=CHECK-SYCL-TARGETS-NO-MAY-SUPPORT-OTHER-ASPECTS %s
45+
// RUN: %clangxx -fsycl --offload-new-driver -nogpulib -fsycl-targets=intel_gpu_pvc,amd_gpu_gfx906 \
46+
// RUN: -fsycl-libspirv-path=%S/Inputs/SYCL/libspirv.bc -### %s 2>&1 \
47+
// RUN: | FileCheck -check-prefix=CHECK-SYCL-TARGETS-NO-MAY-SUPPORT-OTHER-ASPECTS %s
4248
// CHECK-SYCL-TARGETS-NO-MAY-SUPPORT-OTHER-ASPECTS-NOT: "-D__SYCL_ANY_DEVICE_HAS_ANY_ASPECT__=1"
4349
// CHECK-SYCL-TARGETS-NO-MAY-SUPPORT-OTHER-ASPECTS: "-D__SYCL_ANY_DEVICE_HAS_[[ASPECTi:[a-z0-9_]+]]__=1"
4450
// CHECK-SYCL-TARGETS-NO-MAY-SUPPORT-OTHER-ASPECTS: "-D__SYCL_ALL_DEVICES_HAVE_[[ASPECTj:[a-z0-9_]+]]__=1"

0 commit comments

Comments
 (0)