@@ -137,18 +137,19 @@ queue_impl::getExtendDependencyList(const std::vector<event> &DepEvents,
137
137
return DepEvents;
138
138
139
139
QueueLock.lock ();
140
- EventImplPtr ExtraEvent = MGraph.expired () ? MDefaultGraphDeps.LastEventPtr
141
- : MExtGraphDeps.LastEventPtr ;
142
140
std::optional<event> ExternalEvent = popExternalEvent ();
143
141
144
- if (!ExternalEvent && !ExtraEvent )
142
+ if (!ExternalEvent && !LastHostTaskEvent )
145
143
return DepEvents;
146
144
147
145
MutableVec = DepEvents;
148
146
if (ExternalEvent)
149
147
MutableVec.push_back (*ExternalEvent);
150
- if (ExtraEvent)
151
- MutableVec.push_back (detail::createSyclObjFromImpl<event>(ExtraEvent));
148
+ if (LastHostTaskEvent) {
149
+ MutableVec.push_back (
150
+ detail::createSyclObjFromImpl<event>(LastHostTaskEvent));
151
+ LastHostTaskEvent = nullptr ;
152
+ }
152
153
return MutableVec;
153
154
}
154
155
@@ -283,20 +284,21 @@ event queue_impl::memcpyFromDeviceGlobal(
283
284
DeviceGlobalPtr, IsDeviceImageScope, Self, NumBytes, Offset, Dest);
284
285
}
285
286
286
- sycl::detail::optional<event> queue_impl::getLastEvent () {
287
- // The external event is required to finish last if set, so it is considered
288
- // the last event if present.
287
+ sycl::detail::optional<event>
288
+ queue_impl::getLastEvent (const std::shared_ptr<queue_impl> &Self) {
289
289
if (std::optional<event> ExternalEvent = MInOrderExternalEvent.read ())
290
290
return ExternalEvent;
291
291
292
- std::lock_guard<std::mutex> Lock{MMutex};
293
- if (MGraph.expired () && !MDefaultGraphDeps.LastEventPtr )
292
+ if (MEmpty) {
294
293
return std::nullopt;
295
- if (MDiscardEvents)
296
- return createDiscardedEvent ();
297
- if (!MGraph.expired () && MExtGraphDeps.LastEventPtr )
298
- return detail::createSyclObjFromImpl<event>(MExtGraphDeps.LastEventPtr );
299
- return detail::createSyclObjFromImpl<event>(MDefaultGraphDeps.LastEventPtr );
294
+ }
295
+
296
+ if (LastHostTaskEvent) {
297
+ return detail::createSyclObjFromImpl<event>(LastHostTaskEvent);
298
+ }
299
+
300
+ // We insert a marker to represent an event at end.
301
+ return detail::createSyclObjFromImpl<event>(insertMarkerEvent (Self));
300
302
}
301
303
302
304
void queue_impl::addEvent (const event &Event) {
@@ -414,11 +416,11 @@ event queue_impl::submitWithHandler(const std::shared_ptr<queue_impl> &Self,
414
416
};
415
417
detail::type_erased_cgfo_ty CGF{L};
416
418
417
- if (!CallerNeedsEvent && supportsDiscardingPiEvents ()) {
418
- submit_without_event (CGF, Self, SI,
419
- /* CodeLoc*/ {}, /* IsTopCodeLoc*/ true );
420
- return createDiscardedEvent ();
421
- }
419
+ // if (!CallerNeedsEvent && supportsDiscardingPiEvents()) {
420
+ // submit_without_event(CGF, Self, SI,
421
+ // /*CodeLoc*/ {}, /*IsTopCodeLoc*/ true);
422
+ // return createDiscardedEvent();
423
+ // }
422
424
return submit_with_event (CGF, Self, SI,
423
425
/* CodeLoc*/ {}, /* IsTopCodeLoc*/ true );
424
426
}
@@ -435,6 +437,32 @@ event queue_impl::submitMemOpHelper(const std::shared_ptr<queue_impl> &Self,
435
437
{
436
438
std::unique_lock<std::mutex> Lock (MMutex, std::defer_lock);
437
439
440
+ if (isInOrder ()) {
441
+ Lock.lock ();
442
+ std::optional<event> ExternalEvent = popExternalEvent ();
443
+
444
+ if (LastHostTaskEvent) {
445
+ // TODO: this should be in finalize?
446
+ LastHostTaskEvent->wait (LastHostTaskEvent);
447
+ LastHostTaskEvent = nullptr ;
448
+ }
449
+
450
+ std::vector<event> WaitEvents;
451
+ if (ExternalEvent)
452
+ WaitEvents.emplace_back (std::move (*ExternalEvent));
453
+
454
+ event ResEvent = prepareSYCLEventAssociatedWithQueue (Self);
455
+ const auto &EventImpl = detail::getSyclObjImpl (ResEvent);
456
+ {
457
+ NestedCallsTracker tracker;
458
+ ur_event_handle_t UREvent = nullptr ;
459
+ MemOpFunc (MemOpArgs..., getUrEvents (WaitEvents), &UREvent, EventImpl);
460
+ EventImpl->setHandle (UREvent);
461
+ EventImpl->setEnqueued ();
462
+ }
463
+ return discard_or_return (ResEvent);
464
+ }
465
+
438
466
std::vector<event> MutableDepEvents;
439
467
const std::vector<event> &ExpandedDepEvents =
440
468
getExtendDependencyList (DepEvents, MutableDepEvents, Lock);
@@ -443,22 +471,22 @@ event queue_impl::submitMemOpHelper(const std::shared_ptr<queue_impl> &Self,
443
471
// handler rather than by-passing the scheduler.
444
472
if (MGraph.expired () && Scheduler::areEventsSafeForSchedulerBypass (
445
473
ExpandedDepEvents, MContext)) {
446
- if ((MDiscardEvents || !CallerNeedsEvent) &&
447
- supportsDiscardingPiEvents ()) {
448
- NestedCallsTracker tracker;
449
- MemOpFunc (MemOpArgs..., getUrEvents (ExpandedDepEvents),
450
- /* PiEvent*/ nullptr , /* EventImplPtr*/ nullptr );
451
-
452
- event DiscardedEvent = createDiscardedEvent ();
453
- if (isInOrder ()) {
454
- // Store the discarded event for proper in-order dependency tracking.
455
- auto &EventToStoreIn = MGraph.expired ()
456
- ? MDefaultGraphDeps.LastEventPtr
457
- : MExtGraphDeps.LastEventPtr ;
458
- EventToStoreIn = detail::getSyclObjImpl (DiscardedEvent);
459
- }
460
- return DiscardedEvent;
461
- }
474
+ // if ((MDiscardEvents || !CallerNeedsEvent) &&
475
+ // supportsDiscardingPiEvents()) {
476
+ // NestedCallsTracker tracker;
477
+ // MemOpFunc(MemOpArgs..., getUrEvents(ExpandedDepEvents),
478
+ // /*PiEvent*/ nullptr, /*EventImplPtr*/ nullptr);
479
+
480
+ // event DiscardedEvent = createDiscardedEvent();
481
+ // if (isInOrder()) {
482
+ // // Store the discarded event for proper in-order dependency
483
+ // tracking. auto &EventToStoreIn = MGraph.expired()
484
+ // ? MDefaultGraphDeps.LastEventPtr
485
+ // : MExtGraphDeps.LastEventPtr;
486
+ // EventToStoreIn = detail::getSyclObjImpl(DiscardedEvent);
487
+ // }
488
+ // return DiscardedEvent;
489
+ // }
462
490
463
491
event ResEvent = prepareSYCLEventAssociatedWithQueue (Self);
464
492
const auto &EventImpl = detail::getSyclObjImpl (ResEvent);
@@ -482,11 +510,6 @@ event queue_impl::submitMemOpHelper(const std::shared_ptr<queue_impl> &Self,
482
510
}
483
511
}
484
512
485
- if (isInOrder ()) {
486
- auto &EventToStoreIn = MGraph.expired () ? MDefaultGraphDeps.LastEventPtr
487
- : MExtGraphDeps.LastEventPtr ;
488
- EventToStoreIn = EventImpl;
489
- }
490
513
// Track only if we won't be able to handle it with urQueueFinish.
491
514
if (MEmulateOOO)
492
515
addSharedEvent (ResEvent);
@@ -612,6 +635,11 @@ void queue_impl::wait(const detail::code_location &CodeLoc) {
612
635
std::vector<event> SharedEvents;
613
636
{
614
637
std::lock_guard<std::mutex> Lock (MMutex);
638
+ if (LastHostTaskEvent) {
639
+ LastHostTaskEvent->wait (LastHostTaskEvent);
640
+ LastHostTaskEvent = nullptr ;
641
+ }
642
+
615
643
WeakEvents.swap (MEventsWeak);
616
644
SharedEvents.swap (MEventsShared);
617
645
@@ -736,23 +764,6 @@ ur_native_handle_t queue_impl::getNative(int32_t &NativeHandleDesc) const {
736
764
}
737
765
738
766
bool queue_impl::ext_oneapi_empty () const {
739
- // If we have in-order queue where events are not discarded then just check
740
- // the status of the last event.
741
- if (isInOrder () && !MDiscardEvents) {
742
- std::lock_guard<std::mutex> Lock (MMutex);
743
- // If there is no last event we know that no work has been submitted, so it
744
- // must be trivially empty.
745
- if (!MDefaultGraphDeps.LastEventPtr )
746
- return true ;
747
- // Otherwise, check if the last event is finished.
748
- // Note that we fall back to the backend query if the event was discarded,
749
- // which may happend despite the queue not being a discard event queue.
750
- if (!MDefaultGraphDeps.LastEventPtr ->isDiscarded ())
751
- return MDefaultGraphDeps.LastEventPtr
752
- ->get_info <info::event::command_execution_status>() ==
753
- info::event_command_status::complete;
754
- }
755
-
756
767
// Check the status of the backend queue if this is not a host queue.
757
768
ur_bool_t IsReady = false ;
758
769
getAdapter ()->call <UrApiKind::urQueueGetInfo>(
0 commit comments