10
10
#include <pthread.h>
11
11
#include <stdbool.h>
12
12
#include <stddef.h>
13
+ #include <string.h>
13
14
#include <unistd.h>
14
15
15
16
// Level Zero API
@@ -42,6 +43,13 @@ typedef struct ze_ops_t {
42
43
const ze_host_mem_alloc_desc_t * , size_t ,
43
44
size_t , ze_device_handle_t , void * );
44
45
ze_result_t (* zeMemFree )(ze_context_handle_t , void * );
46
+ ze_result_t (* zeMemGetIpcHandle )(ze_context_handle_t , const void * ,
47
+ ze_ipc_mem_handle_t * );
48
+ ze_result_t (* zeMemPutIpcHandle )(ze_context_handle_t , ze_ipc_mem_handle_t );
49
+ ze_result_t (* zeMemOpenIpcHandle )(ze_context_handle_t , ze_device_handle_t ,
50
+ ze_ipc_mem_handle_t ,
51
+ ze_ipc_memory_flags_t , void * * );
52
+ ze_result_t (* zeMemCloseIpcHandle )(ze_context_handle_t , void * );
45
53
} ze_ops_t ;
46
54
47
55
static ze_ops_t g_ze_ops ;
@@ -55,9 +63,17 @@ static void init_ze_global_state(void) {
55
63
* (void * * )& g_ze_ops .zeMemAllocDevice = dlsym (0 , "zeMemAllocDevice" );
56
64
* (void * * )& g_ze_ops .zeMemAllocShared = dlsym (0 , "zeMemAllocShared" );
57
65
* (void * * )& g_ze_ops .zeMemFree = dlsym (0 , "zeMemFree" );
66
+ * (void * * )& g_ze_ops .zeMemGetIpcHandle = dlsym (0 , "zeMemGetIpcHandle" );
67
+ * (void * * )& g_ze_ops .zeMemPutIpcHandle = dlsym (0 , "zeMemPutIpcHandle" );
68
+ * (void * * )& g_ze_ops .zeMemOpenIpcHandle = dlsym (0 , "zeMemOpenIpcHandle" );
69
+ * (void * * )& g_ze_ops .zeMemCloseIpcHandle = dlsym (0 , "zeMemCloseIpcHandle" );
58
70
59
71
if (!g_ze_ops .zeMemAllocHost || !g_ze_ops .zeMemAllocDevice ||
60
- !g_ze_ops .zeMemAllocShared || !g_ze_ops .zeMemFree ) {
72
+ !g_ze_ops .zeMemAllocShared || !g_ze_ops .zeMemFree ||
73
+ !g_ze_ops .zeMemGetIpcHandle || !g_ze_ops .zeMemOpenIpcHandle ||
74
+ !g_ze_ops .zeMemCloseIpcHandle ) {
75
+ // g_ze_ops.zeMemPutIpcHandle can be NULL because it was introduced
76
+ // starting from Level Zero 1.6
61
77
fprintf (stderr , "Required Level Zero symbols not found.\n" );
62
78
Init_ze_global_state_failed = true;
63
79
}
@@ -254,6 +270,101 @@ static umf_result_t ze_memory_provider_allocation_split(void *provider,
254
270
return UMF_RESULT_ERROR_NOT_SUPPORTED ;
255
271
}
256
272
273
+ struct ipc_data_t {
274
+ ze_ipc_mem_handle_t ze_ipc_handle ;
275
+ ze_memory_type_t memory_type ;
276
+ //TODO: do we need size?
277
+ size_t size ;
278
+ };
279
+
280
+ static umf_result_t ze_memory_provider_get_ipc_handle_size (void * provider ,
281
+ size_t * size ) {
282
+ (void )provider ;
283
+ * size = sizeof (struct ipc_data_t );
284
+ return UMF_RESULT_SUCCESS ;
285
+ }
286
+
287
+ static umf_result_t ze_memory_provider_get_ipc_handle (void * provider ,
288
+ const void * ptr ,
289
+ size_t size ,
290
+ void * ipcData ) {
291
+ ze_result_t ze_result ;
292
+ ze_ipc_mem_handle_t ze_ipc_handle = {0 };
293
+ struct ipc_data_t * ipc_data = (struct ipc_data_t * )ipcData ;
294
+ struct ze_memory_provider_t * ze_provider =
295
+ (struct ze_memory_provider_t * )provider ;
296
+
297
+ ze_result =
298
+ g_ze_ops .zeMemGetIpcHandle (ze_provider -> context , ptr , & ze_ipc_handle );
299
+ if (ze_result != ZE_RESULT_SUCCESS ) {
300
+ fprintf (stderr , "zeMemGetIpcHandle() failed\n" );
301
+ return UMF_RESULT_ERROR_MEMORY_PROVIDER_SPECIFIC ;
302
+ }
303
+
304
+ memcpy (& (ipc_data -> ze_ipc_handle ), & ze_ipc_handle ,
305
+ sizeof (ze_ipc_mem_handle_t ));
306
+ ipc_data -> memory_type = ze_provider -> memory_type ;
307
+ ipc_data -> size = size ;
308
+
309
+ return UMF_RESULT_SUCCESS ;
310
+ }
311
+
312
+ static umf_result_t ze_memory_provider_put_ipc_handle (void * provider ,
313
+ void * ipcData ) {
314
+ ze_result_t ze_result ;
315
+ struct ze_memory_provider_t * ze_provider =
316
+ (struct ze_memory_provider_t * )provider ;
317
+ struct ipc_data_t * ipc_data = (struct ipc_data_t * )ipcData ;
318
+
319
+ if (g_ze_ops .zeMemPutIpcHandle == NULL ) {
320
+ // g_ze_ops.zeMemPutIpcHandle can be NULL because it was introduced
321
+ // starting from Level Zero 1.6
322
+ // TODO: Should we return UMF_RESULT_SUCCESS or UMF_RESULT_ERROR_NOT_SUPPORTED?
323
+ return UMF_RESULT_ERROR_NOT_SUPPORTED ;
324
+ }
325
+
326
+ ze_result = g_ze_ops .zeMemPutIpcHandle (ze_provider -> context ,
327
+ ipc_data -> ze_ipc_handle );
328
+ if (ze_result != ZE_RESULT_SUCCESS ) {
329
+ fprintf (stderr , "zeMemPutIpcHandle() failed\n" );
330
+ return UMF_RESULT_ERROR_MEMORY_PROVIDER_SPECIFIC ;
331
+ }
332
+ return UMF_RESULT_SUCCESS ;
333
+ }
334
+
335
+ static umf_result_t
336
+ ze_memory_provider_open_ipc_handle (void * provider , void * ipcData , void * * ptr ) {
337
+ ze_result_t ze_result ;
338
+ struct ipc_data_t * ipc_data = (struct ipc_data_t * )ipcData ;
339
+ struct ze_memory_provider_t * ze_provider =
340
+ (struct ze_memory_provider_t * )provider ;
341
+
342
+ ze_result =
343
+ g_ze_ops .zeMemOpenIpcHandle (ze_provider -> context , ze_provider -> device ,
344
+ ipc_data -> ze_ipc_handle , 0 , ptr );
345
+ if (ze_result != ZE_RESULT_SUCCESS ) {
346
+ fprintf (stderr , "zeMemOpenIpcHandle() failed\n" );
347
+ return UMF_RESULT_ERROR_MEMORY_PROVIDER_SPECIFIC ;
348
+ }
349
+
350
+ return UMF_RESULT_SUCCESS ;
351
+ }
352
+
353
+ static umf_result_t ze_memory_provider_close_ipc_handle (void * provider ,
354
+ void * ptr ) {
355
+ ze_result_t ze_result ;
356
+ struct ze_memory_provider_t * ze_provider =
357
+ (struct ze_memory_provider_t * )provider ;
358
+
359
+ ze_result = g_ze_ops .zeMemCloseIpcHandle (ze_provider -> context , ptr );
360
+ if (ze_result != ZE_RESULT_SUCCESS ) {
361
+ fprintf (stderr , "zeMemCloseIpcHandle() failed\n" );
362
+ return UMF_RESULT_ERROR_MEMORY_PROVIDER_SPECIFIC ;
363
+ }
364
+
365
+ return UMF_RESULT_SUCCESS ;
366
+ }
367
+
257
368
static struct umf_memory_provider_ops_t UMF_LEVEL_ZERO_MEMORY_PROVIDER_OPS = {
258
369
.version = UMF_VERSION_CURRENT ,
259
370
.initialize = ze_memory_provider_initialize ,
@@ -268,6 +379,11 @@ static struct umf_memory_provider_ops_t UMF_LEVEL_ZERO_MEMORY_PROVIDER_OPS = {
268
379
.ext .purge_force = ze_memory_provider_purge_force ,
269
380
.ext .allocation_merge = ze_memory_provider_allocation_merge ,
270
381
.ext .allocation_split = ze_memory_provider_allocation_split ,
382
+ .ipc .get_ipc_handle_size = ze_memory_provider_get_ipc_handle_size ,
383
+ .ipc .get_ipc_handle = ze_memory_provider_get_ipc_handle ,
384
+ .ipc .put_ipc_handle = ze_memory_provider_put_ipc_handle ,
385
+ .ipc .open_ipc_handle = ze_memory_provider_open_ipc_handle ,
386
+ .ipc .close_ipc_handle = ze_memory_provider_close_ipc_handle ,
271
387
};
272
388
273
389
umf_memory_provider_ops_t * umfLevelZeroMemoryProviderOps (void ) {
0 commit comments