Skip to content

Commit 222a511

Browse files
committed
[L0] Implement IPC ops for L0 adapter
1 parent a29e051 commit 222a511

File tree

2 files changed

+97
-0
lines changed

2 files changed

+97
-0
lines changed

source/adapters/level_zero/usm.cpp

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
#include "logger/ur_logger.hpp"
2020
#include "ur_level_zero.hpp"
21+
#include "ur_util.hpp"
2122

2223
#include <umf_helpers.hpp>
2324

@@ -766,6 +767,97 @@ umf_result_t L0MemoryProvider::get_min_page_size(void *Ptr, size_t *PageSize) {
766767
return UMF_RESULT_SUCCESS;
767768
}
768769

770+
typedef struct ze_ipc_data_t {
771+
int pid;
772+
ze_ipc_mem_handle_t zeHandle;
773+
} ze_ipc_data_t;
774+
775+
umf_result_t L0MemoryProvider::get_ipc_handle_size(size_t *Size) {
776+
UR_ASSERT(Size, UMF_RESULT_ERROR_INVALID_ARGUMENT);
777+
*Size = sizeof(ze_ipc_data_t);
778+
779+
return UMF_RESULT_SUCCESS;
780+
}
781+
782+
umf_result_t L0MemoryProvider::get_ipc_handle(const void *Ptr, size_t Size,
783+
void *IpcData) {
784+
std::ignore = Size;
785+
786+
UR_ASSERT(Ptr && IpcData, UMF_RESULT_ERROR_INVALID_ARGUMENT);
787+
ze_ipc_data_t *zeIpcData = (ze_ipc_data_t *)IpcData;
788+
auto Ret = ZE_CALL_NOCHECK(zeMemGetIpcHandle,
789+
(Context->ZeContext, Ptr, &zeIpcData->zeHandle));
790+
if (Ret != ZE_RESULT_SUCCESS) {
791+
return UMF_RESULT_ERROR_MEMORY_PROVIDER_SPECIFIC;
792+
}
793+
794+
zeIpcData->pid = ur_getpid();
795+
796+
return UMF_RESULT_SUCCESS;
797+
}
798+
799+
umf_result_t L0MemoryProvider::put_ipc_handle(void *IpcData) {
800+
UR_ASSERT(IpcData, UMF_RESULT_ERROR_INVALID_ARGUMENT);
801+
ze_ipc_data_t *zeIpcData = (ze_ipc_data_t *)IpcData;
802+
std::ignore = zeIpcData;
803+
804+
// zeMemPutIpcHandle was introduced in Level Zero 1.6. Before Level Zero 1.6,
805+
// IPC handle was released automatically when corresponding memory buffer
806+
// was freed.
807+
#if (ZE_API_VERSION_CURRENT >= ZE_MAKE_VERSION(1, 6))
808+
auto Ret = ZE_CALL_NOCHECK(zeMemPutIpcHandle,
809+
(Context->ZeContext, zeIpcData->zeHandle));
810+
if (Ret != ZE_RESULT_SUCCESS) {
811+
return UMF_RESULT_ERROR_MEMORY_PROVIDER_SPECIFIC;
812+
}
813+
#endif
814+
815+
return UMF_RESULT_SUCCESS;
816+
}
817+
818+
umf_result_t L0MemoryProvider::open_ipc_handle(void *IpcData, void **Ptr) {
819+
UR_ASSERT(IpcData && Ptr, UMF_RESULT_ERROR_INVALID_ARGUMENT);
820+
ze_ipc_data_t *zeIpcData = (ze_ipc_data_t *)IpcData;
821+
822+
int fdLocal = -1;
823+
if (zeIpcData->pid != ur_getpid()) {
824+
int fdRemote = -1;
825+
memcpy(&fdRemote, &zeIpcData->zeHandle, sizeof(fdRemote));
826+
fdLocal = ur_duplicate_fd(zeIpcData->pid, fdRemote);
827+
if (fdLocal == -1) {
828+
logger::error("duplicating file descriptor from IPC handle failed");
829+
return UMF_RESULT_ERROR_MEMORY_PROVIDER_SPECIFIC;
830+
}
831+
832+
memcpy(&zeIpcData->zeHandle, &fdLocal, sizeof(fdLocal));
833+
}
834+
835+
auto Ret =
836+
ZE_CALL_NOCHECK(zeMemOpenIpcHandle, (Context->ZeContext, Device->ZeDevice,
837+
zeIpcData->zeHandle, 0, Ptr));
838+
if (fdLocal != -1) {
839+
ur_close_fd(fdLocal);
840+
}
841+
842+
if (Ret != ZE_RESULT_SUCCESS) {
843+
return UMF_RESULT_ERROR_MEMORY_PROVIDER_SPECIFIC;
844+
}
845+
846+
return UMF_RESULT_SUCCESS;
847+
}
848+
849+
umf_result_t L0MemoryProvider::close_ipc_handle(void *Ptr, size_t Size) {
850+
std::ignore = Size;
851+
852+
UR_ASSERT(Ptr, UMF_RESULT_ERROR_INVALID_ARGUMENT);
853+
auto Ret = ZE_CALL_NOCHECK(zeMemCloseIpcHandle, (Context->ZeContext, Ptr));
854+
if (Ret != ZE_RESULT_SUCCESS) {
855+
return UMF_RESULT_ERROR_MEMORY_PROVIDER_SPECIFIC;
856+
}
857+
858+
return UMF_RESULT_SUCCESS;
859+
}
860+
769861
ur_result_t L0SharedMemoryProvider::allocateImpl(void **ResultPtr, size_t Size,
770862
uint32_t Alignment) {
771863
return USMSharedAllocImpl(ResultPtr, Context, Device, /*host flags*/ 0,

source/adapters/level_zero/usm.hpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,11 @@ class L0MemoryProvider : public USMMemoryProviderBase {
126126
umf_result_t get_min_page_size(void *, size_t *) override;
127127
// TODO: Different name for each provider (Host/Shared/SharedRO/Device)
128128
const char *get_name() override { return "L0"; };
129+
umf_result_t get_ipc_handle_size(size_t *) override;
130+
umf_result_t get_ipc_handle(const void *, size_t, void *) override;
131+
umf_result_t put_ipc_handle(void *) override;
132+
umf_result_t open_ipc_handle(void *, void **) override;
133+
umf_result_t close_ipc_handle(void *, size_t) override;
129134
};
130135

131136
// Allocation routines for shared memory type

0 commit comments

Comments
 (0)