@@ -73,6 +73,53 @@ std::mutex ZeCall::GlobalLock;
73
73
// Controls Level Zero calls tracing in zePrint.
74
74
static bool ZeDebug = false ;
75
75
76
+ // Map Level Zero runtime error code to PI error code
77
+ static pi_result mapError (ze_result_t ZeResult) {
78
+ // TODO: these mapping need to be clarified and synced with the PI API return
79
+ // values, which is TBD.
80
+ static std::unordered_map<ze_result_t , pi_result> ErrorMapping = {
81
+ {ZE_RESULT_SUCCESS, PI_SUCCESS},
82
+ {ZE_RESULT_ERROR_DEVICE_LOST, PI_DEVICE_NOT_FOUND},
83
+ {ZE_RESULT_ERROR_INSUFFICIENT_PERMISSIONS, PI_INVALID_OPERATION},
84
+ {ZE_RESULT_ERROR_NOT_AVAILABLE, PI_INVALID_OPERATION},
85
+ {ZE_RESULT_ERROR_UNINITIALIZED, PI_INVALID_PLATFORM},
86
+ {ZE_RESULT_ERROR_INVALID_ARGUMENT, PI_INVALID_VALUE},
87
+ {ZE_RESULT_ERROR_INVALID_NULL_POINTER, PI_INVALID_VALUE},
88
+ {ZE_RESULT_ERROR_INVALID_SIZE, PI_INVALID_VALUE},
89
+ {ZE_RESULT_ERROR_UNSUPPORTED_SIZE, PI_INVALID_VALUE},
90
+ {ZE_RESULT_ERROR_UNSUPPORTED_ALIGNMENT, PI_INVALID_VALUE},
91
+ {ZE_RESULT_ERROR_INVALID_SYNCHRONIZATION_OBJECT, PI_INVALID_EVENT},
92
+ {ZE_RESULT_ERROR_INVALID_ENUMERATION, PI_INVALID_VALUE},
93
+ {ZE_RESULT_ERROR_UNSUPPORTED_ENUMERATION, PI_INVALID_VALUE},
94
+ {ZE_RESULT_ERROR_UNSUPPORTED_IMAGE_FORMAT, PI_INVALID_VALUE},
95
+ {ZE_RESULT_ERROR_INVALID_NATIVE_BINARY, PI_INVALID_BINARY},
96
+ {ZE_RESULT_ERROR_INVALID_KERNEL_NAME, PI_INVALID_KERNEL_NAME},
97
+ {ZE_RESULT_ERROR_INVALID_FUNCTION_NAME, PI_BUILD_PROGRAM_FAILURE},
98
+ {ZE_RESULT_ERROR_OVERLAPPING_REGIONS, PI_INVALID_OPERATION},
99
+ {ZE_RESULT_ERROR_INVALID_GROUP_SIZE_DIMENSION,
100
+ PI_INVALID_WORK_GROUP_SIZE},
101
+ {ZE_RESULT_ERROR_MODULE_BUILD_FAILURE, PI_BUILD_PROGRAM_FAILURE}};
102
+
103
+ auto It = ErrorMapping.find (ZeResult);
104
+ if (It == ErrorMapping.end ()) {
105
+ return PI_ERROR_UNKNOWN;
106
+ }
107
+ return It->second ;
108
+ }
109
+
110
+ // Trace a call to Level-Zero RT
111
+ #define ZE_CALL (Call ) \
112
+ if (auto Result = ZeCall().doCall(Call, #Call, true )) \
113
+ return mapError(Result);
114
+ #define ZE_CALL_NOCHECK (Call ) ZeCall().doCall(Call, #Call, false )
115
+
116
+ // Trace an internal PI call; returns in case of an error.
117
+ #define PI_CALL (Call ) \
118
+ fprintf (stderr, " PI ---> %s\n " , #Call); \
119
+ pi_result Result = (Call); \
120
+ if (Result != PI_SUCCESS) \
121
+ return Result;
122
+
76
123
// Controls Level Zero validation layer and parameter validation.
77
124
static bool ZeValidationLayer = false ;
78
125
@@ -212,7 +259,7 @@ pi_result _pi_mem::removeMapping(void *MappedTo, Mapping &MapInfo) {
212
259
return PI_SUCCESS;
213
260
}
214
261
215
- ze_result_t
262
+ pi_result
216
263
_pi_context::getFreeSlotInExistingOrNewPool (ze_event_pool_handle_t &ZePool,
217
264
size_t &Index) {
218
265
// Maximum number of events that can be present in an event ZePool is captured
@@ -227,7 +274,7 @@ _pi_context::getFreeSlotInExistingOrNewPool(ze_event_pool_handle_t &ZePool,
227
274
if (MaxNumEventsPerPool == 0 ) {
228
275
zePrint (" Zero size can't be specified in the "
229
276
" ZE_MAX_NUMBER_OF_EVENTS_PER_EVENT_POOL\n " );
230
- return ZE_RESULT_ERROR_INVALID_SIZE ;
277
+ return PI_INVALID_VALUE ;
231
278
}
232
279
233
280
Index = 0 ;
@@ -260,10 +307,8 @@ _pi_context::getFreeSlotInExistingOrNewPool(ze_event_pool_handle_t &ZePool,
260
307
std::for_each (Devices.begin (), Devices.end (),
261
308
[&](pi_device &D) { ZeDevices.push_back (D->ZeDevice ); });
262
309
263
- if (ze_result_t ZeRes =
264
- zeEventPoolCreate (ZeContext, &ZeEventPoolDesc, ZeDevices.size (),
265
- &ZeDevices[0 ], &ZeEventPool))
266
- return ZeRes;
310
+ ZE_CALL (zeEventPoolCreate (ZeContext, &ZeEventPoolDesc, ZeDevices.size (),
311
+ &ZeDevices[0 ], &ZeEventPool));
267
312
NumEventsAvailableInEventPool[ZeEventPool] = MaxNumEventsPerPool - 1 ;
268
313
NumEventsLiveInEventPool[ZeEventPool] = MaxNumEventsPerPool;
269
314
} else {
@@ -273,57 +318,24 @@ _pi_context::getFreeSlotInExistingOrNewPool(ze_event_pool_handle_t &ZePool,
273
318
--NumEventsAvailableInEventPool[ZeEventPool];
274
319
}
275
320
ZePool = ZeEventPool;
276
- return ZE_RESULT_SUCCESS ;
321
+ return PI_SUCCESS ;
277
322
}
278
323
279
- ze_result_t
324
+ pi_result
280
325
_pi_context::decrementAliveEventsInPool (ze_event_pool_handle_t ZePool) {
281
326
std::lock_guard<std::mutex> Lock (NumEventsLiveInEventPoolMutex);
282
327
--NumEventsLiveInEventPool[ZePool];
283
328
if (NumEventsLiveInEventPool[ZePool] == 0 ) {
284
- return zeEventPoolDestroy (ZePool);
329
+ ZE_CALL ( zeEventPoolDestroy (ZePool) );
285
330
}
286
- return ZE_RESULT_SUCCESS ;
331
+ return PI_SUCCESS ;
287
332
}
288
333
289
334
// Some opencl extensions we know are supported by all Level Zero devices.
290
335
constexpr char ZE_SUPPORTED_EXTENSIONS[] =
291
336
" cl_khr_il_program cl_khr_subgroups cl_intel_subgroups "
292
337
" cl_intel_subgroups_short cl_intel_required_subgroup_size " ;
293
338
294
- // Map Level Zero runtime error code to PI error code
295
- static pi_result mapError (ze_result_t ZeResult) {
296
- // TODO: these mapping need to be clarified and synced with the PI API return
297
- // values, which is TBD.
298
- static std::unordered_map<ze_result_t , pi_result> ErrorMapping = {
299
- {ZE_RESULT_SUCCESS, PI_SUCCESS},
300
- {ZE_RESULT_ERROR_DEVICE_LOST, PI_DEVICE_NOT_FOUND},
301
- {ZE_RESULT_ERROR_INSUFFICIENT_PERMISSIONS, PI_INVALID_OPERATION},
302
- {ZE_RESULT_ERROR_NOT_AVAILABLE, PI_INVALID_OPERATION},
303
- {ZE_RESULT_ERROR_UNINITIALIZED, PI_INVALID_PLATFORM},
304
- {ZE_RESULT_ERROR_INVALID_ARGUMENT, PI_INVALID_VALUE},
305
- {ZE_RESULT_ERROR_INVALID_NULL_POINTER, PI_INVALID_VALUE},
306
- {ZE_RESULT_ERROR_INVALID_SIZE, PI_INVALID_VALUE},
307
- {ZE_RESULT_ERROR_UNSUPPORTED_SIZE, PI_INVALID_VALUE},
308
- {ZE_RESULT_ERROR_UNSUPPORTED_ALIGNMENT, PI_INVALID_VALUE},
309
- {ZE_RESULT_ERROR_INVALID_SYNCHRONIZATION_OBJECT, PI_INVALID_EVENT},
310
- {ZE_RESULT_ERROR_INVALID_ENUMERATION, PI_INVALID_VALUE},
311
- {ZE_RESULT_ERROR_UNSUPPORTED_ENUMERATION, PI_INVALID_VALUE},
312
- {ZE_RESULT_ERROR_UNSUPPORTED_IMAGE_FORMAT, PI_INVALID_VALUE},
313
- {ZE_RESULT_ERROR_INVALID_NATIVE_BINARY, PI_INVALID_BINARY},
314
- {ZE_RESULT_ERROR_INVALID_KERNEL_NAME, PI_INVALID_KERNEL_NAME},
315
- {ZE_RESULT_ERROR_INVALID_FUNCTION_NAME, PI_BUILD_PROGRAM_FAILURE},
316
- {ZE_RESULT_ERROR_OVERLAPPING_REGIONS, PI_INVALID_OPERATION},
317
- {ZE_RESULT_ERROR_INVALID_GROUP_SIZE_DIMENSION,
318
- PI_INVALID_WORK_GROUP_SIZE},
319
- {ZE_RESULT_ERROR_MODULE_BUILD_FAILURE, PI_BUILD_PROGRAM_FAILURE}};
320
- auto It = ErrorMapping.find (ZeResult);
321
- if (It == ErrorMapping.end ()) {
322
- return PI_ERROR_UNKNOWN;
323
- }
324
- return It->second ;
325
- }
326
-
327
339
// Forward declarations
328
340
static pi_result
329
341
enqueueMemCopyHelper (pi_command_type CommandType, pi_queue Queue, void *Dst,
@@ -402,10 +414,6 @@ ze_result_t ZeCall::doCall(ze_result_t ZeResult, const char *CallStr,
402
414
#define PI_ASSERT (condition, error ) \
403
415
if (!(condition)) \
404
416
return error;
405
- #define ZE_CALL (Call ) \
406
- if (auto Result = ZeCall().doCall(Call, #Call, true )) \
407
- return mapError(Result);
408
- #define ZE_CALL_NOCHECK (Call ) ZeCall().doCall(Call, #Call, false )
409
417
410
418
// Destroy all the command lists associated with this device.
411
419
// This is required when destructing the _pi_device object.
@@ -417,7 +425,7 @@ _pi_device::~_pi_device() {
417
425
std::lock_guard<std::mutex> Lock (ZeCommandListCacheMutex);
418
426
for (ze_command_list_handle_t &ZeCommandList : ZeCommandListCache) {
419
427
if (ZeCommandList)
420
- zeCommandListDestroy (ZeCommandList);
428
+ ZE_CALL_NOCHECK ( zeCommandListDestroy (ZeCommandList) );
421
429
}
422
430
}
423
431
@@ -510,7 +518,7 @@ pi_result _pi_context::finalize() {
510
518
std::lock_guard<std::mutex> NumEventsLiveInEventPoolGuard (
511
519
NumEventsLiveInEventPoolMutex);
512
520
if (ZeEventPool && NumEventsLiveInEventPool[ZeEventPool])
513
- zeEventPoolDestroy (ZeEventPool);
521
+ ZE_CALL ( zeEventPoolDestroy (ZeEventPool) );
514
522
515
523
// Destroy the command list used for initializations
516
524
ZE_CALL (zeCommandListDestroy (ZeCommandListInit));
@@ -811,7 +819,7 @@ pi_result _pi_ze_event_list_t::createAndRetainPiZeEventList(
811
819
}
812
820
813
821
for (pi_uint32 I = 0 ; I < this ->Length ; I++) {
814
- piEventRetain (this ->PiEventList [I]);
822
+ PI_CALL ( piEventRetain (this ->PiEventList [I]) );
815
823
}
816
824
}
817
825
@@ -1137,10 +1145,7 @@ pi_result piextPlatformCreateWithNativeHandle(pi_native_handle NativeHandle,
1137
1145
1138
1146
if (NumPlatforms) {
1139
1147
std::vector<pi_platform> Platforms (NumPlatforms);
1140
- Res = piPlatformsGet (NumPlatforms, Platforms.data (), nullptr );
1141
- if (Res != PI_SUCCESS) {
1142
- return Res;
1143
- }
1148
+ PI_CALL (piPlatformsGet (NumPlatforms, Platforms.data (), nullptr ));
1144
1149
1145
1150
// The SYCL spec requires that the set of platforms must remain fixed for
1146
1151
// the duration of the application's execution. We assume that we found all
@@ -2829,7 +2834,7 @@ pi_result piProgramLink(pi_context Context, pi_uint32 NumDevices,
2829
2834
// This module imports symbols, but it isn't currently linked with
2830
2835
// any other module. Grab the flag to indicate that it is now
2831
2836
// linked.
2832
- piProgramRetain (Input);
2837
+ PI_CALL ( piProgramRetain (Input) );
2833
2838
Input->HasImportsAndIsLinked = true ;
2834
2839
} else {
2835
2840
// This module imports symbols and is also linked with another module
@@ -2848,7 +2853,7 @@ pi_result piProgramLink(pi_context Context, pi_uint32 NumDevices,
2848
2853
Input->HasImportsAndIsLinked = true ;
2849
2854
}
2850
2855
} else {
2851
- piProgramRetain (Input);
2856
+ PI_CALL ( piProgramRetain (Input) );
2852
2857
}
2853
2858
Inputs.emplace_back (Input);
2854
2859
ZeHandles.push_back (Input->ZeModule );
@@ -3266,7 +3271,7 @@ pi_result piKernelCreate(pi_program Program, const char *KernelName,
3266
3271
}
3267
3272
3268
3273
// Update the refcount of the program to show its use by this kernel.
3269
- piProgramRetain (Program);
3274
+ PI_CALL ( piProgramRetain (Program) );
3270
3275
3271
3276
return PI_SUCCESS;
3272
3277
}
@@ -3474,7 +3479,7 @@ pi_result piKernelRetain(pi_kernel Kernel) {
3474
3479
3475
3480
++(Kernel->RefCount );
3476
3481
// When retaining a kernel, you are also retaining the program it is part of.
3477
- piProgramRetain (Kernel->Program );
3482
+ PI_CALL ( piProgramRetain (Kernel->Program ) );
3478
3483
return PI_SUCCESS;
3479
3484
}
3480
3485
@@ -3485,12 +3490,12 @@ pi_result piKernelRelease(pi_kernel Kernel) {
3485
3490
auto KernelProgram = Kernel->Program ;
3486
3491
3487
3492
if (--(Kernel->RefCount ) == 0 ) {
3488
- zeKernelDestroy (Kernel->ZeKernel );
3493
+ ZE_CALL ( zeKernelDestroy (Kernel->ZeKernel ) );
3489
3494
delete Kernel;
3490
3495
}
3491
3496
3492
3497
// do a release on the program this kernel was part of
3493
- piProgramRelease (KernelProgram);
3498
+ PI_CALL ( piProgramRelease (KernelProgram) );
3494
3499
3495
3500
return PI_SUCCESS;
3496
3501
}
@@ -3610,7 +3615,7 @@ piEnqueueKernelLaunch(pi_queue Queue, pi_kernel Kernel, pi_uint32 WorkDim,
3610
3615
// code in cleanupAfterEvent will do a piReleaseKernel to update
3611
3616
// the reference count on the kernel, using the kernel saved
3612
3617
// in CommandData.
3613
- piKernelRetain (Kernel);
3618
+ PI_CALL ( piKernelRetain (Kernel) );
3614
3619
3615
3620
// Add the command to the command list
3616
3621
ZE_CALL (zeCommandListAppendLaunchKernel (
@@ -3636,7 +3641,9 @@ piEnqueueKernelLaunch(pi_queue Queue, pi_kernel Kernel, pi_uint32 WorkDim,
3636
3641
pi_result piEventCreate (pi_context Context, pi_event *RetEvent) {
3637
3642
size_t Index = 0 ;
3638
3643
ze_event_pool_handle_t ZeEventPool = {};
3639
- ZE_CALL (Context->getFreeSlotInExistingOrNewPool (ZeEventPool, Index));
3644
+ if (auto Res = Context->getFreeSlotInExistingOrNewPool (ZeEventPool, Index))
3645
+ return Res;
3646
+
3640
3647
ze_event_handle_t ZeEvent;
3641
3648
ze_event_desc_t ZeEventDesc = {};
3642
3649
// We have to set the SIGNAL & WAIT flags as HOST scope because the
@@ -3714,15 +3721,15 @@ pi_result piEventGetProfilingInfo(pi_event Event, pi_profiling_info ParamName,
3714
3721
3715
3722
switch (ParamName) {
3716
3723
case PI_PROFILING_INFO_COMMAND_START: {
3717
- zeEventQueryKernelTimestamp (Event->ZeEvent , &tsResult);
3724
+ ZE_CALL ( zeEventQueryKernelTimestamp (Event->ZeEvent , &tsResult) );
3718
3725
3719
3726
uint64_t ContextStartTime = tsResult.context .kernelStart ;
3720
3727
ContextStartTime *= ZeTimerResolution;
3721
3728
3722
3729
return ReturnValue (uint64_t {ContextStartTime});
3723
3730
}
3724
3731
case PI_PROFILING_INFO_COMMAND_END: {
3725
- zeEventQueryKernelTimestamp (Event->ZeEvent , &tsResult);
3732
+ ZE_CALL ( zeEventQueryKernelTimestamp (Event->ZeEvent , &tsResult) );
3726
3733
3727
3734
uint64_t ContextStartTime = tsResult.context .kernelStart ;
3728
3735
uint64_t ContextEndTime = tsResult.context .kernelEnd ;
@@ -3757,7 +3764,7 @@ pi_result piEventGetProfilingInfo(pi_event Event, pi_profiling_info ParamName,
3757
3764
// Perform any necessary cleanup after an event has been signalled.
3758
3765
// This currently recycles the associate command list, and also makes
3759
3766
// sure to release any kernel that may have been used by the event.
3760
- static void cleanupAfterEvent (pi_event Event) {
3767
+ static pi_result cleanupAfterEvent (pi_event Event) {
3761
3768
// The implementation of this is slightly tricky. The same event
3762
3769
// can be referred to by multiple threads, so it is possible to
3763
3770
// have a race condition between the read of fields of the event,
@@ -3794,7 +3801,7 @@ static void cleanupAfterEvent(pi_event Event) {
3794
3801
// Release the kernel associated with this event if there is one.
3795
3802
if (Event->CommandType == PI_COMMAND_TYPE_NDRANGE_KERNEL &&
3796
3803
Event->CommandData ) {
3797
- piKernelRelease (pi_cast<pi_kernel>(Event->CommandData ));
3804
+ PI_CALL ( piKernelRelease (pi_cast<pi_kernel>(Event->CommandData ) ));
3798
3805
Event->CommandData = nullptr ;
3799
3806
}
3800
3807
}
@@ -3818,8 +3825,9 @@ static void cleanupAfterEvent(pi_event Event) {
3818
3825
3819
3826
DepEvent->WaitList .collectEventsForReleaseAndDestroyPiZeEventList (
3820
3827
EventsToBeReleased);
3821
- piEventRelease (DepEvent);
3828
+ PI_CALL ( piEventRelease (DepEvent) );
3822
3829
}
3830
+ return PI_SUCCESS;
3823
3831
}
3824
3832
3825
3833
pi_result piEventsWait (pi_uint32 NumEvents, const pi_event *EventList) {
@@ -3893,13 +3901,14 @@ pi_result piEventRelease(pi_event Event) {
3893
3901
ZE_CALL (zeEventDestroy (Event->ZeEvent ));
3894
3902
3895
3903
auto Context = Event->Context ;
3896
- ZE_CALL (Context->decrementAliveEventsInPool (Event->ZeEventPool ));
3904
+ if (auto Res = Context->decrementAliveEventsInPool (Event->ZeEventPool ))
3905
+ return Res;
3897
3906
3898
3907
// We intentionally incremented the reference counter when an event is
3899
3908
// created so that we can avoid pi_queue is released before the associated
3900
3909
// pi_event is released. Here we have to decrement it so pi_queue
3901
3910
// can be released successfully.
3902
- piQueueRelease (Event->Queue );
3911
+ PI_CALL ( piQueueRelease (Event->Queue ) );
3903
3912
delete Event;
3904
3913
}
3905
3914
return PI_SUCCESS;
@@ -4510,7 +4519,7 @@ pi_result piEnqueueMemBufferMap(pi_queue Queue, pi_mem Buffer,
4510
4519
// allocated in host memory.
4511
4520
if (Buffer->OnHost ) {
4512
4521
// Wait on incoming events before doing the copy
4513
- piEventsWait (NumEventsInWaitList, EventWaitList);
4522
+ PI_CALL ( piEventsWait (NumEventsInWaitList, EventWaitList) );
4514
4523
if (Buffer->MapHostPtr ) {
4515
4524
*RetMap = Buffer->MapHostPtr + Offset;
4516
4525
if (!(MapFlags & PI_MAP_WRITE_INVALIDATE_REGION))
@@ -4615,7 +4624,7 @@ pi_result piEnqueueMemUnmap(pi_queue Queue, pi_mem MemObj, void *MappedPtr,
4615
4624
// in host memory.
4616
4625
if (MemObj->OnHost ) {
4617
4626
// Wait on incoming events before doing the copy
4618
- piEventsWait (NumEventsInWaitList, EventWaitList);
4627
+ PI_CALL ( piEventsWait (NumEventsInWaitList, EventWaitList) );
4619
4628
if (MemObj->MapHostPtr )
4620
4629
memcpy (pi_cast<char *>(MemObj->getZeHandle ()) + MapInfo.Offset , MappedPtr,
4621
4630
MapInfo.Size );
@@ -5268,7 +5277,8 @@ pi_result piextUSMFree(pi_context Context, void *Ptr) {
5268
5277
pi_result piextKernelSetArgPointer (pi_kernel Kernel, pi_uint32 ArgIndex,
5269
5278
size_t ArgSize, const void *ArgValue) {
5270
5279
5271
- return piKernelSetArg (Kernel, ArgIndex, ArgSize, ArgValue);
5280
+ PI_CALL (piKernelSetArg (Kernel, ArgIndex, ArgSize, ArgValue));
5281
+ return PI_SUCCESS;
5272
5282
}
5273
5283
5274
5284
// / USM Memset API
0 commit comments