Skip to content

Commit 7e17bc4

Browse files
committed
IPC support in L0 provider
1 parent 69df3fc commit 7e17bc4

File tree

1 file changed

+132
-1
lines changed

1 file changed

+132
-1
lines changed

src/provider/provider_level_zero.c

Lines changed: 132 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include <assert.h>
99
#include <stdbool.h>
1010
#include <stddef.h>
11+
#include <string.h>
1112

1213
// Level Zero API
1314
#include <ze_api.h>
@@ -17,6 +18,7 @@
1718
#include <umf/providers/provider_level_zero.h>
1819

1920
#include "base_alloc_global.h"
21+
#include "utils_assert.h"
2022
#include "utils_common.h"
2123
#include "utils_concurrency.h"
2224
#include "utils_load_library.h"
@@ -40,6 +42,13 @@ typedef struct ze_ops_t {
4042
const ze_host_mem_alloc_desc_t *, size_t,
4143
size_t, ze_device_handle_t, void *);
4244
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 *);
4352
} ze_ops_t;
4453

4554
static ze_ops_t g_ze_ops;
@@ -56,9 +65,21 @@ static void init_ze_global_state(void) {
5665
*(void **)&g_ze_ops.zeMemAllocShared =
5766
util_get_symbol_addr(0, "zeMemAllocShared");
5867
*(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");
5976

6077
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
6283
fprintf(stderr, "Required Level Zero symbols not found.\n");
6384
Init_ze_global_state_failed = true;
6485
}
@@ -255,6 +276,111 @@ static umf_result_t ze_memory_provider_allocation_split(void *provider,
255276
return UMF_RESULT_ERROR_NOT_SUPPORTED;
256277
}
257278

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+
258384
static struct umf_memory_provider_ops_t UMF_LEVEL_ZERO_MEMORY_PROVIDER_OPS = {
259385
.version = UMF_VERSION_CURRENT,
260386
.initialize = ze_memory_provider_initialize,
@@ -269,6 +395,11 @@ static struct umf_memory_provider_ops_t UMF_LEVEL_ZERO_MEMORY_PROVIDER_OPS = {
269395
.ext.purge_force = ze_memory_provider_purge_force,
270396
.ext.allocation_merge = ze_memory_provider_allocation_merge,
271397
.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,
272403
};
273404

274405
umf_memory_provider_ops_t *umfLevelZeroMemoryProviderOps(void) {

0 commit comments

Comments
 (0)