Skip to content

Commit 49daedf

Browse files
committed
IPC support in L0 provider
1 parent b64363c commit 49daedf

File tree

1 file changed

+133
-1
lines changed

1 file changed

+133
-1
lines changed

src/provider/provider_level_zero.c

Lines changed: 133 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"
@@ -41,6 +43,13 @@ typedef struct ze_ops_t {
4143
const ze_host_mem_alloc_desc_t *, size_t,
4244
size_t, ze_device_handle_t, void *);
4345
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 *);
4453
} ze_ops_t;
4554

4655
static ze_ops_t g_ze_ops;
@@ -57,9 +66,21 @@ static void init_ze_global_state(void) {
5766
*(void **)&g_ze_ops.zeMemAllocShared =
5867
util_get_symbol_addr(0, "zeMemAllocShared");
5968
*(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");
6077

6178
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
6384
LOG_ERR("Required Level Zero symbols not found.");
6485
Init_ze_global_state_failed = true;
6586
}
@@ -256,6 +277,112 @@ static umf_result_t ze_memory_provider_allocation_split(void *provider,
256277
return UMF_RESULT_ERROR_NOT_SUPPORTED;
257278
}
258279

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 *providerIpcData) {
299+
ASSERT(ptr != NULL);
300+
ASSERT(providerIpcData != 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 *)providerIpcData;
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+
LOG_ERR("zeMemGetIpcHandle() failed.");
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 *providerIpcData) {
324+
ASSERT(provider != NULL);
325+
ASSERT(providerIpcData != 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 *)providerIpcData;
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+
LOG_ERR("zeMemPutIpcHandle() failed.");
342+
return UMF_RESULT_ERROR_MEMORY_PROVIDER_SPECIFIC;
343+
}
344+
return UMF_RESULT_SUCCESS;
345+
}
346+
347+
static umf_result_t ze_memory_provider_open_ipc_handle(void *provider,
348+
void *providerIpcData,
349+
void **ptr) {
350+
ASSERT(provider != NULL);
351+
ASSERT(providerIpcData != NULL);
352+
ASSERT(ptr != NULL);
353+
ze_result_t ze_result;
354+
struct ipc_data_t *ipc_data = (struct ipc_data_t *)providerIpcData;
355+
struct ze_memory_provider_t *ze_provider =
356+
(struct ze_memory_provider_t *)provider;
357+
358+
ze_result =
359+
g_ze_ops.zeMemOpenIpcHandle(ze_provider->context, ze_provider->device,
360+
ipc_data->ze_ipc_handle, 0, ptr);
361+
if (ze_result != ZE_RESULT_SUCCESS) {
362+
LOG_ERR("zeMemOpenIpcHandle() failed.");
363+
return UMF_RESULT_ERROR_MEMORY_PROVIDER_SPECIFIC;
364+
}
365+
366+
return UMF_RESULT_SUCCESS;
367+
}
368+
369+
static umf_result_t ze_memory_provider_close_ipc_handle(void *provider,
370+
void *ptr) {
371+
ASSERT(provider != NULL);
372+
ASSERT(ptr != NULL);
373+
ze_result_t ze_result;
374+
struct ze_memory_provider_t *ze_provider =
375+
(struct ze_memory_provider_t *)provider;
376+
377+
ze_result = g_ze_ops.zeMemCloseIpcHandle(ze_provider->context, ptr);
378+
if (ze_result != ZE_RESULT_SUCCESS) {
379+
LOG_ERR("zeMemCloseIpcHandle() failed.");
380+
return UMF_RESULT_ERROR_MEMORY_PROVIDER_SPECIFIC;
381+
}
382+
383+
return UMF_RESULT_SUCCESS;
384+
}
385+
259386
static struct umf_memory_provider_ops_t UMF_LEVEL_ZERO_MEMORY_PROVIDER_OPS = {
260387
.version = UMF_VERSION_CURRENT,
261388
.initialize = ze_memory_provider_initialize,
@@ -270,6 +397,11 @@ static struct umf_memory_provider_ops_t UMF_LEVEL_ZERO_MEMORY_PROVIDER_OPS = {
270397
.ext.purge_force = ze_memory_provider_purge_force,
271398
.ext.allocation_merge = ze_memory_provider_allocation_merge,
272399
.ext.allocation_split = ze_memory_provider_allocation_split,
400+
.ipc.get_ipc_handle_size = ze_memory_provider_get_ipc_handle_size,
401+
.ipc.get_ipc_handle = ze_memory_provider_get_ipc_handle,
402+
.ipc.put_ipc_handle = ze_memory_provider_put_ipc_handle,
403+
.ipc.open_ipc_handle = ze_memory_provider_open_ipc_handle,
404+
.ipc.close_ipc_handle = ze_memory_provider_close_ipc_handle,
273405
};
274406

275407
umf_memory_provider_ops_t *umfLevelZeroMemoryProviderOps(void) {

0 commit comments

Comments
 (0)