Skip to content

Commit

Permalink
[SYCL][Docs] Make external events wait with queue (intel#12766)
Browse files Browse the repository at this point in the history
This commit adds the behavior to ext_oneapi_set_external_event that it
is also waited on when the queue is waited on.

---------

Signed-off-by: Larsen, Steffen <steffen.larsen@intel.com>
  • Loading branch information
steffenlarsen authored Feb 22, 2024
1 parent 343d953 commit b0f584c
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,11 @@ This is equivalent to calling `handler::depends_on()` in a command submission
with the `externalEvent` from the most recent call to this member function since
the previous command submission to the same queue.

If `queue::wait()` or `queue::wait_and_throw()` is called prior to any command
submission following a call to this member function, `externalEvent.wait()` is
called and `externalEvent` will not be a dependency on the next command
submitted to the queue.

Calls to this member function throw a `sycl::exception` with `errc::invalid` if
the queue does not have the `property::queue::in_order` property.

Expand Down
5 changes: 5 additions & 0 deletions sycl/source/detail/queue_impl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -516,6 +516,11 @@ void queue_impl::wait(const detail::code_location &CodeLoc) {
for (const EventImplPtr &Event : StreamsServiceEvents)
Event->wait(Event);

// If there is an external event set, we need to wait on it.
std::optional<event> ExternalEvent = popExternalEvent();
if (ExternalEvent)
ExternalEvent->wait();

#ifdef XPTI_ENABLE_INSTRUMENTATION
instrumentationEpilog(TelemetryEvent, Name, StreamID, IId);
#endif
Expand Down
62 changes: 54 additions & 8 deletions sycl/test-e2e/InOrderEventsExt/set_external_event.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,13 @@

constexpr size_t N = 1024;

int main() {
sycl::context Ctx;
sycl::device Dev = Ctx.get_devices()[0];

sycl::queue Q1{Ctx, Dev, {sycl::property::queue::in_order{}}};
sycl::queue Q2{Ctx, Dev, {sycl::property::queue::in_order{}}};
int check_work(sycl::queue &Q1, sycl::queue &Q2) {
std::cout << "Checking ext_oneapi_set_external_event for a workload."
<< std::endl;

sycl::buffer<int> DevDataBuf{sycl::range{N}};
sycl::accessor DevData{DevDataBuf};
int *HostData = (int *)malloc(N * sizeof(int) * 10);
int *HostData = new int[N * 10];

for (size_t I = 0; I < 10; ++I) {
Q1.fill(DevData, 0);
Expand Down Expand Up @@ -52,6 +49,55 @@ int main() {
}
}
}
free(HostData);
delete[] HostData;
return Failures;
}

int check_wait(sycl::queue &Q1, sycl::queue &Q2) {
std::cout << "Checking ext_oneapi_set_external_event with wait on queue."
<< std::endl;

sycl::buffer<int> DevDataBuf{sycl::range{N}};
sycl::accessor DevData{DevDataBuf};
int *HostData = new int[N];

Q1.fill(DevData, 0);
for (size_t I = 0; I < 10; ++I) {
Q1.submit([&](sycl::handler &h) {
h.require(DevData);
h.parallel_for(N, [=](sycl::item<1> Idx) { ++DevData[Idx]; });
});
}
sycl::event E = Q1.copy(DevData, HostData);

Q2.ext_oneapi_set_external_event(E);
Q2.wait_and_throw();

int Failures = 0;
for (size_t I = 0; I < N; ++I) {
int Expected = 10;
int Actual = HostData[I];
if (Expected != Actual) {
std::cout << "Result not matching the expected value at index " << I
<< ": " << Expected << " != " << Actual << std::endl;
++Failures;
}
}
delete[] HostData;
return Failures;
}

int main() {
sycl::context Ctx;
sycl::device Dev = Ctx.get_devices()[0];

sycl::queue Q1{Ctx, Dev, {sycl::property::queue::in_order{}}};
sycl::queue Q2{Ctx, Dev, {sycl::property::queue::in_order{}}};

int Failures = 0;

Failures += check_work(Q1, Q2);
Failures += check_wait(Q1, Q2);

return Failures;
}

0 comments on commit b0f584c

Please sign in to comment.