Skip to content

Commit 35ed0b0

Browse files
[SYCL] Fix handling of discarded events in preview lib (#19005)
The queue implementation assumed that handler.finalize() will return either a valid (non-discarded) event or nullptr (that's why parseEvent is nop in preview mode). However, that was not always true. It was possible for scheduler to only mark an event as discarded after handler.finalize() completed (during actual command execution). This resulted in discarded event being stored in LastEventPtr in the queue and calls to wait() on that discarded event (which is not allowed) in MT scenarios. Fix this, by modyfing addCG() to mark the event as discarded immediately and to return nullptr is the event is discarded. --------- Co-authored-by: aelovikov-intel <[email protected]>
1 parent dd7ac1a commit 35ed0b0

File tree

6 files changed

+31
-16
lines changed

6 files changed

+31
-16
lines changed

sycl/include/sycl/handler.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -571,6 +571,9 @@ class __SYCL_EXPORT handler {
571571
/// object destruction.
572572
///
573573
/// \return a SYCL event object representing the command group
574+
///
575+
/// Note: in preview mode, handler.finalize() is expected to return
576+
/// nullptr if the event is not needed (discarded).
574577
#ifdef __INTEL_PREVIEW_BREAKING_CHANGES
575578
detail::EventImplPtr finalize();
576579
#else

sycl/source/detail/queue_impl.hpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -712,7 +712,11 @@ class queue_impl : public std::enable_shared_from_this<queue_impl> {
712712
}
713713

714714
#ifdef __INTEL_PREVIEW_BREAKING_CHANGES
715-
#define parseEvent(arg) (arg)
715+
inline const detail::EventImplPtr &
716+
parseEvent(const detail::EventImplPtr &Event) {
717+
assert(!Event || !Event->isDiscarded());
718+
return Event;
719+
}
716720
#else
717721
inline detail::EventImplPtr parseEvent(const event &Event) {
718722
const detail::EventImplPtr &EventImpl = getSyclObjImpl(Event);

sycl/source/detail/scheduler/commands.cpp

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3122,22 +3122,17 @@ ur_result_t ExecCGCommand::enqueueImpQueue() {
31223122
auto RawEvents = getUrEvents(EventImpls);
31233123
flushCrossQueueDeps(EventImpls);
31243124

3125-
// We can omit creating a UR event and create a "discarded" event if the
3126-
// command has been explicitly marked as not needing an event, e.g. if the
3127-
// user did not ask for one, and there are no requirements.
3128-
bool DiscardUrEvent = MQueue && !MEventNeeded &&
3129-
MQueue->supportsDiscardingPiEvents() &&
3130-
MCommandGroup->getRequirements().size() == 0;
3131-
31323125
ur_event_handle_t UREvent = nullptr;
3133-
ur_event_handle_t *Event = DiscardUrEvent ? nullptr : &UREvent;
3134-
detail::event_impl *EventImpl = DiscardUrEvent ? nullptr : MEvent.get();
3126+
ur_event_handle_t *Event = !MEventNeeded ? nullptr : &UREvent;
3127+
detail::event_impl *EventImpl = !MEventNeeded ? nullptr : MEvent.get();
31353128

31363129
auto SetEventHandleOrDiscard = [&]() {
3137-
if (Event)
3130+
if (!MEventNeeded) {
3131+
assert(MEvent->isDiscarded());
3132+
} else {
3133+
assert(!MEvent->isDiscarded());
31383134
MEvent->setHandle(*Event);
3139-
else
3140-
MEvent->setStateDiscarded();
3135+
}
31413136
};
31423137

31433138
switch (MCommandGroup->getType()) {

sycl/source/detail/scheduler/scheduler.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,14 @@ EventImplPtr Scheduler::addCG(
133133
}
134134
NewEvent = NewCmd->getEvent();
135135
NewEvent->setSubmissionTime();
136+
137+
// This is the last moment we can mark the event as discarded.
138+
// Doing this during command execution would lead to incorrect
139+
// event handling (as event would change it's state from non-discarded
140+
// to discarded).
141+
if (!EventNeeded) {
142+
NewEvent->setStateDiscarded();
143+
}
136144
}
137145

138146
enqueueCommandForCG(NewEvent, AuxiliaryCmds);

sycl/source/detail/scheduler/scheduler.hpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -376,7 +376,8 @@ class Scheduler {
376376
/// directly to the queue.
377377
/// \param Dependencies Optional list of dependency
378378
/// sync points when enqueuing to a command buffer.
379-
/// \return an event object to wait on for command group completion.
379+
/// \return an event object to wait on for command group completion. It can
380+
/// be a discarded event.
380381
EventImplPtr addCG(
381382
std::unique_ptr<detail::CG> CommandGroup, const QueueImplPtr &Queue,
382383
bool EventNeeded, ur_exp_command_buffer_handle_t CommandBuffer = nullptr,

sycl/source/handler.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -894,11 +894,15 @@ event handler::finalize() {
894894
#endif
895895
}
896896

897+
bool DiscardEvent = !impl->MEventNeeded && Queue &&
898+
Queue->supportsDiscardingPiEvents() &&
899+
CommandGroup->getRequirements().size() == 0;
900+
897901
detail::EventImplPtr Event = detail::Scheduler::getInstance().addCG(
898-
std::move(CommandGroup), Queue->shared_from_this(), impl->MEventNeeded);
902+
std::move(CommandGroup), Queue->shared_from_this(), !DiscardEvent);
899903

900904
#ifdef __INTEL_PREVIEW_BREAKING_CHANGES
901-
MLastEvent = Event;
905+
MLastEvent = DiscardEvent ? nullptr : Event;
902906
#else
903907
MLastEvent = detail::createSyclObjFromImpl<event>(Event);
904908
#endif

0 commit comments

Comments
 (0)