Skip to content

Commit 88ac4a6

Browse files
Add a workaround to avoid waiting for events in L0 plugin during submit
Level Zero plugin has recently started to call wait on events during piEventRelease. With the queue::wait change we started to release some events during submit, prior to their completion. This introduces implicit wait on every submit that would produce such an event, which also interferes with level zero batching. Work around this by storing such events for level zero only to release them later.
1 parent 97d76dc commit 88ac4a6

File tree

2 files changed

+31
-6
lines changed

2 files changed

+31
-6
lines changed

sycl/source/detail/queue_impl.cpp

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,9 @@ event queue_impl::memset(const std::shared_ptr<detail::queue_impl> &Self,
6262

6363
event ResEvent = prepareUSMEvent(Self, NativeEvent);
6464
// Track only if we won't be able to handle it with piQueueFinish.
65-
if (!MSupportOOO)
65+
// FIXME these events are stored for level zero until as a workaround, remove
66+
// once piEventRelease no longer calls wait on the event in the plugin.
67+
if (!MSupportOOO || getPlugin().getBackend() == backend::level_zero)
6668
addSharedEvent(ResEvent);
6769
return ResEvent;
6870
}
@@ -79,7 +81,9 @@ event queue_impl::memcpy(const std::shared_ptr<detail::queue_impl> &Self,
7981

8082
event ResEvent = prepareUSMEvent(Self, NativeEvent);
8183
// Track only if we won't be able to handle it with piQueueFinish.
82-
if (!MSupportOOO)
84+
// FIXME these events are stored for level zero until as a workaround, remove
85+
// once piEventRelease no longer calls wait on the event in the plugin.
86+
if (!MSupportOOO || getPlugin().getBackend() == backend::level_zero)
8387
addSharedEvent(ResEvent);
8488
return ResEvent;
8589
}
@@ -97,7 +101,9 @@ event queue_impl::mem_advise(const std::shared_ptr<detail::queue_impl> &Self,
97101

98102
event ResEvent = prepareUSMEvent(Self, NativeEvent);
99103
// Track only if we won't be able to handle it with piQueueFinish.
100-
if (!MSupportOOO)
104+
// FIXME these events are stored for level zero until as a workaround, remove
105+
// once piEventRelease no longer calls wait on the event in the plugin.
106+
if (!MSupportOOO || getPlugin().getBackend() == backend::level_zero)
101107
addSharedEvent(ResEvent);
102108
return ResEvent;
103109
}
@@ -109,7 +115,11 @@ void queue_impl::addEvent(const event &Event) {
109115
// if there is no command on the event, we cannot track it with MEventsWeak
110116
// as that will leave it with no owner. Track in MEventsShared only if we're
111117
// unable to call piQueueFinish during wait.
112-
if (is_host() || !MSupportOOO)
118+
// FIXME these events are stored for level zero until as a workaround,
119+
// remove once piEventRelease no longer calls wait on the event in the
120+
// plugin.
121+
if (is_host() || !MSupportOOO ||
122+
getPlugin().getBackend() == backend::level_zero)
113123
addSharedEvent(Event);
114124
} else {
115125
std::weak_ptr<event_impl> EventWeakPtr{Eimpl};
@@ -122,7 +132,10 @@ void queue_impl::addEvent(const event &Event) {
122132
/// but some events have no other owner. In this case,
123133
/// addSharedEvent will have the queue track the events via a shared pointer.
124134
void queue_impl::addSharedEvent(const event &Event) {
125-
assert(is_host() || !MSupportOOO);
135+
// FIXME The assertion should be corrected once the Level Zero workaround is
136+
// removed.
137+
assert(is_host() || !MSupportOOO ||
138+
getPlugin().getBackend() == backend::level_zero);
126139
std::lock_guard<std::mutex> Lock(MMutex);
127140
// Events stored in MEventsShared are not released anywhere else aside from
128141
// calls to queue::wait/wait_and_throw, which a user application might not
@@ -274,6 +287,12 @@ void queue_impl::wait(const detail::code_location &CodeLoc) {
274287
if (std::shared_ptr<event_impl> EventImplSharedPtr =
275288
EventImplWeakPtr.lock())
276289
EventImplSharedPtr->cleanupCommand(EventImplSharedPtr);
290+
// FIXME these events are stored for level zero until as a workaround,
291+
// remove once piEventRelease no longer calls wait on the event in the
292+
// plugin.
293+
if (Plugin.getBackend() == backend::level_zero) {
294+
SharedEvents.clear();
295+
}
277296
assert(SharedEvents.empty() && "Queues that support calling piQueueFinish "
278297
"shouldn't have shared events");
279298
} else {

sycl/unittests/queue/Wait.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
#include <CL/sycl.hpp>
1010
#include <detail/event_impl.hpp>
11+
#include <detail/platform_impl.hpp>
1112
#include <detail/scheduler/commands.hpp>
1213
#include <gtest/gtest.h>
1314
#include <helpers/PiMock.hpp>
@@ -120,7 +121,12 @@ TEST(QueueWait, QueueWaitTest) {
120121
TestContext = {};
121122
Q.memset(HostAlloc, 42, 1);
122123
// No need to keep the event since we'll use piQueueFinish.
123-
ASSERT_EQ(TestContext.EventReferenceCount, 0);
124+
// FIXME ... unless the plugin is Level Zero, where there's a workaround that
125+
// releases events later.
126+
if (detail::getSyclObjImpl(Plt)->getPlugin().getBackend() !=
127+
backend::level_zero) {
128+
ASSERT_EQ(TestContext.EventReferenceCount, 0);
129+
}
124130
Q.wait();
125131
ASSERT_EQ(TestContext.NEventsWaitedFor, 0);
126132
ASSERT_TRUE(TestContext.PiQueueFinishCalled);

0 commit comments

Comments
 (0)