@@ -136,18 +136,19 @@ queue_impl::getExtendDependencyList(const std::vector<event> &DepEvents,
136
136
return DepEvents;
137
137
138
138
QueueLock.lock ();
139
- EventImplPtr ExtraEvent = MGraph.expired () ? MDefaultGraphDeps.LastEventPtr
140
- : MExtGraphDeps.LastEventPtr ;
141
139
std::optional<event> ExternalEvent = popExternalEvent ();
142
140
143
- if (!ExternalEvent && !ExtraEvent )
141
+ if (!ExternalEvent && !LastHostTaskEvent )
144
142
return DepEvents;
145
143
146
144
MutableVec = DepEvents;
147
145
if (ExternalEvent)
148
146
MutableVec.push_back (*ExternalEvent);
149
- if (ExtraEvent)
150
- MutableVec.push_back (detail::createSyclObjFromImpl<event>(ExtraEvent));
147
+ if (LastHostTaskEvent) {
148
+ MutableVec.push_back (
149
+ detail::createSyclObjFromImpl<event>(LastHostTaskEvent));
150
+ LastHostTaskEvent = nullptr ;
151
+ }
151
152
return MutableVec;
152
153
}
153
154
@@ -282,20 +283,21 @@ event queue_impl::memcpyFromDeviceGlobal(
282
283
DeviceGlobalPtr, IsDeviceImageScope, Self, NumBytes, Offset, Dest);
283
284
}
284
285
285
- sycl::detail::optional<event> queue_impl::getLastEvent () {
286
- // The external event is required to finish last if set, so it is considered
287
- // the last event if present.
286
+ sycl::detail::optional<event>
287
+ queue_impl::getLastEvent (const std::shared_ptr<queue_impl> &Self) {
288
288
if (std::optional<event> ExternalEvent = MInOrderExternalEvent.read ())
289
289
return ExternalEvent;
290
290
291
- std::lock_guard<std::mutex> Lock{MMutex};
292
- if (MGraph.expired () && !MDefaultGraphDeps.LastEventPtr )
291
+ if (MEmpty) {
293
292
return std::nullopt;
294
- if (MDiscardEvents)
295
- return createDiscardedEvent ();
296
- if (!MGraph.expired () && MExtGraphDeps.LastEventPtr )
297
- return detail::createSyclObjFromImpl<event>(MExtGraphDeps.LastEventPtr );
298
- return detail::createSyclObjFromImpl<event>(MDefaultGraphDeps.LastEventPtr );
293
+ }
294
+
295
+ if (LastHostTaskEvent) {
296
+ return detail::createSyclObjFromImpl<event>(LastHostTaskEvent);
297
+ }
298
+
299
+ // We insert a marker to represent an event at end.
300
+ return detail::createSyclObjFromImpl<event>(insertMarkerEvent (Self));
299
301
}
300
302
301
303
void queue_impl::addEvent (const event &Event) {
@@ -375,11 +377,11 @@ event queue_impl::submitWithHandler(const std::shared_ptr<queue_impl> &Self,
375
377
};
376
378
detail::type_erased_cgfo_ty CGF{L};
377
379
378
- if (!CallerNeedsEvent && supportsDiscardingPiEvents ()) {
379
- submit_without_event (CGF, Self, SI,
380
- /* CodeLoc*/ {}, /* IsTopCodeLoc*/ true );
381
- return createDiscardedEvent ();
382
- }
380
+ // if (!CallerNeedsEvent && supportsDiscardingPiEvents()) {
381
+ // submit_without_event(CGF, Self, SI,
382
+ // /*CodeLoc*/ {}, /*IsTopCodeLoc*/ true);
383
+ // return createDiscardedEvent();
384
+ // }
383
385
return submit_with_event (CGF, Self, SI,
384
386
/* CodeLoc*/ {}, /* IsTopCodeLoc*/ true );
385
387
}
@@ -396,6 +398,32 @@ event queue_impl::submitMemOpHelper(const std::shared_ptr<queue_impl> &Self,
396
398
{
397
399
std::unique_lock<std::mutex> Lock (MMutex, std::defer_lock);
398
400
401
+ if (isInOrder ()) {
402
+ Lock.lock ();
403
+ std::optional<event> ExternalEvent = popExternalEvent ();
404
+
405
+ if (LastHostTaskEvent) {
406
+ // TODO: this should be in finalize?
407
+ LastHostTaskEvent->wait (LastHostTaskEvent);
408
+ LastHostTaskEvent = nullptr ;
409
+ }
410
+
411
+ std::vector<event> WaitEvents;
412
+ if (ExternalEvent)
413
+ WaitEvents.emplace_back (std::move (*ExternalEvent));
414
+
415
+ event ResEvent = prepareSYCLEventAssociatedWithQueue (Self);
416
+ const auto &EventImpl = detail::getSyclObjImpl (ResEvent);
417
+ {
418
+ NestedCallsTracker tracker;
419
+ ur_event_handle_t UREvent = nullptr ;
420
+ MemOpFunc (MemOpArgs..., getUrEvents (WaitEvents), &UREvent, EventImpl);
421
+ EventImpl->setHandle (UREvent);
422
+ EventImpl->setEnqueued ();
423
+ }
424
+ return discard_or_return (ResEvent);
425
+ }
426
+
399
427
std::vector<event> MutableDepEvents;
400
428
const std::vector<event> &ExpandedDepEvents =
401
429
getExtendDependencyList (DepEvents, MutableDepEvents, Lock);
@@ -404,22 +432,22 @@ event queue_impl::submitMemOpHelper(const std::shared_ptr<queue_impl> &Self,
404
432
// handler rather than by-passing the scheduler.
405
433
if (MGraph.expired () && Scheduler::areEventsSafeForSchedulerBypass (
406
434
ExpandedDepEvents, MContext)) {
407
- if ((MDiscardEvents || !CallerNeedsEvent) &&
408
- supportsDiscardingPiEvents ()) {
409
- NestedCallsTracker tracker;
410
- MemOpFunc (MemOpArgs..., getUrEvents (ExpandedDepEvents),
411
- /* PiEvent*/ nullptr , /* EventImplPtr*/ nullptr );
412
-
413
- event DiscardedEvent = createDiscardedEvent ();
414
- if (isInOrder ()) {
415
- // Store the discarded event for proper in-order dependency tracking.
416
- auto &EventToStoreIn = MGraph.expired ()
417
- ? MDefaultGraphDeps.LastEventPtr
418
- : MExtGraphDeps.LastEventPtr ;
419
- EventToStoreIn = detail::getSyclObjImpl (DiscardedEvent);
420
- }
421
- return DiscardedEvent;
422
- }
435
+ // if ((MDiscardEvents || !CallerNeedsEvent) &&
436
+ // supportsDiscardingPiEvents()) {
437
+ // NestedCallsTracker tracker;
438
+ // MemOpFunc(MemOpArgs..., getUrEvents(ExpandedDepEvents),
439
+ // /*PiEvent*/ nullptr, /*EventImplPtr*/ nullptr);
440
+
441
+ // event DiscardedEvent = createDiscardedEvent();
442
+ // if (isInOrder()) {
443
+ // // Store the discarded event for proper in-order dependency
444
+ // tracking. auto &EventToStoreIn = MGraph.expired()
445
+ // ? MDefaultGraphDeps.LastEventPtr
446
+ // : MExtGraphDeps.LastEventPtr;
447
+ // EventToStoreIn = detail::getSyclObjImpl(DiscardedEvent);
448
+ // }
449
+ // return DiscardedEvent;
450
+ // }
423
451
424
452
event ResEvent = prepareSYCLEventAssociatedWithQueue (Self);
425
453
const auto &EventImpl = detail::getSyclObjImpl (ResEvent);
@@ -443,12 +471,6 @@ event queue_impl::submitMemOpHelper(const std::shared_ptr<queue_impl> &Self,
443
471
}
444
472
}
445
473
446
- if (isInOrder ()) {
447
- auto &EventToStoreIn = MGraph.expired () ? MDefaultGraphDeps.LastEventPtr
448
- : MExtGraphDeps.LastEventPtr ;
449
- EventToStoreIn = EventImpl;
450
- }
451
-
452
474
return discard_or_return (ResEvent);
453
475
}
454
476
}
@@ -569,6 +591,11 @@ void queue_impl::wait(const detail::code_location &CodeLoc) {
569
591
std::vector<std::weak_ptr<event_impl>> WeakEvents;
570
592
{
571
593
std::lock_guard<std::mutex> Lock (MMutex);
594
+ if (LastHostTaskEvent) {
595
+ LastHostTaskEvent->wait (LastHostTaskEvent);
596
+ LastHostTaskEvent = nullptr ;
597
+ }
598
+
572
599
WeakEvents.swap (MEventsWeak);
573
600
574
601
MMissedCleanupRequests.unset (
@@ -684,23 +711,6 @@ ur_native_handle_t queue_impl::getNative(int32_t &NativeHandleDesc) const {
684
711
}
685
712
686
713
bool queue_impl::ext_oneapi_empty () const {
687
- // If we have in-order queue where events are not discarded then just check
688
- // the status of the last event.
689
- if (isInOrder () && !MDiscardEvents) {
690
- std::lock_guard<std::mutex> Lock (MMutex);
691
- // If there is no last event we know that no work has been submitted, so it
692
- // must be trivially empty.
693
- if (!MDefaultGraphDeps.LastEventPtr )
694
- return true ;
695
- // Otherwise, check if the last event is finished.
696
- // Note that we fall back to the backend query if the event was discarded,
697
- // which may happend despite the queue not being a discard event queue.
698
- if (!MDefaultGraphDeps.LastEventPtr ->isDiscarded ())
699
- return MDefaultGraphDeps.LastEventPtr
700
- ->get_info <info::event::command_execution_status>() ==
701
- info::event_command_status::complete;
702
- }
703
-
704
714
// Check the status of the backend queue if this is not a host queue.
705
715
ur_bool_t IsReady = false ;
706
716
getAdapter ()->call <UrApiKind::urQueueGetInfo>(
0 commit comments