Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions sycl/include/sycl/event.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,10 @@ class __SYCL_EXPORT event : public detail::OwnerLessBase<event> {
/// enabled.
bool ext_oneapi_ipc_enabled() const noexcept;

/// Returns true if the event is reusable (can be enqueued for signaling
/// multiple times).
bool ext_oneapi_reusable() const noexcept;

private:
event(std::shared_ptr<detail::event_impl> EventImpl);

Expand Down
5 changes: 5 additions & 0 deletions sycl/source/detail/event_deps.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,11 @@ void registerEventDependency(
"Queue operation cannot depend on discarded event.");
}

if (EventImpl->isReusable()) {
throw sycl::exception(make_error_code(errc::invalid),
"Reusable events cannot be used as a dependency.");
}

// Async alloc calls adapter immediately. Any explicit/implicit dependencies
// are handled at that point, including in order queue deps. Further calls to
// depends_on after an async alloc are explicitly disallowed.
Expand Down
8 changes: 7 additions & 1 deletion sycl/source/detail/event_impl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ class event_impl {
/// If the constructed SYCL event is waited on it will complete immediately.
event_impl(private_tag)
: MIsFlushed(true), MState(HES_Complete), MIsDefaultConstructed(true),
MIsHostEvent(false) {
MIsHostEvent(false), MReusable(true) {
// Need to fail in event() constructor if there are problems with the
// ONEAPI_DEVICE_SELECTOR. Deferring may lead to conficts with noexcept
// event methods. This ::get() call uses static vars to read and parse the
Expand Down Expand Up @@ -399,6 +399,8 @@ class event_impl {
// Initializes the host profiling info for the event.
void initHostProfilingInfo();

bool isReusable() const noexcept { return MReusable; }

protected:
// When instrumentation is enabled emits trace event for event wait begin and
// returns the telemetry event generated for the wait
Expand Down Expand Up @@ -505,6 +507,10 @@ class event_impl {
// MEvent is lazily created in first ur handle query.
bool MIsDefaultConstructed = false;
bool MIsHostEvent = false;

/// True if the event is reusable (can be enqueued for signaling multiple
/// times).
bool MReusable = false;
};

using events_iterator =
Expand Down
15 changes: 11 additions & 4 deletions sycl/source/detail/queue_impl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -615,14 +615,21 @@ EventImplPtr queue_impl::submit_barrier_direct_impl(
/*SchedulerBypass*/ true};
}

if (EventForReuse) {
if (EventForReuse || !CallerNeedsEvent) {
// Current limitation: reusable events require scheduler bypass so that
// the barrier can be submitted directly to the backend with the reusable
// event's handle as the output event. Scheduler bypass is not possible
// when dependencies include host tasks or cross-context dependencies.
throw sycl::exception(sycl::make_error_code(errc::invalid),
"An event cannot be enqueued for signaling behind "
"a command which is not enqueued in the backend.");
//
// This limitation applies to both: enqueue_signal_event and
// enqueue_wait_event(s).
//
// The !CallerNeedsEvent condition is used to detect the
// enqueue_wait_event(s) function calls.
throw sycl::exception(
sycl::make_error_code(errc::invalid),
"An event cannot be enqueued for signaling or waiting "
"behind a command which is not enqueued in the backend.");
}

std::unique_ptr<detail::CG> CommandGroup;
Expand Down
2 changes: 2 additions & 0 deletions sycl/source/event.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,8 @@ bool event::ext_oneapi_ipc_enabled() const noexcept {
return impl->isIPCEnabled();
}

bool event::ext_oneapi_reusable() const noexcept { return impl->isReusable(); }

ur_native_handle_t event::getNative() const { return impl->getNative(); }

std::vector<ur_native_handle_t> event::getNativeVector() const {
Expand Down
7 changes: 7 additions & 0 deletions sycl/source/handler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -938,6 +938,13 @@ void handler::ext_oneapi_barrier(const std::vector<event> &WaitList) {
impl->MEventsWaitWithBarrier.reserve(WaitList.size());
for (auto &Event : WaitList) {
auto EventImpl = detail::getSyclObjImpl(Event);

if (EventImpl->isReusable()) {
throw sycl::exception(
make_error_code(errc::invalid),
"Reusable events cannot be used as barrier events.");
}

// We could not wait for host task events in backend.
// Adding them as dependency to enable proper scheduling.
if (EventImpl->isHost()) {
Expand Down
7 changes: 7 additions & 0 deletions sycl/source/queue.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,13 @@ event queue::ext_oneapi_submit_barrier(const detail::code_location &CodeLoc) {
/// group is being enqueued on.
event queue::ext_oneapi_submit_barrier(const std::vector<event> &WaitList,
const detail::code_location &CodeLoc) {
for (const event &e : WaitList) {
if (e.ext_oneapi_reusable()) {
throw sycl::exception(
make_error_code(errc::invalid),
"Reusable events cannot be used as barrier events.");
}
}
return impl->submit_barrier_direct_with_event(
WaitList, detail::CGType::BarrierWaitlist, CodeLoc);
}
Expand Down
44 changes: 44 additions & 0 deletions sycl/source/reusable_events.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,21 @@ __SYCL_EXPORT sycl::event make_event(const sycl::context &ctxt,

__SYCL_EXPORT void enqueue_wait_event(sycl::queue q, const event &evt) {
detail::queue_impl &QueueImpl = *sycl::detail::getSyclObjImpl(q);
detail::event_impl &EventImpl = *sycl::detail::getSyclObjImpl(evt);

// Only reusable events are supported.
if (!EventImpl.isReusable()) {
throw sycl::exception(sycl::make_error_code(errc::invalid),
"Event must be reusable.");
}

// The queue and an event need to be in the same context. The reason
// is, that cross-context dependencies use host tasks, and the wait
// command might be queued in the runtime.
if (&QueueImpl.getContextImpl() != &EventImpl.getContextImpl()) {
throw sycl::exception(sycl::make_error_code(errc::invalid),
"Event context must match the queue context.");
}

QueueImpl.submit_barrier_direct_without_event(
sycl::span<const event>(&evt, 1), detail::CGType::BarrierWaitlist,
Expand All @@ -70,6 +85,28 @@ __SYCL_EXPORT void enqueue_wait_events(sycl::queue q,
const std::vector<event> &evts) {
detail::queue_impl &QueueImpl = *sycl::detail::getSyclObjImpl(q);

// For reusable events, the queue and all the events need to be in
// the same context. The reason is, that cross-context dependencies
// use host tasks, and the wait command might be queued in the runtime.
// This would prevent the runtime from capturing the dependency
// at the point in time where this function is called (might delay
// the dependency capture).
//
// All the events need to be reusable.
for (const sycl::event &evt : evts) {
detail::event_impl &EventImpl = *sycl::detail::getSyclObjImpl(evt);
if (!EventImpl.isReusable()) {
throw sycl::exception(sycl::make_error_code(errc::invalid),
"All events must be reusable.");
}

if (&QueueImpl.getContextImpl() != &EventImpl.getContextImpl()) {
throw sycl::exception(
sycl::make_error_code(errc::invalid),
"Context of all events must match the queue context.");
}
}

QueueImpl.submit_barrier_direct_without_event(
evts, detail::CGType::BarrierWaitlist, detail::code_location::current());
}
Expand All @@ -78,6 +115,13 @@ __SYCL_EXPORT void enqueue_signal_event(sycl::queue q, event &evt) {
detail::queue_impl &QueueImpl = *sycl::detail::getSyclObjImpl(q);
detail::event_impl &EventImpl = *sycl::detail::getSyclObjImpl(evt);

// Only reusable events can be enqueued for signaling.
if (!EventImpl.isReusable()) {
throw sycl::exception(
sycl::make_error_code(errc::invalid),
"Only a reusable event can be enqueued for signaling.");
}

if (EventImpl.isInterop()) {
throw sycl::exception(
sycl::make_error_code(errc::runtime),
Expand Down
1 change: 1 addition & 0 deletions sycl/test/abi/sycl_symbols_linux.dump
Original file line number Diff line number Diff line change
Expand Up @@ -3703,6 +3703,7 @@ _ZNK4sycl3_V15event15getNativeVectorEv
_ZNK4sycl3_V15event18get_profiling_infoINS0_4info15event_profiling11command_endEEENS0_6detail28is_event_profiling_info_descIT_E11return_typeEv
_ZNK4sycl3_V15event18get_profiling_infoINS0_4info15event_profiling13command_startEEENS0_6detail28is_event_profiling_info_descIT_E11return_typeEv
_ZNK4sycl3_V15event18get_profiling_infoINS0_4info15event_profiling14command_submitEEENS0_6detail28is_event_profiling_info_descIT_E11return_typeEv
_ZNK4sycl3_V15event19ext_oneapi_reusableEv
_ZNK4sycl3_V15event22ext_oneapi_ipc_enabledEv
_ZNK4sycl3_V15event8get_infoINS0_4info5event15reference_countEEENS0_6detail18is_event_info_descIT_E11return_typeEv
_ZNK4sycl3_V15event8get_infoINS0_4info5event24command_execution_statusEEENS0_6detail18is_event_info_descIT_E11return_typeEv
Expand Down
1 change: 1 addition & 0 deletions sycl/test/abi/sycl_symbols_windows.dump
Original file line number Diff line number Diff line change
Expand Up @@ -3933,6 +3933,7 @@
?ext_oneapi_owner_before@device@_V1@sycl@@QEBA_NAEBV123@@Z
?ext_oneapi_owner_before@device@_V1@sycl@@QEBA_NAEBV?$weak_object@Vdevice@_V1@sycl@@@oneapi@ext@23@@Z
?ext_oneapi_prod@queue@_V1@sycl@@QEAAXXZ
?ext_oneapi_reusable@event@_V1@sycl@@QEBA_NXZ
?ext_oneapi_set_external_event@queue@_V1@sycl@@QEAAXAEBVevent@23@@Z
?ext_oneapi_signal_external_semaphore@handler@_V1@sycl@@QEAAXUexternal_semaphore@experimental@oneapi@ext@23@@Z
?ext_oneapi_signal_external_semaphore@handler@_V1@sycl@@QEAAXUexternal_semaphore@experimental@oneapi@ext@23@_K@Z
Expand Down
1 change: 0 additions & 1 deletion sycl/unittests/Extensions/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ add_sycl_unittest(ExtensionsTests OBJECT
OneAPIProd.cpp
EnqueueFunctionsEvents.cpp
EnqueueFunctionsPrefetch.cpp
ExtOneapiBarrierOpt.cpp
ProfilingTag.cpp
KernelProperties.cpp
NoDeviceIPVersion.cpp
Expand Down
58 changes: 0 additions & 58 deletions sycl/unittests/Extensions/ExtOneapiBarrierOpt.cpp

This file was deleted.

Loading
Loading