From abab204d6f1f9e7a3595ae6a957b677ac8d1334e Mon Sep 17 00:00:00 2001 From: "Neil R. Spruit" Date: Fri, 31 May 2024 11:05:59 -0700 Subject: [PATCH] [L0] Support for Bindless Image Import Signed-off-by: Neil R. Spruit --- source/adapters/level_zero/device.hpp | 12 +++ source/adapters/level_zero/image.cpp | 128 +++++++++++++++++++++----- 2 files changed, 116 insertions(+), 24 deletions(-) diff --git a/source/adapters/level_zero/device.hpp b/source/adapters/level_zero/device.hpp index 3cdfcbce7e..4a993fbf30 100644 --- a/source/adapters/level_zero/device.hpp +++ b/source/adapters/level_zero/device.hpp @@ -44,6 +44,18 @@ struct ze_global_memsize { uint64_t value; }; +enum ur_ze_external_memory_desc_type { + UR_ZE_EXTERNAL_OPAQUE_FD, + UR_ZE_EXTERNAL_WIN32, +}; + +struct ur_ze_external_memory_data { + void *importExtensionDesc; + ur_mem_handle_t urMemoryHandle; + enum ur_ze_external_memory_desc_type type; + size_t size; +}; + struct ur_device_handle_t_ : _ur_object { ur_device_handle_t_(ze_device_handle_t Device, ur_platform_handle_t Plt, ur_device_handle_t ParentDevice = nullptr) diff --git a/source/adapters/level_zero/image.cpp b/source/adapters/level_zero/image.cpp index 5f8396d96d..948fca00b0 100644 --- a/source/adapters/level_zero/image.cpp +++ b/source/adapters/level_zero/image.cpp @@ -947,15 +947,57 @@ UR_APIEXPORT ur_result_t UR_APICALL urBindlessImagesImportExternalMemoryExp( ur_exp_external_mem_type_t memHandleType, ur_exp_interop_mem_desc_t *pInteropMemDesc, ur_exp_interop_mem_handle_t *phInteropMem) { - std::ignore = hContext; - std::ignore = hDevice; - std::ignore = size; - std::ignore = memHandleType; - std::ignore = pInteropMemDesc; - std::ignore = phInteropMem; - logger::error(logger::LegacyMessage("[UR][L0] {} function not implemented!"), - "{} function not implemented!", __FUNCTION__); - return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; + + UR_ASSERT(hContext && hDevice, UR_RESULT_ERROR_INVALID_NULL_HANDLE); + UR_ASSERT(pInteropMemDesc && phInteropMem, + UR_RESULT_ERROR_INVALID_NULL_POINTER); + + struct ur_ze_external_memory_data *externalMemoryData = + new struct ur_ze_external_memory_data; + + void *pNext = const_cast(pInteropMemDesc->pNext); + while (pNext != nullptr) { + const ur_base_desc_t *BaseDesc = static_cast(pNext); + if (BaseDesc->stype == UR_STRUCTURE_TYPE_EXP_FILE_DESCRIPTOR) { + ze_external_memory_import_fd_t *importFd = + new ze_external_memory_import_fd_t; + importFd->stype = ZE_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMPORT_FD; + importFd->pNext = nullptr; + auto FileDescriptor = + static_cast(pNext); + importFd->fd = FileDescriptor->fd; + importFd->flags = ZE_EXTERNAL_MEMORY_TYPE_FLAG_OPAQUE_FD; + externalMemoryData->importExtensionDesc = importFd; + externalMemoryData->type = UR_ZE_EXTERNAL_OPAQUE_FD; + } else if (BaseDesc->stype == UR_STRUCTURE_TYPE_EXP_WIN32_HANDLE) { + ze_external_memory_import_win32_handle_t *importWin32 = + new ze_external_memory_import_win32_handle_t; + importWin32->stype = ZE_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMPORT_WIN32; + importWin32->pNext = nullptr; + auto Win32Handle = static_cast(pNext); + + switch (memHandleType) { + case UR_EXP_EXTERNAL_MEM_TYPE_WIN32_NT: + importWin32->flags = ZE_EXTERNAL_MEMORY_TYPE_FLAG_OPAQUE_WIN32; + break; + case UR_EXP_EXTERNAL_MEM_TYPE_WIN32_NT_DX12_RESOURCE: + importWin32->flags = ZE_EXTERNAL_MEMORY_TYPE_FLAG_D3D12_RESOURCE; + break; + case UR_EXP_EXTERNAL_MEM_TYPE_OPAQUE_FD: + default: + return UR_RESULT_ERROR_INVALID_VALUE; + } + importWin32->handle = Win32Handle->handle; + externalMemoryData->importExtensionDesc = importWin32; + externalMemoryData->type = UR_ZE_EXTERNAL_WIN32; + } + pNext = const_cast(BaseDesc->pNext); + } + externalMemoryData->size = size; + + *phInteropMem = + reinterpret_cast(externalMemoryData); + return UR_RESULT_SUCCESS; } UR_APIEXPORT ur_result_t UR_APICALL urBindlessImagesMapExternalArrayExp( @@ -963,26 +1005,64 @@ UR_APIEXPORT ur_result_t UR_APICALL urBindlessImagesMapExternalArrayExp( const ur_image_format_t *pImageFormat, const ur_image_desc_t *pImageDesc, ur_exp_interop_mem_handle_t hInteropMem, ur_exp_image_mem_handle_t *phImageMem) { - std::ignore = hContext; - std::ignore = hDevice; - std::ignore = pImageFormat; - std::ignore = pImageDesc; - std::ignore = hInteropMem; - std::ignore = phImageMem; - logger::error(logger::LegacyMessage("[UR][L0] {} function not implemented!"), - "{} function not implemented!", __FUNCTION__); - return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; + + UR_ASSERT(hContext && hDevice && hInteropMem, + UR_RESULT_ERROR_INVALID_NULL_HANDLE); + UR_ASSERT(pImageFormat && pImageDesc, UR_RESULT_ERROR_INVALID_NULL_POINTER); + + struct ur_ze_external_memory_data *externalMemoryData = + reinterpret_cast(hInteropMem); + + ze_image_bindless_exp_desc_t ZeImageBindlessDesc = {}; + ZeImageBindlessDesc.stype = ZE_STRUCTURE_TYPE_BINDLESS_IMAGE_EXP_DESC; + + ZeStruct ZeImageDesc; + UR_CALL(ur2zeImageDesc(pImageFormat, pImageDesc, ZeImageDesc)); + + ZeImageBindlessDesc.pNext = externalMemoryData->importExtensionDesc; + ZeImageBindlessDesc.flags = ZE_IMAGE_BINDLESS_EXP_FLAG_BINDLESS; + ZeImageDesc.pNext = &ZeImageBindlessDesc; + + ze_image_handle_t ZeImage; + ZE2UR_CALL(zeImageCreate, + (hContext->ZeContext, hDevice->ZeDevice, &ZeImageDesc, &ZeImage)); + ZE2UR_CALL(zeContextMakeImageResident, + (hContext->ZeContext, hDevice->ZeDevice, ZeImage)); + UR_CALL(createUrMemFromZeImage(hContext, ZeImage, /*OwnZeMemHandle*/ true, + ZeImageDesc, phImageMem)); + externalMemoryData->urMemoryHandle = + reinterpret_cast(*phImageMem); + return UR_RESULT_SUCCESS; } UR_APIEXPORT ur_result_t UR_APICALL urBindlessImagesReleaseInteropExp( ur_context_handle_t hContext, ur_device_handle_t hDevice, ur_exp_interop_mem_handle_t hInteropMem) { - std::ignore = hContext; - std::ignore = hDevice; - std::ignore = hInteropMem; - logger::error(logger::LegacyMessage("[UR][L0] {} function not implemented!"), - "{} function not implemented!", __FUNCTION__); - return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; + + UR_ASSERT(hContext && hDevice && hInteropMem, + UR_RESULT_ERROR_INVALID_NULL_HANDLE); + + struct ur_ze_external_memory_data *externalMemoryData = + reinterpret_cast(hInteropMem); + + UR_CALL(urMemRelease(externalMemoryData->urMemoryHandle)); + + switch (externalMemoryData->type) { + case UR_ZE_EXTERNAL_OPAQUE_FD: + delete (reinterpret_cast( + externalMemoryData->importExtensionDesc)); + break; + case UR_ZE_EXTERNAL_WIN32: + delete (reinterpret_cast( + externalMemoryData->importExtensionDesc)); + break; + default: + return UR_RESULT_ERROR_INVALID_VALUE; + } + + delete (externalMemoryData); + + return UR_RESULT_SUCCESS; } UR_APIEXPORT ur_result_t UR_APICALL urBindlessImagesImportExternalSemaphoreExp(