Skip to content

Commit b333cee

Browse files
[SYCL] Fix an issue when spec constants are set in a CG w/o a kernel (#6826)
Fix an issue introduced by #6595. Removing the version check also removed the implicit check for whether we have a command group at all, which caused a CTS regression.
1 parent 593ba5f commit b333cee

File tree

2 files changed

+123
-104
lines changed

2 files changed

+123
-104
lines changed

sycl/source/handler.cpp

Lines changed: 108 additions & 104 deletions
Original file line numberDiff line numberDiff line change
@@ -93,122 +93,126 @@ event handler::finalize() {
9393
return MLastEvent;
9494
MIsFinalized = true;
9595

96-
std::shared_ptr<detail::kernel_bundle_impl> KernelBundleImpPtr = nullptr;
97-
// If there were uses of set_specialization_constant build the kernel_bundle
98-
KernelBundleImpPtr = getOrInsertHandlerKernelBundle(/*Insert=*/false);
99-
if (KernelBundleImpPtr) {
100-
// Make sure implicit non-interop kernel bundles have the kernel
101-
if (!KernelBundleImpPtr->isInterop() &&
102-
!MImpl->isStateExplicitKernelBundle()) {
103-
kernel_id KernelID =
104-
detail::ProgramManager::getInstance().getSYCLKernelID(MKernelName);
105-
bool KernelInserted =
106-
KernelBundleImpPtr->add_kernel(KernelID, MQueue->get_device());
107-
// If kernel was not inserted and the bundle is in input mode we try
108-
// building it and trying to find the kernel in executable mode
109-
if (!KernelInserted &&
110-
KernelBundleImpPtr->get_bundle_state() == bundle_state::input) {
111-
auto KernelBundle =
96+
const auto &type = getType();
97+
if (type == detail::CG::Kernel) {
98+
// If there were uses of set_specialization_constant build the kernel_bundle
99+
std::shared_ptr<detail::kernel_bundle_impl> KernelBundleImpPtr =
100+
getOrInsertHandlerKernelBundle(/*Insert=*/false);
101+
if (KernelBundleImpPtr) {
102+
// Make sure implicit non-interop kernel bundles have the kernel
103+
if (!KernelBundleImpPtr->isInterop() &&
104+
!MImpl->isStateExplicitKernelBundle()) {
105+
kernel_id KernelID =
106+
detail::ProgramManager::getInstance().getSYCLKernelID(MKernelName);
107+
bool KernelInserted =
108+
KernelBundleImpPtr->add_kernel(KernelID, MQueue->get_device());
109+
// If kernel was not inserted and the bundle is in input mode we try
110+
// building it and trying to find the kernel in executable mode
111+
if (!KernelInserted &&
112+
KernelBundleImpPtr->get_bundle_state() == bundle_state::input) {
113+
auto KernelBundle =
114+
detail::createSyclObjFromImpl<kernel_bundle<bundle_state::input>>(
115+
KernelBundleImpPtr);
116+
kernel_bundle<bundle_state::executable> ExecKernelBundle =
117+
build(KernelBundle);
118+
KernelBundleImpPtr = detail::getSyclObjImpl(ExecKernelBundle);
119+
setHandlerKernelBundle(KernelBundleImpPtr);
120+
KernelInserted =
121+
KernelBundleImpPtr->add_kernel(KernelID, MQueue->get_device());
122+
}
123+
// If the kernel was not found in executable mode we throw an exception
124+
if (!KernelInserted)
125+
throw sycl::exception(make_error_code(errc::runtime),
126+
"Failed to add kernel to kernel bundle.");
127+
}
128+
129+
switch (KernelBundleImpPtr->get_bundle_state()) {
130+
case bundle_state::input: {
131+
// Underlying level expects kernel_bundle to be in executable state
132+
kernel_bundle<bundle_state::executable> ExecBundle = build(
112133
detail::createSyclObjFromImpl<kernel_bundle<bundle_state::input>>(
113-
KernelBundleImpPtr);
114-
kernel_bundle<bundle_state::executable> ExecKernelBundle =
115-
build(KernelBundle);
116-
KernelBundleImpPtr = detail::getSyclObjImpl(ExecKernelBundle);
134+
KernelBundleImpPtr));
135+
KernelBundleImpPtr = detail::getSyclObjImpl(ExecBundle);
117136
setHandlerKernelBundle(KernelBundleImpPtr);
118-
KernelInserted =
119-
KernelBundleImpPtr->add_kernel(KernelID, MQueue->get_device());
137+
break;
138+
}
139+
case bundle_state::executable:
140+
// Nothing to do
141+
break;
142+
case bundle_state::object:
143+
assert(0 && "Expected that the bundle is either in input or executable "
144+
"states.");
145+
break;
120146
}
121-
// If the kernel was not found in executable mode we throw an exception
122-
if (!KernelInserted)
123-
throw sycl::exception(make_error_code(errc::runtime),
124-
"Failed to add kernel to kernel bundle.");
125147
}
126148

127-
switch (KernelBundleImpPtr->get_bundle_state()) {
128-
case bundle_state::input: {
129-
// Underlying level expects kernel_bundle to be in executable state
130-
kernel_bundle<bundle_state::executable> ExecBundle = build(
131-
detail::createSyclObjFromImpl<kernel_bundle<bundle_state::input>>(
132-
KernelBundleImpPtr));
133-
KernelBundleImpPtr = detail::getSyclObjImpl(ExecBundle);
134-
setHandlerKernelBundle(KernelBundleImpPtr);
135-
break;
136-
}
137-
case bundle_state::executable:
138-
// Nothing to do
139-
break;
140-
case bundle_state::object:
141-
assert(0 && "Expected that the bundle is either in input or executable "
142-
"states.");
143-
break;
144-
}
145-
}
149+
if (MRequirements.size() + MEvents.size() + MStreamStorage.size() == 0) {
150+
// if user does not add a new dependency to the dependency graph, i.e.
151+
// the graph is not changed, then this faster path is used to submit
152+
// kernel bypassing scheduler and avoiding CommandGroup, Command objects
153+
// creation.
146154

147-
const auto &type = getType();
148-
if (type == detail::CG::Kernel &&
149-
MRequirements.size() + MEvents.size() + MStreamStorage.size() == 0) {
150-
// if user does not add a new dependency to the dependency graph, i.e.
151-
// the graph is not changed, then this faster path is used to submit kernel
152-
// bypassing scheduler and avoiding CommandGroup, Command objects creation.
153-
154-
std::vector<RT::PiEvent> RawEvents;
155-
detail::EventImplPtr NewEvent;
156-
RT::PiEvent *OutEvent = nullptr;
157-
158-
auto EnqueueKernel = [&]() {
159-
// 'Result' for single point of return
160-
pi_int32 Result = PI_ERROR_INVALID_VALUE;
161-
162-
if (MQueue->is_host()) {
163-
MHostKernel->call(
164-
MNDRDesc, (NewEvent) ? NewEvent->getHostProfilingInfo() : nullptr);
165-
Result = PI_SUCCESS;
166-
} else {
167-
if (MQueue->getPlugin().getBackend() ==
168-
backend::ext_intel_esimd_emulator) {
169-
MQueue->getPlugin().call<detail::PiApiKind::piEnqueueKernelLaunch>(
170-
nullptr, reinterpret_cast<pi_kernel>(MHostKernel->getPtr()),
171-
MNDRDesc.Dims, &MNDRDesc.GlobalOffset[0], &MNDRDesc.GlobalSize[0],
172-
&MNDRDesc.LocalSize[0], 0, nullptr, nullptr);
155+
std::vector<RT::PiEvent> RawEvents;
156+
detail::EventImplPtr NewEvent;
157+
RT::PiEvent *OutEvent = nullptr;
158+
159+
auto EnqueueKernel = [&]() {
160+
// 'Result' for single point of return
161+
pi_int32 Result = PI_ERROR_INVALID_VALUE;
162+
163+
if (MQueue->is_host()) {
164+
MHostKernel->call(MNDRDesc, (NewEvent)
165+
? NewEvent->getHostProfilingInfo()
166+
: nullptr);
173167
Result = PI_SUCCESS;
174168
} else {
175-
Result = enqueueImpKernel(MQueue, MNDRDesc, MArgs, KernelBundleImpPtr,
176-
MKernel, MKernelName, MOSModuleHandle,
177-
RawEvents, OutEvent, nullptr);
169+
if (MQueue->getPlugin().getBackend() ==
170+
backend::ext_intel_esimd_emulator) {
171+
MQueue->getPlugin().call<detail::PiApiKind::piEnqueueKernelLaunch>(
172+
nullptr, reinterpret_cast<pi_kernel>(MHostKernel->getPtr()),
173+
MNDRDesc.Dims, &MNDRDesc.GlobalOffset[0],
174+
&MNDRDesc.GlobalSize[0], &MNDRDesc.LocalSize[0], 0, nullptr,
175+
nullptr);
176+
Result = PI_SUCCESS;
177+
} else {
178+
Result = enqueueImpKernel(
179+
MQueue, MNDRDesc, MArgs, KernelBundleImpPtr, MKernel,
180+
MKernelName, MOSModuleHandle, RawEvents, OutEvent, nullptr);
181+
}
178182
}
183+
return Result;
184+
};
185+
186+
bool DiscardEvent = false;
187+
if (MQueue->has_discard_events_support()) {
188+
// Kernel only uses assert if it's non interop one
189+
bool KernelUsesAssert =
190+
!(MKernel && MKernel->isInterop()) &&
191+
detail::ProgramManager::getInstance().kernelUsesAssert(
192+
MOSModuleHandle, MKernelName);
193+
DiscardEvent = !KernelUsesAssert;
179194
}
180-
return Result;
181-
};
182-
183-
bool DiscardEvent = false;
184-
if (MQueue->has_discard_events_support()) {
185-
// Kernel only uses assert if it's non interop one
186-
bool KernelUsesAssert =
187-
!(MKernel && MKernel->isInterop()) &&
188-
detail::ProgramManager::getInstance().kernelUsesAssert(
189-
MOSModuleHandle, MKernelName);
190-
DiscardEvent = !KernelUsesAssert;
191-
}
192195

193-
if (DiscardEvent) {
194-
if (PI_SUCCESS != EnqueueKernel())
195-
throw runtime_error("Enqueue process failed.",
196-
PI_ERROR_INVALID_OPERATION);
197-
} else {
198-
NewEvent = std::make_shared<detail::event_impl>(MQueue);
199-
NewEvent->setContextImpl(MQueue->getContextImplPtr());
200-
NewEvent->setStateIncomplete();
201-
OutEvent = &NewEvent->getHandleRef();
202-
203-
if (PI_SUCCESS != EnqueueKernel())
204-
throw runtime_error("Enqueue process failed.",
205-
PI_ERROR_INVALID_OPERATION);
206-
else if (NewEvent->is_host() || NewEvent->getHandleRef() == nullptr)
207-
NewEvent->setComplete();
208-
209-
MLastEvent = detail::createSyclObjFromImpl<event>(NewEvent);
196+
if (DiscardEvent) {
197+
if (PI_SUCCESS != EnqueueKernel())
198+
throw runtime_error("Enqueue process failed.",
199+
PI_ERROR_INVALID_OPERATION);
200+
} else {
201+
NewEvent = std::make_shared<detail::event_impl>(MQueue);
202+
NewEvent->setContextImpl(MQueue->getContextImplPtr());
203+
NewEvent->setStateIncomplete();
204+
OutEvent = &NewEvent->getHandleRef();
205+
206+
if (PI_SUCCESS != EnqueueKernel())
207+
throw runtime_error("Enqueue process failed.",
208+
PI_ERROR_INVALID_OPERATION);
209+
else if (NewEvent->is_host() || NewEvent->getHandleRef() == nullptr)
210+
NewEvent->setComplete();
211+
212+
MLastEvent = detail::createSyclObjFromImpl<event>(NewEvent);
213+
}
214+
return MLastEvent;
210215
}
211-
return MLastEvent;
212216
}
213217

214218
std::unique_ptr<detail::CG> CommandGroup;

sycl/unittests/SYCL2020/SpecializationConstant.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,3 +267,18 @@ TEST(SpecializationConstant, UseKernelBundleAfterSetSpecConst) {
267267
// Expected path
268268
}
269269
}
270+
271+
TEST(SpecializationConstant, NoKernel) {
272+
sycl::unittest::PiMock Mock;
273+
sycl::platform Plt = Mock.getPlatform();
274+
275+
const sycl::device Dev = Plt.get_devices()[0];
276+
sycl::context Ctx{Dev};
277+
sycl::queue Queue{Ctx, Dev};
278+
279+
Queue.submit([&](sycl::handler &CGH) {
280+
int ExpectedValue = 42;
281+
CGH.set_specialization_constant<SpecConst1>(ExpectedValue);
282+
EXPECT_EQ(CGH.get_specialization_constant<SpecConst1>(), ExpectedValue);
283+
});
284+
}

0 commit comments

Comments
 (0)