@@ -632,7 +632,11 @@ pi_result _pi_context::finalize() {
632
632
std::scoped_lock<pi_mutex> Lock (EventCacheMutex);
633
633
for (auto &EventCache : EventCaches) {
634
634
for (auto &Event : EventCache) {
635
- ZE_CALL (zeEventDestroy, (Event->ZeEvent ));
635
+ auto ZeResult = ZE_CALL_NOCHECK (zeEventDestroy, (Event->ZeEvent ));
636
+ // Gracefully handle the case that L0 was already unloaded.
637
+ if (ZeResult && ZeResult != ZE_RESULT_ERROR_UNINITIALIZED)
638
+ return mapError (ZeResult);
639
+
636
640
delete Event;
637
641
}
638
642
EventCache.clear ();
@@ -641,26 +645,41 @@ pi_result _pi_context::finalize() {
641
645
{
642
646
std::scoped_lock<pi_mutex> Lock (ZeEventPoolCacheMutex);
643
647
for (auto &ZePoolCache : ZeEventPoolCache) {
644
- for (auto &ZePool : ZePoolCache)
645
- ZE_CALL (zeEventPoolDestroy, (ZePool));
648
+ for (auto &ZePool : ZePoolCache) {
649
+ auto ZeResult = ZE_CALL_NOCHECK (zeEventPoolDestroy, (ZePool));
650
+ // Gracefully handle the case that L0 was already unloaded.
651
+ if (ZeResult && ZeResult != ZE_RESULT_ERROR_UNINITIALIZED)
652
+ return mapError (ZeResult);
653
+ }
646
654
ZePoolCache.clear ();
647
655
}
648
656
}
649
657
650
658
// Destroy the command list used for initializations
651
- ZE_CALL (zeCommandListDestroy, (ZeCommandListInit));
659
+ auto ZeResult = ZE_CALL_NOCHECK (zeCommandListDestroy, (ZeCommandListInit));
660
+ // Gracefully handle the case that L0 was already unloaded.
661
+ if (ZeResult && ZeResult != ZE_RESULT_ERROR_UNINITIALIZED)
662
+ return mapError (ZeResult);
652
663
653
664
std::scoped_lock<pi_mutex> Lock (ZeCommandListCacheMutex);
654
665
for (auto &List : ZeComputeCommandListCache) {
655
666
for (ze_command_list_handle_t &ZeCommandList : List.second ) {
656
- if (ZeCommandList)
657
- ZE_CALL (zeCommandListDestroy, (ZeCommandList));
667
+ if (ZeCommandList) {
668
+ auto ZeResult = ZE_CALL_NOCHECK (zeCommandListDestroy, (ZeCommandList));
669
+ // Gracefully handle the case that L0 was already unloaded.
670
+ if (ZeResult && ZeResult != ZE_RESULT_ERROR_UNINITIALIZED)
671
+ return mapError (ZeResult);
672
+ }
658
673
}
659
674
}
660
675
for (auto &List : ZeCopyCommandListCache) {
661
676
for (ze_command_list_handle_t &ZeCommandList : List.second ) {
662
- if (ZeCommandList)
663
- ZE_CALL (zeCommandListDestroy, (ZeCommandList));
677
+ if (ZeCommandList) {
678
+ auto ZeResult = ZE_CALL_NOCHECK (zeCommandListDestroy, (ZeCommandList));
679
+ // Gracefully handle the case that L0 was already unloaded.
680
+ if (ZeResult && ZeResult != ZE_RESULT_ERROR_UNINITIALIZED)
681
+ return mapError (ZeResult);
682
+ }
664
683
}
665
684
}
666
685
return PI_SUCCESS;
@@ -2423,9 +2442,12 @@ pi_result ContextReleaseHelper(pi_context Context) {
2423
2442
// and therefore it must be valid at that point.
2424
2443
// Technically it should be placed to the destructor of pi_context
2425
2444
// but this makes API error handling more complex.
2426
- if (DestoryZeContext)
2427
- ZE_CALL (zeContextDestroy, (DestoryZeContext));
2428
-
2445
+ if (DestoryZeContext) {
2446
+ auto ZeResult = ZE_CALL_NOCHECK (zeContextDestroy, (DestoryZeContext));
2447
+ // Gracefully handle the case that L0 was already unloaded.
2448
+ if (ZeResult && ZeResult != ZE_RESULT_ERROR_UNINITIALIZED)
2449
+ return mapError (ZeResult);
2450
+ }
2429
2451
return Result;
2430
2452
}
2431
2453
@@ -2707,8 +2729,12 @@ pi_result piQueueRelease(pi_queue Queue) {
2707
2729
// runtime. Destroy only if a queue is healthy. Destroying a fence may
2708
2730
// cause a hang otherwise.
2709
2731
// If the fence is a nullptr we are using immediate commandlists.
2710
- if (Queue->Healthy && it->second .ZeFence != nullptr )
2711
- ZE_CALL (zeFenceDestroy, (it->second .ZeFence ));
2732
+ if (Queue->Healthy && it->second .ZeFence != nullptr ) {
2733
+ auto ZeResult = ZE_CALL_NOCHECK (zeFenceDestroy, (it->second .ZeFence ));
2734
+ // Gracefully handle the case that L0 was already unloaded.
2735
+ if (ZeResult && ZeResult != ZE_RESULT_ERROR_UNINITIALIZED)
2736
+ return mapError (ZeResult);
2737
+ }
2712
2738
}
2713
2739
Queue->CommandListMap .clear ();
2714
2740
}
@@ -2744,8 +2770,12 @@ static pi_result piQueueReleaseInternal(pi_queue Queue) {
2744
2770
{Queue->ComputeQueueGroupsByTID , Queue->CopyQueueGroupsByTID })
2745
2771
for (auto &QueueGroup : QueueMap)
2746
2772
for (auto &ZeQueue : QueueGroup.second .ZeQueues )
2747
- if (ZeQueue)
2748
- ZE_CALL (zeCommandQueueDestroy, (ZeQueue));
2773
+ if (ZeQueue) {
2774
+ auto ZeResult = ZE_CALL_NOCHECK (zeCommandQueueDestroy, (ZeQueue));
2775
+ // Gracefully handle the case that L0 was already unloaded.
2776
+ if (ZeResult && ZeResult != ZE_RESULT_ERROR_UNINITIALIZED)
2777
+ return mapError (ZeResult);
2778
+ }
2749
2779
}
2750
2780
2751
2781
urPrint (" piQueueRelease(compute) NumTimesClosedFull %d, "
@@ -3115,7 +3145,11 @@ pi_result piMemRelease(pi_mem Mem) {
3115
3145
if (Mem->isImage ()) {
3116
3146
char *ZeHandleImage;
3117
3147
PI_CALL (Mem->getZeHandle (ZeHandleImage, _pi_mem::write_only));
3118
- ZE_CALL (zeImageDestroy, (pi_cast<ze_image_handle_t >(ZeHandleImage)));
3148
+ auto ZeResult = ZE_CALL_NOCHECK (
3149
+ zeImageDestroy, (pi_cast<ze_image_handle_t >(ZeHandleImage)));
3150
+ // Gracefully handle the case that L0 was already unloaded.
3151
+ if (ZeResult && ZeResult != ZE_RESULT_ERROR_UNINITIALIZED)
3152
+ return mapError (ZeResult);
3119
3153
} else {
3120
3154
auto Buffer = static_cast <pi_buffer>(Mem);
3121
3155
Buffer->free ();
@@ -4326,8 +4360,12 @@ pi_result piKernelRelease(pi_kernel Kernel) {
4326
4360
return PI_SUCCESS;
4327
4361
4328
4362
auto KernelProgram = Kernel->Program ;
4329
- if (Kernel->OwnZeKernel )
4330
- ZE_CALL (zeKernelDestroy, (Kernel->ZeKernel ));
4363
+ if (Kernel->OwnZeKernel ) {
4364
+ auto ZeResult = ZE_CALL_NOCHECK (zeKernelDestroy, (Kernel->ZeKernel ));
4365
+ // Gracefully handle the case that L0 was already unloaded.
4366
+ if (ZeResult && ZeResult != ZE_RESULT_ERROR_UNINITIALIZED)
4367
+ return mapError (ZeResult);
4368
+ }
4331
4369
if (IndirectAccessTrackingEnabled) {
4332
4370
PI_CALL (piContextRelease (KernelProgram->Context ));
4333
4371
}
@@ -5148,7 +5186,11 @@ static pi_result piEventReleaseInternal(pi_event Event) {
5148
5186
}
5149
5187
if (Event->OwnZeEvent ) {
5150
5188
if (DisableEventsCaching) {
5151
- ZE_CALL (zeEventDestroy, (Event->ZeEvent ));
5189
+ auto ZeResult = ZE_CALL_NOCHECK (zeEventDestroy, (Event->ZeEvent ));
5190
+ // Gracefully handle the case that L0 was already unloaded.
5191
+ if (ZeResult && ZeResult != ZE_RESULT_ERROR_UNINITIALIZED)
5192
+ return mapError (ZeResult);
5193
+
5152
5194
auto Context = Event->Context ;
5153
5195
if (auto Res = Context->decrementUnreleasedEventsInPool (Event))
5154
5196
return Res;
@@ -5396,9 +5438,12 @@ pi_result piSamplerRelease(pi_sampler Sampler) {
5396
5438
if (!Sampler->RefCount .decrementAndTest ())
5397
5439
return PI_SUCCESS;
5398
5440
5399
- ZE_CALL (zeSamplerDestroy, (Sampler->ZeSampler ));
5400
- delete Sampler;
5441
+ auto ZeResult = ZE_CALL_NOCHECK (zeSamplerDestroy, (Sampler->ZeSampler ));
5442
+ // Gracefully handle the case that L0 was already unloaded.
5443
+ if (ZeResult && ZeResult != ZE_RESULT_ERROR_UNINITIALIZED)
5444
+ return mapError (ZeResult);
5401
5445
5446
+ delete Sampler;
5402
5447
return PI_SUCCESS;
5403
5448
}
5404
5449
@@ -7393,9 +7438,19 @@ static pi_result USMFreeHelper(pi_context Context, void *Ptr,
7393
7438
7394
7439
// Query memory type of the pointer we're freeing to determine the correct
7395
7440
// way to do it(directly or via an allocator)
7396
- ZE_CALL (zeMemGetAllocProperties,
7397
- (Context->ZeContext , Ptr, &ZeMemoryAllocationProperties,
7398
- &ZeDeviceHandle));
7441
+ auto ZeResult =
7442
+ ZE_CALL_NOCHECK (zeMemGetAllocProperties,
7443
+ (Context->ZeContext , Ptr, &ZeMemoryAllocationProperties,
7444
+ &ZeDeviceHandle));
7445
+
7446
+ // Handle the case that L0 RT was already unloaded
7447
+ if (ZeResult == ZE_RESULT_ERROR_UNINITIALIZED) {
7448
+ if (IndirectAccessTrackingEnabled)
7449
+ PI_CALL (ContextReleaseHelper (Context));
7450
+ return PI_SUCCESS;
7451
+ } else if (ZeResult) {
7452
+ return mapError (ZeResult);
7453
+ }
7399
7454
7400
7455
// If memory type is host release from host pool
7401
7456
if (ZeMemoryAllocationProperties.type == ZE_MEMORY_TYPE_HOST) {
0 commit comments