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