Skip to content

Commit 03f7ed4

Browse files
authored
[SYCL][RTC] Extend mixed SYCL/ESIMD support (#17373)
Add support for the situation that after the first round of splitting, a `ModuleDesc` contains a mix of SYCL and ESIMD kernels. --------- Signed-off-by: Julian Oppermann <julian.oppermann@codeplay.com>
1 parent baa517d commit 03f7ed4

File tree

2 files changed

+74
-59
lines changed

2 files changed

+74
-59
lines changed

sycl-jit/jit-compiler/lib/rtc/DeviceCompilation.cpp

Lines changed: 62 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -659,79 +659,82 @@ jit_compiler::performPostLink(std::unique_ptr<llvm::Module> Module,
659659
// TODO: Call `verifyNoCrossModuleDeviceGlobalUsage` if device globals shall
660660
// be processed.
661661

662-
// TODO: This allocation assumes that there are no further splits required,
663-
// i.e. there are no mixed SYCL/ESIMD modules.
664-
RTCBundleInfo BundleInfo;
665-
BundleInfo.DevImgInfos = DynArray<RTCDevImgInfo>{Splitter->remainingSplits()};
662+
SmallVector<RTCDevImgInfo> DevImgInfoVec;
666663
SmallVector<std::unique_ptr<llvm::Module>> Modules;
667664

668-
auto *DevImgInfoIt = BundleInfo.DevImgInfos.begin();
669-
while (Splitter->hasMoreSplits()) {
670-
assert(DevImgInfoIt != BundleInfo.DevImgInfos.end());
665+
// TODO: The following logic is missing the ability to link ESIMD and SYCL
666+
// modules back together, which would be requested via
667+
// `-fno-sycl-device-code-split-esimd` as a prerequisite for compiling
668+
// `invoke_simd` code.
671669

670+
while (Splitter->hasMoreSplits()) {
672671
ModuleDesc MDesc = Splitter->nextSplit();
673-
RTCDevImgInfo &DevImgInfo = *DevImgInfoIt++;
674672

675673
// TODO: Call `MDesc.fixupLinkageOfDirectInvokeSimdTargets()` when
676674
// `invoke_simd` is supported.
677675

678676
SmallVector<ModuleDesc, 2> ESIMDSplits =
679677
splitByESIMD(std::move(MDesc), EmitOnlyKernelsAsEntryPoints);
680-
assert(!ESIMDSplits.empty());
681-
if (ESIMDSplits.size() > 1) {
682-
return createStringError("Mixing SYCL and ESIMD code is unsupported");
683-
}
684-
MDesc = std::move(ESIMDSplits.front());
685-
686-
if (MDesc.isESIMD()) {
687-
// `sycl-post-link` has a `-lower-esimd` option, but there's no clang
688-
// driver option to influence it. Rather, the driver sets it
689-
// unconditionally in the multi-file output mode, which we are mimicking
690-
// here.
691-
lowerEsimdConstructs(MDesc, PerformOpts);
692-
}
693-
694-
MDesc.saveSplitInformationAsMetadata();
695-
696-
DevImgInfo.SymbolTable = FrozenSymbolTable{MDesc.entries().size()};
697-
transform(MDesc.entries(), DevImgInfo.SymbolTable.begin(),
698-
[](Function *F) { return F->getName(); });
699-
700-
// TODO: Determine what is requested.
701-
GlobalBinImageProps PropReq{
702-
/*EmitKernelParamInfo=*/true, /*EmitProgramMetadata=*/true,
703-
/*EmitExportedSymbols=*/true, /*EmitImportedSymbols=*/true,
704-
/*DeviceGlobals=*/false};
705-
PropertySetRegistry Properties =
706-
computeModuleProperties(MDesc.getModule(), MDesc.entries(), PropReq);
707-
// TODO: Manually add `compile_target` property as in
708-
// `saveModuleProperties`?
709-
const auto &PropertySets = Properties.getPropSets();
710-
711-
DevImgInfo.Properties = FrozenPropertyRegistry{PropertySets.size()};
712-
for (auto [KV, FrozenPropSet] :
713-
zip_equal(PropertySets, DevImgInfo.Properties)) {
714-
const auto &PropertySetName = KV.first;
715-
const auto &PropertySet = KV.second;
716-
FrozenPropSet =
717-
FrozenPropertySet{PropertySetName.str(), PropertySet.size()};
718-
for (auto [KV2, FrozenProp] :
719-
zip_equal(PropertySet, FrozenPropSet.Values)) {
720-
const auto &PropertyName = KV2.first;
721-
const auto &PropertyValue = KV2.second;
722-
FrozenProp =
723-
PropertyValue.getType() == PropertyValue::Type::UINT32
724-
? FrozenPropertyValue{PropertyName.str(),
725-
PropertyValue.asUint32()}
726-
: FrozenPropertyValue{PropertyName.str(),
727-
PropertyValue.asRawByteArray(),
728-
PropertyValue.getRawByteArraySize()};
678+
for (auto &ES : ESIMDSplits) {
679+
MDesc = std::move(ES);
680+
681+
if (MDesc.isESIMD()) {
682+
// `sycl-post-link` has a `-lower-esimd` option, but there's no clang
683+
// driver option to influence it. Rather, the driver sets it
684+
// unconditionally in the multi-file output mode, which we are mimicking
685+
// here.
686+
lowerEsimdConstructs(MDesc, PerformOpts);
729687
}
730-
};
731688

732-
Modules.push_back(MDesc.releaseModulePtr());
689+
MDesc.saveSplitInformationAsMetadata();
690+
691+
RTCDevImgInfo &DevImgInfo = DevImgInfoVec.emplace_back();
692+
DevImgInfo.SymbolTable = FrozenSymbolTable{MDesc.entries().size()};
693+
transform(MDesc.entries(), DevImgInfo.SymbolTable.begin(),
694+
[](Function *F) { return F->getName(); });
695+
696+
// TODO: Determine what is requested.
697+
GlobalBinImageProps PropReq{
698+
/*EmitKernelParamInfo=*/true, /*EmitProgramMetadata=*/true,
699+
/*EmitExportedSymbols=*/true, /*EmitImportedSymbols=*/true,
700+
/*DeviceGlobals=*/false};
701+
PropertySetRegistry Properties =
702+
computeModuleProperties(MDesc.getModule(), MDesc.entries(), PropReq);
703+
// TODO: Manually add `compile_target` property as in
704+
// `saveModuleProperties`?
705+
const auto &PropertySets = Properties.getPropSets();
706+
707+
DevImgInfo.Properties = FrozenPropertyRegistry{PropertySets.size()};
708+
for (auto [KV, FrozenPropSet] :
709+
zip_equal(PropertySets, DevImgInfo.Properties)) {
710+
const auto &PropertySetName = KV.first;
711+
const auto &PropertySet = KV.second;
712+
FrozenPropSet =
713+
FrozenPropertySet{PropertySetName.str(), PropertySet.size()};
714+
for (auto [KV2, FrozenProp] :
715+
zip_equal(PropertySet, FrozenPropSet.Values)) {
716+
const auto &PropertyName = KV2.first;
717+
const auto &PropertyValue = KV2.second;
718+
FrozenProp =
719+
PropertyValue.getType() == PropertyValue::Type::UINT32
720+
? FrozenPropertyValue{PropertyName.str(),
721+
PropertyValue.asUint32()}
722+
: FrozenPropertyValue{PropertyName.str(),
723+
PropertyValue.asRawByteArray(),
724+
PropertyValue.getRawByteArraySize()};
725+
}
726+
};
727+
728+
Modules.push_back(MDesc.releaseModulePtr());
729+
}
733730
}
734731

732+
assert(DevImgInfoVec.size() == Modules.size());
733+
RTCBundleInfo BundleInfo;
734+
BundleInfo.DevImgInfos = DynArray<RTCDevImgInfo>{DevImgInfoVec.size()};
735+
std::move(DevImgInfoVec.begin(), DevImgInfoVec.end(),
736+
BundleInfo.DevImgInfos.begin());
737+
735738
return PostLinkResult{std::move(BundleInfo), std::move(Modules)};
736739
}
737740

sycl/test-e2e/KernelCompiler/kernel_compiler_sycl_jit.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -515,6 +515,18 @@ int test_esimd() {
515515
run_2(q, kESIMD, true, 2.38f);
516516
run_2(q, kSYCL, false, 1.41f);
517517

518+
// Deactivate implicit module splitting to exercise the downstream
519+
// ESIMD-specific splitting.
520+
source_kb kbSrcMixed2 = syclex::create_kernel_bundle_from_source(
521+
ctx, syclex::source_language::sycl_jit, mixedSource);
522+
exe_kb kbExeMixed2 =
523+
syclex::build(kbSrcMixed2, syclex::properties{syclex::build_options{
524+
"-fsycl-device-code-split=off"}});
525+
526+
assert(kbExeMixed2.ext_oneapi_has_kernel("vector_add_esimd"));
527+
assert(kbExeMixed2.ext_oneapi_has_kernel("vec_add"));
528+
assert(std::distance(kbExeMixed2.begin(), kbExeMixed2.end()) == 2);
529+
518530
return 0;
519531
}
520532

0 commit comments

Comments
 (0)