@@ -478,10 +478,18 @@ _pi_context::getFreeSlotInExistingOrNewPool(ze_event_pool_handle_t &Pool,
478
478
std::list<ze_event_pool_handle_t > *ZePoolCache =
479
479
getZeEventPoolCache (HostVisible, ProfilingEnabled);
480
480
481
- // Remove full pool from the cache.
482
481
if (!ZePoolCache->empty ()) {
483
482
if (NumEventsAvailableInEventPool[ZePoolCache->front ()] == 0 ) {
484
- ZePoolCache->erase (ZePoolCache->begin ());
483
+ if (DisableEventsCaching) {
484
+ // Remove full pool from the cache if events caching is disabled.
485
+ ZePoolCache->erase (ZePoolCache->begin ());
486
+ } else {
487
+ // If event caching is enabled then we don't destroy events so there is
488
+ // no need to remove pool from the cache and add it back when it has
489
+ // available slots. Just keep it in the tail of the cache so that all
490
+ // pools can be destroyed during context destruction.
491
+ ZePoolCache->push_front (nullptr );
492
+ }
485
493
}
486
494
}
487
495
if (ZePoolCache->empty ()) {
@@ -878,16 +886,18 @@ pi_result _pi_context::initialize() {
878
886
pi_result _pi_context::finalize () {
879
887
// This function is called when pi_context is deallocated, piContextRelease.
880
888
// There could be some memory that may have not been deallocated.
881
- // For example, event pool caches would be still alive.
882
- {
883
- std::scoped_lock Lock (ZeEventCacheMutex);
884
- for (auto &ZeEventCache : ZeEventCaches) {
885
- for (auto &ZeEventAndPool : ZeEventCache)
886
- ZE_CALL (zeEventDestroy, (ZeEventAndPool.first ));
887
- ZeEventCache.clear ();
889
+ // For example, event and event pool caches would be still alive.
890
+
891
+ if (!DisableEventsCaching) {
892
+ std::scoped_lock Lock (EventCacheMutex);
893
+ for (auto &EventCache : EventCaches) {
894
+ for (auto Event : EventCache) {
895
+ ZE_CALL (zeEventDestroy, (Event->ZeEvent ));
896
+ delete Event;
897
+ }
898
+ EventCache.clear ();
888
899
}
889
900
}
890
-
891
901
{
892
902
std::scoped_lock Lock (ZeEventPoolCacheMutex);
893
903
for (auto &ZePoolCache : ZeEventPoolCache) {
@@ -5449,26 +5459,40 @@ _pi_event::getOrCreateHostVisibleEvent(ze_event_handle_t &ZeHostVisibleEvent) {
5449
5459
return PI_SUCCESS;
5450
5460
}
5451
5461
5452
- std::pair<ze_event_handle_t , ze_event_pool_handle_t >
5453
- _pi_context::getZeEventFromCache (bool HostVisible, bool WithProfiling) {
5454
- std::scoped_lock Lock (ZeEventCacheMutex);
5455
- auto Cache = getZeEventCache (HostVisible, WithProfiling);
5462
+ pi_result _pi_event::reset () {
5463
+ Queue = nullptr ;
5464
+ CleanedUp = false ;
5465
+ Completed = false ;
5466
+ CommandData = nullptr ;
5467
+ CommandType = PI_COMMAND_TYPE_USER;
5468
+ WaitList = {};
5469
+ RefCount.reset (1 );
5470
+
5471
+ if (!isHostVisible ())
5472
+ HostVisibleEvent = nullptr ;
5473
+
5474
+ ZE_CALL (zeEventHostReset, (ZeEvent));
5475
+ return PI_SUCCESS;
5476
+ }
5477
+
5478
+ pi_event _pi_context::getEventFromCache (bool HostVisible, bool WithProfiling) {
5479
+ std::scoped_lock Lock (EventCacheMutex);
5480
+ auto Cache = getEventCache (HostVisible, WithProfiling);
5456
5481
if (Cache->empty ())
5457
- return std::make_pair<ze_event_handle_t , ze_event_pool_handle_t >(nullptr ,
5458
- nullptr );
5482
+ return nullptr ;
5459
5483
5460
5484
auto It = Cache->begin ();
5461
- std::pair< ze_event_handle_t , ze_event_pool_handle_t > ZeEvent = *It;
5485
+ pi_event Event = *It;
5462
5486
Cache->erase (It);
5463
- return ZeEvent ;
5487
+ return Event ;
5464
5488
}
5465
5489
5466
- void _pi_context::addZeEventToCache ( ze_event_handle_t ZeEvent,
5467
- ze_event_pool_handle_t ZePool,
5468
- bool HostVisible, bool WithProfiling) {
5469
- std::scoped_lock Lock (ZeEventCacheMutex );
5470
- auto Cache = getZeEventCache (HostVisible, WithProfiling );
5471
- Cache->emplace_back (ZeEvent, ZePool );
5490
+ void _pi_context::addEventToCache (pi_event Event) {
5491
+ std::scoped_lock Lock (EventCacheMutex);
5492
+ auto Cache =
5493
+ getEventCache (Event-> isHostVisible (), Event-> isProfilingEnabled () );
5494
+ Event-> reset ( );
5495
+ Cache->emplace_back (Event );
5472
5496
}
5473
5497
5474
5498
// Helper function for creating a PI event.
@@ -5481,43 +5505,41 @@ static pi_result EventCreate(pi_context Context, pi_queue Queue,
5481
5505
bool ProfilingEnabled =
5482
5506
!Queue || (Queue->Properties & PI_QUEUE_PROFILING_ENABLE) != 0 ;
5483
5507
5484
- auto CachedEvent =
5485
- Context->getZeEventFromCache (HostVisible, ProfilingEnabled);
5508
+ if (auto CachedEvent =
5509
+ Context->getEventFromCache (HostVisible, ProfilingEnabled)) {
5510
+ *RetEvent = CachedEvent;
5511
+ return PI_SUCCESS;
5512
+ }
5513
+
5486
5514
ze_event_handle_t ZeEvent;
5487
5515
ze_event_pool_handle_t ZeEventPool = {};
5488
5516
5489
- // If no any then check cache of event in the context
5490
- if (CachedEvent.first ) {
5491
- ZeEvent = CachedEvent.first ;
5492
- ZeEventPool = CachedEvent.second ;
5493
- } else {
5494
- size_t Index = 0 ;
5495
-
5496
- if (auto Res = Context->getFreeSlotInExistingOrNewPool (
5497
- ZeEventPool, Index, HostVisible, ProfilingEnabled))
5498
- return Res;
5517
+ size_t Index = 0 ;
5499
5518
5500
- ZeStruct< ze_event_desc_t > ZeEventDesc;
5501
- ZeEventDesc. index = Index;
5502
- ZeEventDesc. wait = 0 ;
5519
+ if ( auto Res = Context-> getFreeSlotInExistingOrNewPool (
5520
+ ZeEventPool, Index, HostVisible, ProfilingEnabled))
5521
+ return Res ;
5503
5522
5504
- if (HostVisible) {
5505
- ZeEventDesc.signal = ZE_EVENT_SCOPE_FLAG_HOST;
5506
- } else {
5507
- //
5508
- // Set the scope to "device" for every event. This is sufficient for
5509
- // global device access and peer device access. If needed to be seen on
5510
- // the host we are doing special handling, see EventsScope options.
5511
- //
5512
- // TODO: see if "sub-device" (ZE_EVENT_SCOPE_FLAG_SUBDEVICE) can better be
5513
- // used in some circumstances.
5514
- //
5515
- ZeEventDesc.signal = 0 ;
5516
- }
5523
+ ZeStruct<ze_event_desc_t > ZeEventDesc;
5524
+ ZeEventDesc.index = Index;
5525
+ ZeEventDesc.wait = 0 ;
5517
5526
5518
- ZE_CALL (zeEventCreate, (ZeEventPool, &ZeEventDesc, &ZeEvent));
5527
+ if (HostVisible) {
5528
+ ZeEventDesc.signal = ZE_EVENT_SCOPE_FLAG_HOST;
5529
+ } else {
5530
+ //
5531
+ // Set the scope to "device" for every event. This is sufficient for
5532
+ // global device access and peer device access. If needed to be seen on
5533
+ // the host we are doing special handling, see EventsScope options.
5534
+ //
5535
+ // TODO: see if "sub-device" (ZE_EVENT_SCOPE_FLAG_SUBDEVICE) can better be
5536
+ // used in some circumstances.
5537
+ //
5538
+ ZeEventDesc.signal = 0 ;
5519
5539
}
5520
5540
5541
+ ZE_CALL (zeEventCreate, (ZeEventPool, &ZeEventDesc, &ZeEvent));
5542
+
5521
5543
try {
5522
5544
PI_ASSERT (RetEvent, PI_ERROR_INVALID_VALUE);
5523
5545
@@ -5869,12 +5891,7 @@ pi_result piEventRelease(pi_event Event) {
5869
5891
Event->CommandData = nullptr ;
5870
5892
}
5871
5893
if (Event->OwnZeEvent ) {
5872
- if (!DisableEventsCaching) {
5873
- ZE_CALL (zeEventHostReset, (Event->ZeEvent ));
5874
- Event->Context ->addZeEventToCache (Event->ZeEvent , Event->ZeEventPool ,
5875
- Event->isHostVisible (),
5876
- Event->isProfilingEnabled ());
5877
- } else {
5894
+ if (DisableEventsCaching) {
5878
5895
ZE_CALL (zeEventDestroy, (Event->ZeEvent ));
5879
5896
auto Context = Event->Context ;
5880
5897
if (auto Res = Context->decrementUnreleasedEventsInPool (Event))
@@ -5896,7 +5913,12 @@ pi_result piEventRelease(pi_event Event) {
5896
5913
if (Event->Queue ) {
5897
5914
PI_CALL (piQueueReleaseInternal (Event->Queue ));
5898
5915
}
5899
- delete Event;
5916
+
5917
+ if (DisableEventsCaching || !Event->OwnZeEvent ) {
5918
+ delete Event;
5919
+ } else {
5920
+ Event->Context ->addEventToCache (Event);
5921
+ }
5900
5922
5901
5923
return PI_SUCCESS;
5902
5924
}
0 commit comments