Skip to content

Commit

Permalink
[SYCL] Fix handling of interop events for barrier with wailist
Browse files Browse the repository at this point in the history
  • Loading branch information
againull committed Sep 10, 2024
1 parent 37d1d51 commit 809762e
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 3 deletions.
7 changes: 7 additions & 0 deletions sycl/source/detail/event_impl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,13 @@ class event_impl {

bool isProfilingTagEvent() const noexcept { return MProfilingTagEvent; }

// Check if this event is an interoperability event.
bool isInterop() const noexcept {
// We assume that if this event is interop then it must not have a command
// and therefore must not be enqueued.
return MEvent && MQueue.expired() && !MIsEnqueued && !MCommand;
}

protected:
// When instrumentation is enabled emits trace event for event wait begin and
// returns the telemetry event generated for the wait
Expand Down
9 changes: 6 additions & 3 deletions sycl/source/detail/scheduler/commands.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -265,9 +265,12 @@ std::vector<ur_event_handle_t> Command::getUrEventsBlocking(
if (EventImpl->isDefaultConstructed() || EventImpl->isHost() ||
EventImpl->isNOP())
continue;
// In this path nullptr native event means that the command has not been
// enqueued. It may happen if async enqueue in a host task is involved.
if (!EventImpl->isEnqueued()) {

// If command has not been enqueued then we have to enqueue it.
// It may happen if async enqueue in a host task is involved.
// Interoperability events are special case and they are not enqueued, as
// they don't have associated queue and command.
if (!EventImpl->isInterop() && !EventImpl->isEnqueued()) {
if (!EventImpl->getCommand() ||
!static_cast<Command *>(EventImpl->getCommand())->producesPiEvent())
continue;
Expand Down
44 changes: 44 additions & 0 deletions sycl/test-e2e/Regression/barrier_waitlist_with_interop_event.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// REQUIRES: level_zero, level_zero_dev_kit
// RUN: %{build} %level_zero_options -o %t.out
// RUN: %{run} %t.out
// UNSUPPORTED: ze_debug

#include <level_zero/ze_api.h>
#include <sycl/detail/core.hpp>
#include <sycl/ext/oneapi/backend/level_zero.hpp>
#include <sycl/usm.hpp>

// Test checks the case when an interoperability event is passed as a dependency
// to the barrier. In such case waiting for the even produced by barrier must
// guarantee completion of the interoperability event.

using namespace sycl;

int main() {
sycl::queue Queue;
const size_t N = 1024;
int *Data = sycl::malloc_shared<int>(N, Queue);
auto FillEvent = Queue.fill(Data, 0, N);
auto FillZeEvent = get_native<backend::ext_oneapi_level_zero>(FillEvent);

backend_input_t<backend::ext_oneapi_level_zero, event> EventInteropInput = {
FillZeEvent};
EventInteropInput.Ownership = sycl::ext::oneapi::level_zero::ownership::keep;
auto EventInterop = make_event<backend::ext_oneapi_level_zero>(
EventInteropInput, Queue.get_context());

auto BarrierEvent = Queue.ext_oneapi_submit_barrier({EventInterop});
BarrierEvent.wait();

if (EventInterop.get_info<sycl::info::event::command_execution_status>() !=
sycl::info::event_command_status::complete) {
Queue.wait();
sycl::free(Data, Queue);
return -1;
}

// Free the USM memory
sycl::free(Data, Queue);

return 0;
}

0 comments on commit 809762e

Please sign in to comment.