diff --git a/sycl/source/detail/event_impl.cpp b/sycl/source/detail/event_impl.cpp index 080d8f7d45990..2719d92b97e22 100644 --- a/sycl/source/detail/event_impl.cpp +++ b/sycl/source/detail/event_impl.cpp @@ -37,15 +37,17 @@ void event_impl::ensureContextInitialized() { if (MIsContextInitialized) return; - const device &SyclDevice = default_selector().select_device(); - this->setContextImpl( - detail::queue_impl::getDefaultOrNew(detail::getSyclObjImpl(SyclDevice))); + if (MHostEvent) { + QueueImplPtr HostQueue = Scheduler::getInstance().getDefaultHostQueue(); + this->setContextImpl(detail::getSyclObjImpl(HostQueue->get_context())); + } else { + const device &SyclDevice = default_selector().select_device(); + this->setContextImpl(detail::queue_impl::getDefaultOrNew( + detail::getSyclObjImpl(SyclDevice))); + } } bool event_impl::is_host() { - // We'll need a context before we can answer is_host question. - // setting it may adjust the values of MHostEvent and MOpenCLInterop - ensureContextInitialized(); // Treat all devices that don't support interoperability as host devices to // avoid attempts to call method get on such events. return MHostEvent || !MOpenCLInterop; @@ -126,8 +128,9 @@ void event_impl::setContextImpl(const ContextImplPtr &Context) { MIsContextInitialized = true; } -event_impl::event_impl(HostEventState State) - : MIsInitialized(false), MIsFlushed(true), MState(State) {} +event_impl::event_impl(std::optional State) + : MIsInitialized(false), MHostEvent(State), MIsFlushed(true), + MState(State.value_or(HES_Complete)) {} event_impl::event_impl(RT::PiEvent Event, const context &SyclContext) : MIsContextInitialized(true), MEvent(Event), diff --git a/sycl/source/detail/event_impl.hpp b/sycl/source/detail/event_impl.hpp index 364266cd8f210..f9ea6167943ba 100644 --- a/sycl/source/detail/event_impl.hpp +++ b/sycl/source/detail/event_impl.hpp @@ -43,7 +43,10 @@ class event_impl { /// Constructs a ready SYCL event. /// /// If the constructed SYCL event is waited on it will complete immediately. - event_impl(HostEventState State = HES_Complete); + /// Normally constructs a host event, use std::nullopt to instead instantiate + /// a device event. + event_impl(std::optional State = HES_Complete); + /// Constructs an event instance from a plug-in event handle. /// /// The SyclContext must match the plug-in context associated with the diff --git a/sycl/source/detail/helpers.cpp b/sycl/source/detail/helpers.cpp index c5d3be5fe29cd..5ef25d598bf18 100644 --- a/sycl/source/detail/helpers.cpp +++ b/sycl/source/detail/helpers.cpp @@ -23,10 +23,11 @@ std::vector getOrWaitEvents(std::vector DepEvents, std::vector Events; for (auto SyclEvent : DepEvents) { auto SyclEventImplPtr = detail::getSyclObjImpl(SyclEvent); - // throwaway events created with default constructor will not have a context - // (which is set lazily) calling is_host(), getContextImpl() would set that + // throwaway events created with empty constructor will not have a context + // (which is set lazily) calling getContextImpl() would set that // context, which we wish to avoid as it is expensive. - if (SyclEventImplPtr->MIsContextInitialized == false) { + if (SyclEventImplPtr->MIsContextInitialized == false && + !SyclEventImplPtr->is_host()) { continue; } if (SyclEventImplPtr->is_host() || diff --git a/sycl/source/event.cpp b/sycl/source/event.cpp index c7cb912a1cd66..3c64aed678bac 100644 --- a/sycl/source/event.cpp +++ b/sycl/source/event.cpp @@ -22,7 +22,7 @@ __SYCL_INLINE_NAMESPACE(cl) { namespace sycl { -event::event() : impl(std::make_shared()) {} +event::event() : impl(std::make_shared(std::nullopt)) {} event::event(cl_event ClEvent, const context &SyclContext) : impl(std::make_shared(