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