Skip to content

Commit cb610e4

Browse files
committed
[SYCL] Filter implicit kernel bundle images
The runtime currently uses implicit kernel bundles to allow for operations such as setting specialization constants. Since the handler does not know the kernel to launch before it is being launched, the implicit kernel bundle created is not limited to specific kernels. As an effect of this, the kernel bundle may try to build more device images than it needs. These changes make the runtime filter the device images of implicit kernel bundles as soon as the relevant kernel is known. Signed-off-by: Steffen Larsen <[email protected]>
1 parent 7ae7ca8 commit cb610e4

File tree

4 files changed

+77
-1
lines changed

4 files changed

+77
-1
lines changed

sycl/include/CL/sycl/handler.hpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -730,7 +730,8 @@ class __SYCL_EXPORT handler {
730730
// If the kernel lambda is callable with a kernel_handler argument, manifest
731731
// the associated kernel handler.
732732
if (IsCallableWithKernelHandler) {
733-
getOrInsertHandlerKernelBundle(/*Insert=*/true);
733+
getOrInsertFilteredHandlerKernelBundle(/*Insert=*/true,
734+
{get_kernel_id<KernelName>()});
734735
}
735736
}
736737

@@ -1272,6 +1273,9 @@ class __SYCL_EXPORT handler {
12721273
std::shared_ptr<detail::kernel_bundle_impl>
12731274
getOrInsertHandlerKernelBundle(bool Insert) const;
12741275

1276+
std::shared_ptr<detail::kernel_bundle_impl>
1277+
getOrInsertFilteredHandlerKernelBundle(bool Insert, kernel_id KernelId) const;
1278+
12751279
void setHandlerKernelBundle(
12761280
const std::shared_ptr<detail::kernel_bundle_impl> &NewKernelBundleImpPtr);
12771281

sycl/source/detail/kernel_bundle_impl.hpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -496,6 +496,16 @@ class kernel_bundle_impl {
496496

497497
bool isInterop() const { return MIsInterop; }
498498

499+
void filterImages(const kernel_id &KernelId) {
500+
std::vector<device_image_plain> FilteredDeviceImages;
501+
std::copy_if(MDeviceImages.begin(), MDeviceImages.end(),
502+
std::back_inserter(FilteredDeviceImages),
503+
[&KernelId](const device_image_plain &Img) {
504+
return Img.has_kernel(KernelId);
505+
});
506+
MDeviceImages = FilteredDeviceImages;
507+
}
508+
499509
private:
500510
context MContext;
501511
std::vector<device> MDevices;

sycl/source/handler.cpp

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,67 @@ handler::getOrInsertHandlerKernelBundle(bool Insert) const {
128128
return KernelBundleImpPtr;
129129
}
130130

131+
// Returns a shared_ptr to kernel_bundle stored in the extended members vector.
132+
//
133+
// If there is no kernel_bundle created:
134+
// returns newly created kernel_bundle with KernelId if Insert is true
135+
// returns shared_ptr(nullptr) if Insert is false
136+
//
137+
// If there already existed a kernel_bundle, the underlying device images are
138+
// filtered such that only the ones containing KernelId remain in the
139+
// kernel_bundle.
140+
std::shared_ptr<detail::kernel_bundle_impl>
141+
handler::getOrInsertFilteredHandlerKernelBundle(bool Insert,
142+
kernel_id KernelId) const {
143+
144+
std::lock_guard<std::mutex> Lock(
145+
detail::GlobalHandler::instance().getHandlerExtendedMembersMutex());
146+
147+
assert(!MSharedPtrStorage.empty());
148+
149+
std::shared_ptr<std::vector<detail::ExtendedMemberT>> ExtendedMembersVec =
150+
detail::convertToExtendedMembers(MSharedPtrStorage[0]);
151+
// Look for the kernel bundle in extended members
152+
std::shared_ptr<detail::kernel_bundle_impl> KernelBundleImpPtr;
153+
for (const detail::ExtendedMemberT &EMember : *ExtendedMembersVec)
154+
if (detail::ExtendedMembersType::HANDLER_KERNEL_BUNDLE == EMember.MType) {
155+
KernelBundleImpPtr =
156+
std::static_pointer_cast<detail::kernel_bundle_impl>(EMember.MData);
157+
break;
158+
}
159+
160+
// No kernel bundle yet, create one
161+
if (!KernelBundleImpPtr) {
162+
if (Insert) {
163+
KernelBundleImpPtr =
164+
detail::getSyclObjImpl(get_kernel_bundle<bundle_state::input>(
165+
MQueue->get_context(), {KernelId}));
166+
if (KernelBundleImpPtr->empty()) {
167+
KernelBundleImpPtr =
168+
detail::getSyclObjImpl(get_kernel_bundle<bundle_state::executable>(
169+
MQueue->get_context(), {KernelId}));
170+
}
171+
172+
detail::ExtendedMemberT EMember = {
173+
detail::ExtendedMembersType::HANDLER_KERNEL_BUNDLE,
174+
KernelBundleImpPtr};
175+
ExtendedMembersVec->push_back(EMember);
176+
}
177+
return KernelBundleImpPtr;
178+
}
179+
180+
auto HandlerImplMember = (*ExtendedMembersVec)[0];
181+
assert(detail::ExtendedMembersType::HANDLER_IMPL == HandlerImplMember.MType);
182+
auto HandlerImpl =
183+
std::static_pointer_cast<detail::handler_impl>(HandlerImplMember.MData);
184+
185+
// Kernel bundles set explicitly by the user must not be filtered
186+
if (!HandlerImpl->isStateExplicitKernelBundle())
187+
KernelBundleImpPtr->filterImages(KernelId);
188+
189+
return KernelBundleImpPtr;
190+
}
191+
131192
// Sets kernel bundle to the provided one. Either replaces existing one or
132193
// create a new entry in the extended members vector.
133194
void handler::setHandlerKernelBundle(

sycl/test/abi/sycl_symbols_linux.dump

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4320,6 +4320,7 @@ _ZNK2cl4sycl7context9getNativeEv
43204320
_ZNK2cl4sycl7handler14getHandlerImplEv
43214321
_ZNK2cl4sycl7handler27isStateExplicitKernelBundleEv
43224322
_ZNK2cl4sycl7handler30getOrInsertHandlerKernelBundleEb
4323+
_ZNK2cl4sycl7handler38getOrInsertFilteredHandlerKernelBundleEbNS0_9kernel_idE
43234324
_ZNK2cl4sycl7program10get_kernelENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
43244325
_ZNK2cl4sycl7program10get_kernelENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEb
43254326
_ZNK2cl4sycl7program10has_kernelENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE

0 commit comments

Comments
 (0)