Skip to content

Commit f780bf0

Browse files
committed
IPC support in L0 provider
1 parent 0ae6e12 commit f780bf0

File tree

1 file changed

+117
-1
lines changed

1 file changed

+117
-1
lines changed

src/provider/provider_level_zero.c

Lines changed: 117 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include <pthread.h>
1111
#include <stdbool.h>
1212
#include <stddef.h>
13+
#include <string.h>
1314
#include <unistd.h>
1415

1516
// Level Zero API
@@ -42,6 +43,13 @@ typedef struct ze_ops_t {
4243
const ze_host_mem_alloc_desc_t *, size_t,
4344
size_t, ze_device_handle_t, void *);
4445
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 *);
4553
} ze_ops_t;
4654

4755
static ze_ops_t g_ze_ops;
@@ -55,9 +63,17 @@ static void init_ze_global_state(void) {
5563
*(void **)&g_ze_ops.zeMemAllocDevice = dlsym(0, "zeMemAllocDevice");
5664
*(void **)&g_ze_ops.zeMemAllocShared = dlsym(0, "zeMemAllocShared");
5765
*(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");
5870

5971
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
6177
fprintf(stderr, "Required Level Zero symbols not found.\n");
6278
Init_ze_global_state_failed = true;
6379
}
@@ -254,6 +270,101 @@ static umf_result_t ze_memory_provider_allocation_split(void *provider,
254270
return UMF_RESULT_ERROR_NOT_SUPPORTED;
255271
}
256272

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+
257368
static struct umf_memory_provider_ops_t UMF_LEVEL_ZERO_MEMORY_PROVIDER_OPS = {
258369
.version = UMF_VERSION_CURRENT,
259370
.initialize = ze_memory_provider_initialize,
@@ -268,6 +379,11 @@ static struct umf_memory_provider_ops_t UMF_LEVEL_ZERO_MEMORY_PROVIDER_OPS = {
268379
.get_name = ze_memory_provider_get_name,
269380
.allocation_split = ze_memory_provider_allocation_split,
270381
.allocation_merge = ze_memory_provider_allocation_merge,
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,
271387
};
272388

273389
umf_memory_provider_ops_t *umfLevelZeroMemoryProviderOps(void) {

0 commit comments

Comments
 (0)