@@ -478,10 +478,18 @@ _pi_context::getFreeSlotInExistingOrNewPool(ze_event_pool_handle_t &Pool,
478478 std::list<ze_event_pool_handle_t > *ZePoolCache =
479479 getZeEventPoolCache (HostVisible, ProfilingEnabled);
480480
481- // Remove full pool from the cache.
482481 if (!ZePoolCache->empty ()) {
483482 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+ }
485493 }
486494 }
487495 if (ZePoolCache->empty ()) {
@@ -878,16 +886,18 @@ pi_result _pi_context::initialize() {
878886pi_result _pi_context::finalize () {
879887 // This function is called when pi_context is deallocated, piContextRelease.
880888 // 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 ();
888899 }
889900 }
890-
891901 {
892902 std::scoped_lock Lock (ZeEventPoolCacheMutex);
893903 for (auto &ZePoolCache : ZeEventPoolCache) {
@@ -5449,26 +5459,40 @@ _pi_event::getOrCreateHostVisibleEvent(ze_event_handle_t &ZeHostVisibleEvent) {
54495459 return PI_SUCCESS;
54505460}
54515461
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);
54565481 if (Cache->empty ())
5457- return std::make_pair<ze_event_handle_t , ze_event_pool_handle_t >(nullptr ,
5458- nullptr );
5482+ return nullptr ;
54595483
54605484 auto It = Cache->begin ();
5461- std::pair< ze_event_handle_t , ze_event_pool_handle_t > ZeEvent = *It;
5485+ pi_event Event = *It;
54625486 Cache->erase (It);
5463- return ZeEvent ;
5487+ return Event ;
54645488}
54655489
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 );
54725496}
54735497
54745498// Helper function for creating a PI event.
@@ -5481,43 +5505,41 @@ static pi_result EventCreate(pi_context Context, pi_queue Queue,
54815505 bool ProfilingEnabled =
54825506 !Queue || (Queue->Properties & PI_QUEUE_PROFILING_ENABLE) != 0 ;
54835507
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+
54865514 ze_event_handle_t ZeEvent;
54875515 ze_event_pool_handle_t ZeEventPool = {};
54885516
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 ;
54995518
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 ;
55035522
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 ;
55175526
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 ;
55195539 }
55205540
5541+ ZE_CALL (zeEventCreate, (ZeEventPool, &ZeEventDesc, &ZeEvent));
5542+
55215543 try {
55225544 PI_ASSERT (RetEvent, PI_ERROR_INVALID_VALUE);
55235545
@@ -5869,12 +5891,7 @@ pi_result piEventRelease(pi_event Event) {
58695891 Event->CommandData = nullptr ;
58705892 }
58715893 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) {
58785895 ZE_CALL (zeEventDestroy, (Event->ZeEvent ));
58795896 auto Context = Event->Context ;
58805897 if (auto Res = Context->decrementUnreleasedEventsInPool (Event))
@@ -5896,7 +5913,12 @@ pi_result piEventRelease(pi_event Event) {
58965913 if (Event->Queue ) {
58975914 PI_CALL (piQueueReleaseInternal (Event->Queue ));
58985915 }
5899- delete Event;
5916+
5917+ if (DisableEventsCaching || !Event->OwnZeEvent ) {
5918+ delete Event;
5919+ } else {
5920+ Event->Context ->addEventToCache (Event);
5921+ }
59005922
59015923 return PI_SUCCESS;
59025924}
0 commit comments