From eec1fe53021f20d51d6777a8877ca3d65b9b7ff5 Mon Sep 17 00:00:00 2001 From: "Larsen, Steffen" Date: Thu, 4 Sep 2025 05:31:51 -0700 Subject: [PATCH 01/38] [SYCL][Docs] Add sycl_ext_oneapi_inter_process_communication This commit adds a new extension for inter-process communicable SYCL object handles. As part of the initial version of this extension, only inter-process communicable memory is exposed. Signed-off-by: Larsen, Steffen --- .../llvm/SYCLLowerIR/DeviceConfigFile.td | 4 +- ...neapi_inter_process_communication.asciidoc | 189 +++++++++ .../ext/oneapi/experimental/ipc_memory.hpp | 59 +++ sycl/include/sycl/info/aspects.def | 1 + sycl/include/sycl/sycl.hpp | 1 + sycl/source/CMakeLists.txt | 1 + sycl/source/detail/device_impl.hpp | 4 + sycl/source/detail/ipc_memory_impl.hpp | 109 ++++++ .../detail/ur_device_info_ret_types.inc | 1 + sycl/source/feature_test.hpp.in | 1 + sycl/source/ipc_memory.cpp | 33 ++ sycl/test-e2e/Experimental/ipc_memory.cpp | 104 +++++ sycl/test/abi/sycl_symbols_linux.dump | 6 + sycl/test/abi/sycl_symbols_windows.dump | 14 + sycl/unittests/Extensions/CMakeLists.txt | 1 + sycl/unittests/Extensions/IPC.cpp | 213 ++++++++++ unified-runtime/include/ur_api.h | 279 +++++++++++++ unified-runtime/include/ur_api_funcs.def | 7 + unified-runtime/include/ur_ddi.h | 69 ++++ unified-runtime/include/ur_print.h | 70 ++++ unified-runtime/include/ur_print.hpp | 239 ++++++++++++ .../core/EXP-INTER-PROCESS-COMMUNICATION.rst | 71 ++++ .../core/exp-inter-process-communication.yml | 201 ++++++++++ unified-runtime/scripts/core/registry.yml | 21 + .../source/adapters/adapter.def.in | 1 + .../source/adapters/adapter.map.in | 1 + .../source/adapters/cuda/device.cpp | 7 + .../source/adapters/cuda/memory.cpp | 90 +++++ .../source/adapters/cuda/memory.hpp | 8 + .../adapters/cuda/ur_interface_loader.cpp | 19 + .../source/adapters/hip/device.cpp | 2 + .../source/adapters/hip/memory.cpp | 36 ++ .../source/adapters/hip/memory.hpp | 3 + .../adapters/hip/ur_interface_loader.cpp | 19 + .../source/adapters/level_zero/device.cpp | 2 + .../source/adapters/level_zero/memory.cpp | 95 +++++ .../source/adapters/level_zero/memory.hpp | 8 + .../level_zero/ur_interface_loader.cpp | 23 ++ .../level_zero/ur_interface_loader.hpp | 19 + .../source/adapters/level_zero/usm.hpp | 2 +- .../source/adapters/level_zero/v2/memory.cpp | 96 +++++ .../source/adapters/level_zero/v2/memory.hpp | 8 + .../source/adapters/level_zero/v2/usm.hpp | 4 +- .../source/adapters/mock/ur_mock.cpp | 1 + .../source/adapters/mock/ur_mockddi.cpp | 369 ++++++++++++++++++ .../source/adapters/native_cpu/device.cpp | 2 + .../source/adapters/native_cpu/memory.cpp | 36 ++ .../source/adapters/native_cpu/memory.hpp | 3 + .../native_cpu/ur_interface_loader.cpp | 19 + .../source/adapters/offload/memory.cpp | 36 ++ .../source/adapters/offload/memory.hpp | 3 + .../adapters/offload/ur_interface_loader.cpp | 19 + .../source/adapters/opencl/device.cpp | 2 + .../source/adapters/opencl/memory.cpp | 36 ++ .../source/adapters/opencl/memory.hpp | 3 + .../adapters/opencl/ur_interface_loader.cpp | 19 + .../loader/layers/tracing/ur_trcddi.cpp | 335 ++++++++++++++++ .../loader/layers/validation/ur_valddi.cpp | 291 ++++++++++++++ unified-runtime/source/loader/loader.def.in | 15 + unified-runtime/source/loader/loader.map.in | 15 + unified-runtime/source/loader/ur_ldrddi.cpp | 203 ++++++++++ unified-runtime/source/loader/ur_libapi.cpp | 245 ++++++++++++ unified-runtime/source/loader/ur_libddi.cpp | 5 + unified-runtime/source/loader/ur_print.cpp | 56 +++ unified-runtime/source/ur_api.cpp | 201 ++++++++++ unified-runtime/tools/urinfo/urinfo.hpp | 2 + 66 files changed, 4053 insertions(+), 4 deletions(-) create mode 100644 sycl/doc/extensions/experimental/sycl_ext_oneapi_inter_process_communication.asciidoc create mode 100644 sycl/include/sycl/ext/oneapi/experimental/ipc_memory.hpp create mode 100644 sycl/source/detail/ipc_memory_impl.hpp create mode 100644 sycl/source/ipc_memory.cpp create mode 100644 sycl/test-e2e/Experimental/ipc_memory.cpp create mode 100644 sycl/unittests/Extensions/IPC.cpp create mode 100644 unified-runtime/scripts/core/EXP-INTER-PROCESS-COMMUNICATION.rst create mode 100644 unified-runtime/scripts/core/exp-inter-process-communication.yml diff --git a/llvm/include/llvm/SYCLLowerIR/DeviceConfigFile.td b/llvm/include/llvm/SYCLLowerIR/DeviceConfigFile.td index b4f7c71af7d9f..9ad107e4874a6 100644 --- a/llvm/include/llvm/SYCLLowerIR/DeviceConfigFile.td +++ b/llvm/include/llvm/SYCLLowerIR/DeviceConfigFile.td @@ -97,6 +97,7 @@ def Aspectext_oneapi_exportable_device_mem : Aspect<"ext_oneapi_exportable_devic def Aspectext_oneapi_clock_sub_group : Aspect<"ext_oneapi_clock_sub_group">; def Aspectext_oneapi_clock_work_group : Aspect<"ext_oneapi_clock_work_group">; def Aspectext_oneapi_clock_device : Aspect<"ext_oneapi_clock_device">; +def Aspectext_oneapi_ipc_memory : Aspect<"ext_oneapi_ipc_memory">; // Deprecated aspects def AspectInt64_base_atomics : Aspect<"int64_base_atomics">; @@ -174,7 +175,8 @@ def : TargetInfo<"__TestAspectList", Aspectext_oneapi_exportable_device_mem, Aspectext_oneapi_clock_sub_group, Aspectext_oneapi_clock_work_group, - Aspectext_oneapi_clock_device], + Aspectext_oneapi_clock_device, + Aspectext_oneapi_ipc_memory], []>; // This definition serves the only purpose of testing whether the deprecated aspect list defined in here and in SYCL RT // match. diff --git a/sycl/doc/extensions/experimental/sycl_ext_oneapi_inter_process_communication.asciidoc b/sycl/doc/extensions/experimental/sycl_ext_oneapi_inter_process_communication.asciidoc new file mode 100644 index 0000000000000..16af2048f234d --- /dev/null +++ b/sycl/doc/extensions/experimental/sycl_ext_oneapi_inter_process_communication.asciidoc @@ -0,0 +1,189 @@ += sycl_ext_oneapi_inter_process_communication + +:source-highlighter: coderay +:coderay-linenums-mode: table + +// This section needs to be after the document title. +:doctype: book +:toc2: +:toc: left +:encoding: utf-8 +:lang: en +:dpcpp: pass:[DPC++] +:endnote: —{nbsp}end{nbsp}note + +// Set the default source code type in this document to C++, +// for syntax highlighting purposes. This is needed because +// docbook uses c++ and html5 uses cpp. +:language: {basebackend@docbook:c++:cpp} + + +== Notice + +[%hardbreaks] +Copyright (C) 2025 Intel Corporation. All rights reserved. + +Khronos(R) is a registered trademark and SYCL(TM) and SPIR(TM) are trademarks +of The Khronos Group Inc. OpenCL(TM) is a trademark of Apple Inc. used by +permission by Khronos. + + +== Contact + +To report problems with this extension, please open a new issue at: + +https://github.com/intel/llvm/issues + + +== Dependencies + +This extension is written against the SYCL 2020 revision 10 specification. All +references below to the "core SYCL specification" or to section numbers in the +SYCL specification refer to that revision. + + +== Status + +This is an experimental extension specification, intended to provide early +access to features and gather community feedback. Interfaces defined in this +specification are implemented in {dpcpp}, but they are not finalized and may +change incompatibly in future versions of {dpcpp} without prior notice. +*Shipping software products should not rely on APIs defined in this +specification.* + + +== Backend support status + +The APIs in this extension may be used only on a device that has +`aspect::ext_oneapi_ipc_memory`. The application must check that the device has +this aspect before submitting a kernel using any of the APIs in this +extension. If the application fails to do this, the implementation throws +a synchronous exception with the `errc::kernel_not_supported` error code +when the kernel is submitted to the queue. + + +== Overview + +This extension adds the ability for SYCL programs to share device USM memory +allocations between processes. This is done by the allocating process creating +a new `ipc_memory` object and transferring the "handle data" to the other +processes. The other processes can use the handle data to recreate the +`ipc_memory` object and get a pointer to the corresponding device USM memory. + + +== Specification + +=== Feature test macro + +This extension provides a feature-test macro as described in the core SYCL +specification. An implementation supporting this extension must predefine the +macro `SYCL_EXT_ONEAPI_IPC` to one of the values defined in the table +below. Applications can test for the existence of this macro to determine if +the implementation supports this feature, or applications can test the macro's +value to determine which of the extension's features the implementation +supports. + +_And follow the text with a table like this *unless the extension is +"experimental"*. Note that your table may have more than one row if it +has multiple versions._ + +[%header,cols="1,5"] +|=== +|Value +|Description + +|1 +|The APIs of this experimental extension are not versioned, so the + feature-test macro always has this value. +|=== + +=== Inter-process communicable memory + + +This extension adds the new `ipc_memory` class. This new class adheres to the +common reference semantics described in +https://registry.khronos.org/SYCL/specs/sycl-2020/html/sycl-2020.html#sec:reference-semantics[Section 4.5.2.] +in the SYCL 2020 specification. + +``` +namespace sycl::ext::oneapi::experimental { + +class ipc_memory { +public: + ipc_memory(void *ptr, sycl::context &ctx); + ipc_memory(span ipc_memory_handle_data, + const sycl::context &ctx, const sycl::device &dev); + + span get_handle_data() const; + + void *get_ptr() const; +}; + +} +``` + +|==== +a| +[frame=all,grid=none] +!==== +a! +[source] +---- +ipc_memory(void *ptr, const sycl::context &ctx) +---- +!==== + +_Effects:_ Constructs an IPC memory object in `ctx` from a pointer `ptr` to +device USM memory. +If `ptr` is not pointing to device USM memory, the behaviors of this constructor +and any resulting objects are undefined. + +!==== +a! +[source] +---- +ipc_memory(span ipc_memory_handle_data, + const sycl::context &ctx, const sycl::device &dev) +---- +!==== + +_Effects:_ Constructs an IPC memory object in `ctx` from the handle data +`ipc_memory_handle_data` of returned by the `get_handle_data()` member function +of another `ipc_memory` object. +The `ipc_memory` object that the handle data originated from is allowed to be +from another process on the host system. +If the `ipc_memory` object that the handle data originated from has been +destroyed, the behaviors of this constructor and any resulting objects are +undefined. +If the device USM memory the original `ipc_memory` object was created with was +not originally allocated on `dev`, the behaviors of this constructor and any +resulting objects are undefined. + +!==== +a! +[source] +---- +span get_handle_data() const +---- +!==== + +_Returns:_ The handle data of the `ipc_memory` object. +Accessing the handle data returned by this API after the `ipc_memory` object has +been destroyed results in undefined behavior. + +!==== +a! +[source] +---- +void *get_ptr() const +---- +!==== + +_Returns:_ A pointer to device USM memory corresponding to the pointer used to +construct the original `ipc_memory` object. +Accessing the pointer returned by this API after the `ipc_memory` object has +been destroyed results in undefined behavior. + +|==== + + diff --git a/sycl/include/sycl/ext/oneapi/experimental/ipc_memory.hpp b/sycl/include/sycl/ext/oneapi/experimental/ipc_memory.hpp new file mode 100644 index 0000000000000..ccb3eb7471675 --- /dev/null +++ b/sycl/include/sycl/ext/oneapi/experimental/ipc_memory.hpp @@ -0,0 +1,59 @@ +//==------- ipc_memory.hpp --- SYCL inter-process communicable memory ------==// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#pragma once + +#include +#include +#include +#include + +#include + +namespace sycl { +inline namespace _V1 { + +class context; +class device; + +namespace detail { +class ipc_memory_impl; +} + +namespace ext::oneapi::experimental { +class __SYCL_EXPORT ipc_memory + : public sycl::detail::OwnerLessBase { +public: + ipc_memory(void *Ptr, const sycl::context &Ctx); + ipc_memory(const span IPCMemoryHandleData, + const sycl::context &Ctx, const sycl::device &Dev); + + sycl::span get_handle_data() const; + + void *get_ptr() const; + +private: + ipc_memory(std::shared_ptr IPCMemImpl) + : impl{IPCMemImpl} {} + + std::shared_ptr impl; + + template + friend const decltype(Obj::impl) & + sycl::detail::getSyclObjImpl(const Obj &SyclObject); + + template + friend T sycl::detail::createSyclObjFromImpl( + std::add_rvalue_reference_t ImplObj); + template + friend T sycl::detail::createSyclObjFromImpl( + std::add_lvalue_reference_t ImplObj); +}; +} // namespace ext::oneapi::experimental +} // namespace _V1 +} // namespace sycl diff --git a/sycl/include/sycl/info/aspects.def b/sycl/include/sycl/info/aspects.def index d3e97a47a0248..f6c6b2e439bd4 100644 --- a/sycl/include/sycl/info/aspects.def +++ b/sycl/include/sycl/info/aspects.def @@ -83,3 +83,4 @@ __SYCL_ASPECT(ext_oneapi_exportable_device_mem, 90) __SYCL_ASPECT(ext_oneapi_clock_sub_group, 91) __SYCL_ASPECT(ext_oneapi_clock_work_group, 92) __SYCL_ASPECT(ext_oneapi_clock_device, 93) +__SYCL_ASPECT(ext_oneapi_ipc_memory, 94) diff --git a/sycl/include/sycl/sycl.hpp b/sycl/include/sycl/sycl.hpp index a09870dd77c30..e84dc848c42cc 100644 --- a/sycl/include/sycl/sycl.hpp +++ b/sycl/include/sycl/sycl.hpp @@ -128,6 +128,7 @@ can be disabled by setting SYCL_DISABLE_FSYCL_SYCLHPP_WARNING macro.") #include #include #include +#include #include #include #include diff --git a/sycl/source/CMakeLists.txt b/sycl/source/CMakeLists.txt index bb11518b003b0..8272d3011dba3 100644 --- a/sycl/source/CMakeLists.txt +++ b/sycl/source/CMakeLists.txt @@ -321,6 +321,7 @@ set(SYCL_COMMON_SOURCES "handler.cpp" "image.cpp" "interop_handle.cpp" + "ipc_memory.cpp" "kernel.cpp" "kernel_bundle.cpp" "physical_mem.cpp" diff --git a/sycl/source/detail/device_impl.hpp b/sycl/source/detail/device_impl.hpp index 38214254595c6..f66a92d804ef4 100644 --- a/sycl/source/detail/device_impl.hpp +++ b/sycl/source/detail/device_impl.hpp @@ -1591,6 +1591,10 @@ class device_impl : public std::enable_shared_from_this { // Will be updated in a follow-up UR patch. return false; } + CASE(ext_oneapi_ipc_memory) { + return get_info_impl_nocheck() + .value_or(0); + } else { return false; // This device aspect has not been implemented yet. } diff --git a/sycl/source/detail/ipc_memory_impl.hpp b/sycl/source/detail/ipc_memory_impl.hpp new file mode 100644 index 0000000000000..0d41ca2b699cd --- /dev/null +++ b/sycl/source/detail/ipc_memory_impl.hpp @@ -0,0 +1,109 @@ +//==-------- ipc_memory_impl.hpp --- SYCL ipc_memory implementation --------==// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#pragma once + +#include +#include +#include +#include + +#include + +namespace sycl { +inline namespace _V1 { +namespace detail { + +class ipc_memory_impl { + struct private_tag { + explicit private_tag() = default; + }; + +public: + ipc_memory_impl(void *Ptr, const sycl::context &Ctx, private_tag) + : MRelationship{HandleRelationship::Owner}, MContext{getSyclObjImpl(Ctx)}, + MPtr{Ptr} { + adapter_impl &Adapter = MContext->getAdapter(); + Adapter.call(MContext->getHandleRef(), Ptr, + &MUrHandle); + } + + ipc_memory_impl(span IPCMemoryHandleData, + const sycl::context &Ctx, const sycl::device &Dev, + private_tag) + : MRelationship{HandleRelationship::Adopted}, + MContext{getSyclObjImpl(Ctx)} { + adapter_impl &Adapter = MContext->getAdapter(); + + // First recreate the IPC handle. + ur_result_t UrRes = + Adapter.call_nocheck( + MContext->getHandleRef(), getSyclObjImpl(Dev)->getHandleRef(), + IPCMemoryHandleData.data(), IPCMemoryHandleData.size(), &MUrHandle); + if (UrRes == UR_RESULT_ERROR_INVALID_VALUE) + throw sycl::exception(sycl::make_error_code(errc::invalid), + "IPCMemoryHandleData data size does not correspond " + "to the target platform's IPC memory handle size."); + Adapter.checkUrResult(UrRes); + + // Then open it and retrieve the pointer. + Adapter.call(MContext->getHandleRef(), + MUrHandle, &MPtr); + } + + ipc_memory_impl(const ipc_memory_impl &) = delete; + ipc_memory_impl(ipc_memory_impl &&) = default; + + ~ipc_memory_impl() { + try { + adapter_impl &Adapter = MContext->getAdapter(); + if (MRelationship == HandleRelationship::Owner) { + Adapter.call_nocheck( + MContext->getHandleRef(), MUrHandle); + } else { + Adapter.call_nocheck( + MContext->getHandleRef(), MPtr); + Adapter.call_nocheck( + MContext->getHandleRef(), MUrHandle); + } + } catch (std::exception &e) { + __SYCL_REPORT_EXCEPTION_TO_STREAM("exception in ~ipc_memory_impl", e); + } + } + + ipc_memory_impl &operator=(const ipc_memory_impl &) = delete; + ipc_memory_impl &operator=(ipc_memory_impl &&) = default; + + template + static std::shared_ptr create(Ts &&...args) { + return std::make_shared(std::forward(args)..., + private_tag{}); + } + + sycl::span get_handle_data() const { + adapter_impl &Adapter = MContext->getAdapter(); + const void *HandleDataPtr = nullptr; + size_t HandleDataSize = 0; + Adapter.call( + MContext->getHandleRef(), MUrHandle, &HandleDataPtr, &HandleDataSize); + return sycl::span{ + reinterpret_cast(HandleDataPtr), HandleDataSize}; + } + + void *get_ptr() const { return MPtr; } + +private: + enum class HandleRelationship { Owner, Adopted } MRelationship; + std::shared_ptr MContext; + void *MPtr = nullptr; + ur_exp_ipc_mem_handle_t MUrHandle = nullptr; +}; + +} // namespace detail +} // namespace _V1 +} // namespace sycl \ No newline at end of file diff --git a/sycl/source/detail/ur_device_info_ret_types.inc b/sycl/source/detail/ur_device_info_ret_types.inc index e1e724262b85f..31ef440822af7 100644 --- a/sycl/source/detail/ur_device_info_ret_types.inc +++ b/sycl/source/detail/ur_device_info_ret_types.inc @@ -162,6 +162,7 @@ MAP(UR_DEVICE_INFO_NODE_MASK, uint32_t) // These aren't present in the specification, extracted from ur_api.h // instead. MAP(UR_DEVICE_INFO_2D_BLOCK_ARRAY_CAPABILITIES_EXP, ur_exp_device_2d_block_array_capability_flags_t) +MAP(UR_DEVICE_INFO_IPC_MEMORY_SUPPORT_EXP, ur_bool_t) MAP(UR_DEVICE_INFO_ASYNC_USM_ALLOCATIONS_SUPPORT_EXP, ur_bool_t) MAP(UR_DEVICE_INFO_BINDLESS_IMAGES_1D_USM_SUPPORT_EXP, ur_bool_t) MAP(UR_DEVICE_INFO_BINDLESS_IMAGES_2D_USM_SUPPORT_EXP, ur_bool_t) diff --git a/sycl/source/feature_test.hpp.in b/sycl/source/feature_test.hpp.in index a641ae79b65e6..e8ca65def3a7c 100644 --- a/sycl/source/feature_test.hpp.in +++ b/sycl/source/feature_test.hpp.in @@ -126,6 +126,7 @@ inline namespace _V1 { #define SYCL_KHR_DEFAULT_CONTEXT 1 #define SYCL_EXT_INTEL_EVENT_MODE 1 #define SYCL_EXT_ONEAPI_TANGLE 1 +#define SYCL_EXT_ONEAPI_IPC 1 // Unfinished KHR extensions. These extensions are only available if the // __DPCPP_ENABLE_UNFINISHED_KHR_EXTENSIONS macro is defined. diff --git a/sycl/source/ipc_memory.cpp b/sycl/source/ipc_memory.cpp new file mode 100644 index 0000000000000..3fc790656ee82 --- /dev/null +++ b/sycl/source/ipc_memory.cpp @@ -0,0 +1,33 @@ +//==------- ipc_memory.cpp --- SYCL inter-process communicable memory ------==// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include +#include +#include + +namespace sycl { +inline namespace _V1 { +namespace ext::oneapi::experimental { + +ipc_memory::ipc_memory(void *Ptr, const sycl::context &Ctx) + : impl(detail::ipc_memory_impl::create(Ptr, Ctx)) {} + +ipc_memory::ipc_memory( + span IPCMemoryHandleData, + const sycl::context &Ctx, const sycl::device &Dev) + : impl(detail::ipc_memory_impl::create(IPCMemoryHandleData, Ctx, Dev)) {} + +span ipc_memory::get_handle_data() const { + return impl->get_handle_data(); +} + +void *ipc_memory::get_ptr() const { return impl->get_ptr(); } + +} // namespace ext::oneapi::experimental +} // namespace _V1 +} // namespace sycl diff --git a/sycl/test-e2e/Experimental/ipc_memory.cpp b/sycl/test-e2e/Experimental/ipc_memory.cpp new file mode 100644 index 0000000000000..31d2cdb03e37c --- /dev/null +++ b/sycl/test-e2e/Experimental/ipc_memory.cpp @@ -0,0 +1,104 @@ +// REQUIRES: aspect-usm_device_allocations && aspect-ext_oneapi_ipc_memory + +// RUN: %{build} -o %t.out +// RUN: %{run} %t.out + +#include +#include +#include + +#include +#include +#include + +namespace syclexp = sycl::ext::oneapi::experimental; + +constexpr size_t N = 32; +constexpr const char *CommsFile = "ipc_comms.txt"; + +int spawner(int argc, char *argv[]) { + assert(argc == 1); + sycl::queue Q; + + int *DataPtr = sycl::malloc_device(N, Q); + Q.parallel_for(N, [=](sycl::item<1> I) { + DataPtr[I] = static_cast(I.get_linear_id()); + }).wait(); + + { + syclexp::ipc_memory IPCMem{DataPtr, Q.get_context()}; + assert(IPCMem.get_ptr() == DataPtr); + + // Write handle data to file. + { + sycl::span HandleData = + IPCMem.get_handle_data(); + size_t HandleDataSize = HandleData.size(); + std::fstream FS(CommsFile, std::ios_base::out | std::ios_base::binary); + FS.write(reinterpret_cast(&HandleDataSize), sizeof(size_t)); + FS.write(HandleData.data(), HandleDataSize); + } + + // Spawn other process with an arguement. + std::string Cmd = std::string{argv[0]} + " 1"; + std::cout << "Spawning: " << Cmd << std::endl; + std::system(Cmd.c_str()); + } + + int Failures = 0; + int Read[N] = {0}; + Q.copy(DataPtr, Read, N).wait(); + for (size_t I = 0; I < N; ++I) { + if (Read[I] != (N - I)) { + ++Failures; + std::cout << "Failed from spawner: Result at " << I + << " unexpected: " << Read[I] << " != " << (N - I) << std::endl; + } + } + sycl::free(DataPtr, Q); + return Failures; +} + +int consumer() { + sycl::queue Q; + + // Read the handle data. + std::fstream FS(CommsFile, std::ios_base::in | std::ios_base::binary); + size_t HandleSize = 0; + FS.read(reinterpret_cast(&HandleSize), sizeof(size_t)); + std::unique_ptr HandleData{new char[HandleSize]}; + FS.read(HandleData.get(), HandleSize); + + // Re-create the IPC handle. + sycl::span Handle{HandleData.get(), + HandleSize}; + syclexp::ipc_memory IPCMem{Handle, Q.get_context(), Q.get_device()}; + int *DataPtr = reinterpret_cast(IPCMem.get_ptr()); + + // Test the data already in the USM pointer. + // TODO: This is currently disabled for L0 due to a bug in the original data + // after opening an IPC handle. + int Failures = 0; + if (Q.get_backend() != sycl::backend::ext_oneapi_level_zero) { + int Read[N] = {0}; + Q.copy(DataPtr, Read, N).wait(); + for (size_t I = 0; I < N; ++I) { + if (Read[I] != I) { + ++Failures; + std::cout << "Failed from consumer: Result at " << I + << " unexpected: " << Read[I] << " != " << I << std::endl; + } + } + } + + Q.parallel_for(N, [=](sycl::item<1> I) { + DataPtr[I] = static_cast(N - I.get_linear_id()); + }).wait(); + + return Failures; +} + +int main(int argc, char *argv[]) { + // We either have the spawner (if no extra argument it provided) or + return argc == 1 ? spawner(argc, argv) : consumer(); +} diff --git a/sycl/test/abi/sycl_symbols_linux.dump b/sycl/test/abi/sycl_symbols_linux.dump index e9f65ce662488..f5b010fb15769 100644 --- a/sycl/test/abi/sycl_symbols_linux.dump +++ b/sycl/test/abi/sycl_symbols_linux.dump @@ -2991,6 +2991,10 @@ _ZN4sycl3_V13ext5intel12experimental9pipe_base18get_pipe_name_implEPKv _ZN4sycl3_V13ext6oneapi10level_zero6detail11make_deviceERKNS0_8platformEm _ZN4sycl3_V13ext6oneapi12experimental10async_freeERKNS0_5queueEPvRKNS0_6detail13code_locationE _ZN4sycl3_V13ext6oneapi12experimental10async_freeERNS0_7handlerEPv +_ZN4sycl3_V13ext6oneapi12experimental10ipc_memoryC1ENS0_4spanIKcLm18446744073709551615EEERKNS0_7contextERKNS0_6deviceE +_ZN4sycl3_V13ext6oneapi12experimental10ipc_memoryC1EPvRKNS0_7contextE +_ZN4sycl3_V13ext6oneapi12experimental10ipc_memoryC2ENS0_4spanIKcLm18446744073709551615EEERKNS0_7contextERKNS0_6deviceE +_ZN4sycl3_V13ext6oneapi12experimental10ipc_memoryC2EPvRKNS0_7contextE _ZN4sycl3_V13ext6oneapi12experimental10mem_adviseENS0_5queueEPvmiRKNS0_6detail13code_locationE _ZN4sycl3_V13ext6oneapi12experimental11memory_pool21increase_threshold_toEm _ZN4sycl3_V13ext6oneapi12experimental11memory_poolC1ERKNS0_7contextERKNS0_6deviceENS0_3usm5allocENS4_15pool_propertiesE @@ -3691,6 +3695,8 @@ _ZNK4sycl3_V114interop_handle22ext_codeplay_has_graphEv _ZNK4sycl3_V115device_selector13select_deviceEv _ZNK4sycl3_V116default_selectorclERKNS0_6deviceE _ZNK4sycl3_V120accelerator_selectorclERKNS0_6deviceE +_ZNK4sycl3_V13ext6oneapi12experimental10ipc_memory7get_ptrEv +_ZNK4sycl3_V13ext6oneapi12experimental10ipc_memory15get_handle_dataEv _ZNK4sycl3_V13ext6oneapi12experimental11memory_pool10get_deviceEv _ZNK4sycl3_V13ext6oneapi12experimental11memory_pool11get_contextEv _ZNK4sycl3_V13ext6oneapi12experimental11memory_pool13get_thresholdEv diff --git a/sycl/test/abi/sycl_symbols_windows.dump b/sycl/test/abi/sycl_symbols_windows.dump index b3453854edec8..a3e5e90386e8d 100644 --- a/sycl/test/abi/sycl_symbols_windows.dump +++ b/sycl/test/abi/sycl_symbols_windows.dump @@ -447,6 +447,11 @@ ??0image_plain@detail@_V1@sycl@@IEAA@_KAEBVcontext@23@Vevent@23@V?$unique_ptr@VSYCLMemObjAllocator@detail@_V1@sycl@@U?$default_delete@VSYCLMemObjAllocator@detail@_V1@sycl@@@std@@@std@@EW4image_channel_order@23@W4image_channel_type@23@_NV?$range@$02@23@@Z ??0image_plain@detail@_V1@sycl@@QEAA@$$QEAV0123@@Z ??0image_plain@detail@_V1@sycl@@QEAA@AEBV0123@@Z +??0ipc_memory@experimental@oneapi@ext@_V1@sycl@@QEAA@AEBV012345@@Z +??0ipc_memory@experimental@oneapi@ext@_V1@sycl@@QEAA@PEAXAEBVcontext@45@@Z +??0ipc_memory@experimental@oneapi@ext@_V1@sycl@@AEAA@V?$shared_ptr@Vipc_memory_impl@detail@_V1@sycl@@@std@@@Z +??0ipc_memory@experimental@oneapi@ext@_V1@sycl@@QEAA@V?$span@$$CBD$0?0@45@AEBVcontext@45@AEBVdevice@45@@Z +??0ipc_memory@experimental@oneapi@ext@_V1@sycl@@QEAA@$$QEAV012345@@Z ??0kernel@_V1@sycl@@AEAA@V?$shared_ptr@Vkernel_impl@detail@_V1@sycl@@@std@@@Z ??0kernel@_V1@sycl@@QEAA@$$QEAV012@@Z ??0kernel@_V1@sycl@@QEAA@AEBV012@@Z @@ -537,6 +542,7 @@ ??1image_mem@experimental@oneapi@ext@_V1@sycl@@QEAA@XZ ??1image_mem_impl@detail@experimental@oneapi@ext@_V1@sycl@@QEAA@XZ ??1image_plain@detail@_V1@sycl@@QEAA@XZ +??1ipc_memory@experimental@oneapi@ext@_V1@sycl@@QEAA@XZ ??1kernel@_V1@sycl@@QEAA@XZ ??1kernel_bundle_plain@detail@_V1@sycl@@QEAA@XZ ??1kernel_id@_V1@sycl@@QEAA@XZ @@ -557,6 +563,8 @@ ??4?$OwnerLessBase@Vevent@_V1@sycl@@@detail@_V1@sycl@@QEAAAEAV0123@AEBV0123@@Z ??4?$OwnerLessBase@Vexecutable_command_graph@detail@experimental@oneapi@ext@_V1@sycl@@@detail@_V1@sycl@@QEAAAEAV0123@$$QEAV0123@@Z ??4?$OwnerLessBase@Vexecutable_command_graph@detail@experimental@oneapi@ext@_V1@sycl@@@detail@_V1@sycl@@QEAAAEAV0123@AEBV0123@@Z +??4?$OwnerLessBase@Vipc_memory@experimental@oneapi@ext@_V1@sycl@@@detail@_V1@sycl@@QEAAAEAV0123@AEBV0123@@Z +??4?$OwnerLessBase@Vipc_memory@experimental@oneapi@ext@_V1@sycl@@@detail@_V1@sycl@@QEAAAEAV0123@$$QEAV0123@@Z ??4?$OwnerLessBase@Vkernel@_V1@sycl@@@detail@_V1@sycl@@QEAAAEAV0123@$$QEAV0123@@Z ??4?$OwnerLessBase@Vkernel@_V1@sycl@@@detail@_V1@sycl@@QEAAAEAV0123@AEBV0123@@Z ??4?$OwnerLessBase@Vkernel_id@_V1@sycl@@@detail@_V1@sycl@@QEAAAEAV0123@$$QEAV0123@@Z @@ -635,6 +643,8 @@ ??4image_mem@experimental@oneapi@ext@_V1@sycl@@QEAAAEAV012345@AEBV012345@@Z ??4image_plain@detail@_V1@sycl@@QEAAAEAV0123@$$QEAV0123@@Z ??4image_plain@detail@_V1@sycl@@QEAAAEAV0123@AEBV0123@@Z +??4ipc_memory@experimental@oneapi@ext@_V1@sycl@@QEAAAEAV012345@AEBV012345@@Z +??4ipc_memory@experimental@oneapi@ext@_V1@sycl@@QEAAAEAV012345@$$QEAV012345@@Z ??4kernel@_V1@sycl@@QEAAAEAV012@$$QEAV012@@Z ??4kernel@_V1@sycl@@QEAAAEAV012@AEBV012@@Z ??4kernel_bundle_plain@detail@_V1@sycl@@QEAAAEAV0123@$$QEAV0123@@Z @@ -3984,6 +3994,8 @@ ?ext_oneapi_owner_before@?$OwnerLessBase@Vevent@_V1@sycl@@@detail@_V1@sycl@@QEBA_NAEBVevent@34@@Z ?ext_oneapi_owner_before@?$OwnerLessBase@Vexecutable_command_graph@detail@experimental@oneapi@ext@_V1@sycl@@@detail@_V1@sycl@@QEBA_NAEBV?$weak_object_base@Vexecutable_command_graph@detail@experimental@oneapi@ext@_V1@sycl@@@2oneapi@ext@34@@Z ?ext_oneapi_owner_before@?$OwnerLessBase@Vexecutable_command_graph@detail@experimental@oneapi@ext@_V1@sycl@@@detail@_V1@sycl@@QEBA_NAEBVexecutable_command_graph@2experimental@oneapi@ext@34@@Z +?ext_oneapi_owner_before@?$OwnerLessBase@Vipc_memory@experimental@oneapi@ext@_V1@sycl@@@detail@_V1@sycl@@QEBA_NAEBV?$weak_object_base@Vipc_memory@experimental@oneapi@ext@_V1@sycl@@@2oneapi@ext@34@@Z +?ext_oneapi_owner_before@?$OwnerLessBase@Vipc_memory@experimental@oneapi@ext@_V1@sycl@@@detail@_V1@sycl@@QEBA_NAEBVipc_memory@experimental@oneapi@ext@34@@Z ?ext_oneapi_owner_before@?$OwnerLessBase@Vkernel@_V1@sycl@@@detail@_V1@sycl@@QEBA_NAEBV?$weak_object_base@Vkernel@_V1@sycl@@@2oneapi@ext@34@@Z ?ext_oneapi_owner_before@?$OwnerLessBase@Vkernel@_V1@sycl@@@detail@_V1@sycl@@QEBA_NAEBVkernel@34@@Z ?ext_oneapi_owner_before@?$OwnerLessBase@Vkernel_id@_V1@sycl@@@detail@_V1@sycl@@QEBA_NAEBV?$weak_object_base@Vkernel_id@_V1@sycl@@@2oneapi@ext@34@@Z @@ -4177,6 +4189,7 @@ ?get_empty_interop_kernel_bundle_impl@detail@_V1@sycl@@YA?AV?$shared_ptr@Vkernel_bundle_impl@detail@_V1@sycl@@@std@@AEBVcontext@23@AEBV?$vector@Vdevice@_V1@sycl@@V?$allocator@Vdevice@_V1@sycl@@@std@@@5@@Z ?get_filtering_mode@sampler@_V1@sycl@@QEBA?AW4filtering_mode@23@XZ ?get_flags@stream@_V1@sycl@@AEBAIXZ +?get_handle_data@ipc_memory@experimental@oneapi@ext@_V1@sycl@@QEBA?AV?$span@$$CBD$0?0@56@XZ ?get_handle@image_mem@experimental@oneapi@ext@_V1@sycl@@QEBA?AUimage_mem_handle@23456@XZ ?get_image_channel_type@experimental@oneapi@ext@_V1@sycl@@YA?AW4image_channel_type@45@Uimage_mem_handle@12345@AEBVdevice@45@AEBVcontext@45@@Z ?get_image_channel_type@experimental@oneapi@ext@_V1@sycl@@YA?AW4image_channel_type@45@Uimage_mem_handle@12345@AEBVqueue@45@@Z @@ -4217,6 +4230,7 @@ ?get_pointer_type@detail@_V1@sycl@@YA?AW4alloc@usm@23@PEBXAEAVcontext_impl@123@@Z ?get_precision@stream@_V1@sycl@@QEBA_KXZ ?get_predecessors@node@experimental@oneapi@ext@_V1@sycl@@QEBA?AV?$vector@Vnode@experimental@oneapi@ext@_V1@sycl@@V?$allocator@Vnode@experimental@oneapi@ext@_V1@sycl@@@std@@@std@@XZ +?get_ptr@ipc_memory@experimental@oneapi@ext@_V1@sycl@@QEBAPEAXXZ ?get_queue@fusion_wrapper@experimental@codeplay@ext@_V1@sycl@@QEBA?AVqueue@56@XZ ?get_range@image_mem@experimental@oneapi@ext@_V1@sycl@@QEBA?AV?$range@$02@56@XZ ?get_range@image_plain@detail@_V1@sycl@@IEBA?AV?$range@$02@34@XZ diff --git a/sycl/unittests/Extensions/CMakeLists.txt b/sycl/unittests/Extensions/CMakeLists.txt index 59d57f0851ec1..3b3faf110bdbc 100644 --- a/sycl/unittests/Extensions/CMakeLists.txt +++ b/sycl/unittests/Extensions/CMakeLists.txt @@ -24,6 +24,7 @@ add_sycl_unittest(ExtensionsTests OBJECT DeviceInfo.cpp RootGroup.cpp USMPrefetch.cpp + IPC.cpp ) add_subdirectory(CommandGraph) diff --git a/sycl/unittests/Extensions/IPC.cpp b/sycl/unittests/Extensions/IPC.cpp new file mode 100644 index 0000000000000..c650c3ed83163 --- /dev/null +++ b/sycl/unittests/Extensions/IPC.cpp @@ -0,0 +1,213 @@ +//==------------------------------ IPC.cpp ---------------------------------==// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include + +#include +#include +#include +#include +#include + +namespace syclexp = sycl::ext::oneapi::experimental; + +namespace { + +int DummyInt1 = 42; +void *DummyPtr = &DummyInt1; + +int DummyInt2 = 24; +ur_exp_ipc_mem_handle_t DummyMemHandle = + reinterpret_cast(&DummyInt2); + +constexpr size_t DummyHandleDataSize = 10; +char DummyHandleData[DummyHandleDataSize] = {9, 8, 7, 6, 5, 4, 3, 2, 1}; + +thread_local int urIPCGetMemHandleExp_counter = 0; +thread_local int urIPCPutMemHandleExp_counter = 0; +thread_local int urIPCOpenMemHandleExp_counter = 0; +thread_local int urIPCCloseMemHandleExp_counter = 0; +thread_local int urIPCCreateMemHandleFromDataExp_counter = 0; +thread_local int urIPCDestroyMemHandleExp_counter = 0; +thread_local int urIPCGetMemHandleDataExp_counter = 0; + +ur_result_t replace_urIPCGetMemHandleExp(void *pParams) { + ++urIPCGetMemHandleExp_counter; + auto params = *static_cast(pParams); + EXPECT_EQ(*params.ppMem, DummyPtr); + **params.pphIPCMem = DummyMemHandle; + return UR_RESULT_SUCCESS; +} + +ur_result_t replace_urIPCPutMemHandleExp(void *pParams) { + ++urIPCPutMemHandleExp_counter; + auto params = *static_cast(pParams); + EXPECT_EQ(*params.phIPCMem, DummyMemHandle); + return UR_RESULT_SUCCESS; +} + +ur_result_t replace_urIPCOpenMemHandleExp(void *pParams) { + ++urIPCOpenMemHandleExp_counter; + auto params = *static_cast(pParams); + EXPECT_EQ(*params.phIPCMem, DummyMemHandle); + **params.pppMem = DummyPtr; + return UR_RESULT_SUCCESS; +} + +ur_result_t replace_urIPCCloseMemHandleExp(void *pParams) { + ++urIPCCloseMemHandleExp_counter; + auto params = *static_cast(pParams); + EXPECT_EQ(*params.ppMem, DummyPtr); + return UR_RESULT_SUCCESS; +} + +ur_result_t replace_urIPCCreateMemHandleFromDataExp(void *pParams) { + ++urIPCCreateMemHandleFromDataExp_counter; + auto params = + *static_cast(pParams); + EXPECT_EQ(*params.pipcMemHandleData, DummyHandleData); + EXPECT_EQ(*params.pipcMemHandleDataSize, DummyHandleDataSize); + **params.pphIPCMem = DummyMemHandle; + return UR_RESULT_SUCCESS; +} + +ur_result_t replace_urIPCDestroyMemHandleExp(void *pParams) { + ++urIPCDestroyMemHandleExp_counter; + auto params = *static_cast(pParams); + EXPECT_EQ(*params.phIPCMem, DummyMemHandle); + return UR_RESULT_SUCCESS; +} + +ur_result_t replace_urIPCGetMemHandleDataExp(void *pParams) { + ++urIPCGetMemHandleDataExp_counter; + auto params = + *static_cast(pParams); + EXPECT_EQ(*params.phIPCMem, DummyMemHandle); + **params.pppIPCHandleData = DummyHandleData; + **params.ppIPCMemHandleDataSizeRet = DummyHandleDataSize; + return UR_RESULT_SUCCESS; +} + +class IPCTests : public ::testing::Test { +public: + IPCTests() : Mock{}, Ctxt(sycl::platform()) {} + +protected: + void SetUp() override { + urIPCGetMemHandleExp_counter = 0; + urIPCPutMemHandleExp_counter = 0; + urIPCOpenMemHandleExp_counter = 0; + urIPCCloseMemHandleExp_counter = 0; + urIPCCreateMemHandleFromDataExp_counter = 0; + urIPCDestroyMemHandleExp_counter = 0; + urIPCGetMemHandleDataExp_counter = 0; + + mock::getCallbacks().set_replace_callback("urIPCGetMemHandleExp", + replace_urIPCGetMemHandleExp); + mock::getCallbacks().set_replace_callback("urIPCPutMemHandleExp", + replace_urIPCPutMemHandleExp); + mock::getCallbacks().set_replace_callback("urIPCOpenMemHandleExp", + replace_urIPCOpenMemHandleExp); + mock::getCallbacks().set_replace_callback("urIPCCloseMemHandleExp", + replace_urIPCCloseMemHandleExp); + mock::getCallbacks().set_replace_callback( + "urIPCCreateMemHandleFromDataExp", + replace_urIPCCreateMemHandleFromDataExp); + mock::getCallbacks().set_replace_callback("urIPCDestroyMemHandleExp", + replace_urIPCDestroyMemHandleExp); + mock::getCallbacks().set_replace_callback("urIPCGetMemHandleDataExp", + replace_urIPCGetMemHandleDataExp); + } + + sycl::unittest::UrMock<> Mock; + sycl::context Ctxt; +}; + +TEST_F(IPCTests, IPCGetPut) { + { + syclexp::ipc_memory IPCMem{DummyPtr, Ctxt}; + + // Creating the IPC memory from a pointer should only call "get". + EXPECT_EQ(urIPCGetMemHandleExp_counter, 1); + EXPECT_EQ(urIPCPutMemHandleExp_counter, 0); + EXPECT_EQ(urIPCOpenMemHandleExp_counter, 0); + EXPECT_EQ(urIPCCloseMemHandleExp_counter, 0); + EXPECT_EQ(urIPCCreateMemHandleFromDataExp_counter, 0); + EXPECT_EQ(urIPCDestroyMemHandleExp_counter, 0); + EXPECT_EQ(urIPCGetMemHandleDataExp_counter, 0); + + sycl::span IPCMemHandleData = + IPCMem.get_handle_data(); + EXPECT_EQ(IPCMemHandleData.data(), DummyHandleData); + EXPECT_EQ(IPCMemHandleData.size(), DummyHandleDataSize); + + // Getting the underlying data should call the backend. + EXPECT_EQ(urIPCGetMemHandleExp_counter, 1); + EXPECT_EQ(urIPCPutMemHandleExp_counter, 0); + EXPECT_EQ(urIPCOpenMemHandleExp_counter, 0); + EXPECT_EQ(urIPCCloseMemHandleExp_counter, 0); + EXPECT_EQ(urIPCCreateMemHandleFromDataExp_counter, 0); + EXPECT_EQ(urIPCDestroyMemHandleExp_counter, 0); + EXPECT_EQ(urIPCGetMemHandleDataExp_counter, 1); + } + + // When the IPC memory object dies, it should return the handle, calling + // "put". + EXPECT_EQ(urIPCGetMemHandleExp_counter, 1); + EXPECT_EQ(urIPCPutMemHandleExp_counter, 1); + EXPECT_EQ(urIPCOpenMemHandleExp_counter, 0); + EXPECT_EQ(urIPCCloseMemHandleExp_counter, 0); + EXPECT_EQ(urIPCCreateMemHandleFromDataExp_counter, 0); + EXPECT_EQ(urIPCDestroyMemHandleExp_counter, 0); + EXPECT_EQ(urIPCGetMemHandleDataExp_counter, 1); +} + +TEST_F(IPCTests, IPCOpenClose) { + { + sycl::span HandleData{ + DummyHandleData, DummyHandleDataSize}; + syclexp::ipc_memory IPCMem{HandleData, Ctxt, Ctxt.get_devices()[0]}; + EXPECT_EQ(IPCMem.get_ptr(), DummyPtr); + + // Creating the IPC memory from handle data should first re-create the + // handle and then call open on it. + EXPECT_EQ(urIPCGetMemHandleExp_counter, 0); + EXPECT_EQ(urIPCPutMemHandleExp_counter, 0); + EXPECT_EQ(urIPCOpenMemHandleExp_counter, 1); + EXPECT_EQ(urIPCCloseMemHandleExp_counter, 0); + EXPECT_EQ(urIPCCreateMemHandleFromDataExp_counter, 1); + EXPECT_EQ(urIPCDestroyMemHandleExp_counter, 0); + EXPECT_EQ(urIPCGetMemHandleDataExp_counter, 0); + + sycl::span IPCMemHandleData = + IPCMem.get_handle_data(); + EXPECT_EQ(IPCMemHandleData.data(), DummyHandleData); + EXPECT_EQ(IPCMemHandleData.size(), DummyHandleDataSize); + + // Getting the underlying data should call the backend. + EXPECT_EQ(urIPCGetMemHandleExp_counter, 0); + EXPECT_EQ(urIPCPutMemHandleExp_counter, 0); + EXPECT_EQ(urIPCOpenMemHandleExp_counter, 1); + EXPECT_EQ(urIPCCloseMemHandleExp_counter, 0); + EXPECT_EQ(urIPCCreateMemHandleFromDataExp_counter, 1); + EXPECT_EQ(urIPCDestroyMemHandleExp_counter, 0); + EXPECT_EQ(urIPCGetMemHandleDataExp_counter, 1); + } + + // When the IPC memory object dies, it should release the handle, calling + // "close" and then destroying it. + EXPECT_EQ(urIPCGetMemHandleExp_counter, 0); + EXPECT_EQ(urIPCPutMemHandleExp_counter, 0); + EXPECT_EQ(urIPCOpenMemHandleExp_counter, 1); + EXPECT_EQ(urIPCCloseMemHandleExp_counter, 1); + EXPECT_EQ(urIPCCreateMemHandleFromDataExp_counter, 1); + EXPECT_EQ(urIPCDestroyMemHandleExp_counter, 1); + EXPECT_EQ(urIPCGetMemHandleDataExp_counter, 1); +} + +} // namespace diff --git a/unified-runtime/include/ur_api.h b/unified-runtime/include/ur_api.h index f78714b4e06aa..f45aec5bc2edc 100644 --- a/unified-runtime/include/ur_api.h +++ b/unified-runtime/include/ur_api.h @@ -475,6 +475,20 @@ typedef enum ur_function_t { UR_FUNCTION_MEMORY_EXPORT_EXPORT_MEMORY_HANDLE_EXP = 287, /// Enumerator for ::urBindlessImagesSupportsImportingHandleTypeExp UR_FUNCTION_BINDLESS_IMAGES_SUPPORTS_IMPORTING_HANDLE_TYPE_EXP = 288, + /// Enumerator for ::urIPCGetMemHandleExp + UR_FUNCTION_IPC_GET_MEM_HANDLE_EXP = 289, + /// Enumerator for ::urIPCPutMemHandleExp + UR_FUNCTION_IPC_PUT_MEM_HANDLE_EXP = 290, + /// Enumerator for ::urIPCOpenMemHandleExp + UR_FUNCTION_IPC_OPEN_MEM_HANDLE_EXP = 291, + /// Enumerator for ::urIPCCloseMemHandleExp + UR_FUNCTION_IPC_CLOSE_MEM_HANDLE_EXP = 292, + /// Enumerator for ::urIPCGetMemHandleDataExp + UR_FUNCTION_IPC_GET_MEM_HANDLE_DATA_EXP = 293, + /// Enumerator for ::urIPCCreateMemHandleFromDataExp + UR_FUNCTION_IPC_CREATE_MEM_HANDLE_FROM_DATA_EXP = 294, + /// Enumerator for ::urIPCDestroyMemHandleExp + UR_FUNCTION_IPC_DESTROY_MEM_HANDLE_EXP = 295, /// @cond UR_FUNCTION_FORCE_UINT32 = 0x7fffffff /// @endcond @@ -2426,6 +2440,9 @@ typedef enum ur_device_info_t { /// [::ur_exp_device_2d_block_array_capability_flags_t] return a bit-field /// of Intel GPU 2D block array capabilities UR_DEVICE_INFO_2D_BLOCK_ARRAY_CAPABILITIES_EXP = 0x2022, + /// [::ur_bool_t] returns true if the device supports inter-process + /// communicable memory handles + UR_DEVICE_INFO_IPC_MEMORY_SUPPORT_EXP = 0x2023, /// [::ur_bool_t] returns true if the device supports enqueueing of /// allocations and frees. UR_DEVICE_INFO_ASYNC_USM_ALLOCATIONS_SUPPORT_EXP = 0x2050, @@ -12347,6 +12364,198 @@ UR_APIEXPORT ur_result_t UR_APICALL urEnqueueTimestampRecordingExp( /// array. ur_event_handle_t *phEvent); +#if !defined(__GNUC__) +#pragma endregion +#endif +// Intel 'oneAPI' Unified Runtime Experimental APIs for Inter Process +// Communication +#if !defined(__GNUC__) +#pragma region inter_process_communication_(experimental) +#endif +/////////////////////////////////////////////////////////////////////////////// +/// @brief Handle of inter-process communicable memory +typedef struct ur_exp_ipc_mem_handle_t_ *ur_exp_ipc_mem_handle_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Gets an inter-process memory handle for a pointer to device USM +/// memory +/// +/// @returns +/// - ::UR_RESULT_SUCCESS +/// - ::UR_RESULT_ERROR_UNINITIALIZED +/// - ::UR_RESULT_ERROR_DEVICE_LOST +/// - ::UR_RESULT_ERROR_ADAPTER_SPECIFIC +/// - ::UR_RESULT_ERROR_INVALID_NULL_HANDLE +/// + `NULL == hContext` +/// + NULL == hContext +/// - ::UR_RESULT_ERROR_INVALID_NULL_POINTER +/// + `NULL == phIPCMem` +/// + NULL == phIPCMem +/// - ::UR_RESULT_ERROR_INVALID_CONTEXT +/// - ::UR_RESULT_ERROR_OUT_OF_HOST_MEMORY +/// - ::UR_RESULT_ERROR_OUT_OF_RESOURCES +UR_APIEXPORT ur_result_t UR_APICALL urIPCGetMemHandleExp( + /// [in] handle of the context object + ur_context_handle_t hContext, + /// [in] pointer to device USM memory + void *pMem, + /// [out][alloc] pointer to the resulting IPC memory handle + ur_exp_ipc_mem_handle_t *phIPCMem); + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Releases an inter-process memory handle +/// +/// @returns +/// - ::UR_RESULT_SUCCESS +/// - ::UR_RESULT_ERROR_UNINITIALIZED +/// - ::UR_RESULT_ERROR_DEVICE_LOST +/// - ::UR_RESULT_ERROR_ADAPTER_SPECIFIC +/// - ::UR_RESULT_ERROR_INVALID_NULL_HANDLE +/// + `NULL == hContext` +/// + NULL == hContext +/// + NULL == hIPCMem +/// - ::UR_RESULT_ERROR_INVALID_CONTEXT +/// - ::UR_RESULT_ERROR_OUT_OF_HOST_MEMORY +/// - ::UR_RESULT_ERROR_OUT_OF_RESOURCES +UR_APIEXPORT ur_result_t UR_APICALL urIPCPutMemHandleExp( + /// [in] handle of the context object + ur_context_handle_t hContext, + /// [in] the IPC memory handle + ur_exp_ipc_mem_handle_t hIPCMem); + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Opens an inter-process memory handle to get the corresponding pointer +/// to device USM memory +/// +/// @returns +/// - ::UR_RESULT_SUCCESS +/// - ::UR_RESULT_ERROR_UNINITIALIZED +/// - ::UR_RESULT_ERROR_DEVICE_LOST +/// - ::UR_RESULT_ERROR_ADAPTER_SPECIFIC +/// - ::UR_RESULT_ERROR_INVALID_NULL_HANDLE +/// + `NULL == hContext` +/// + NULL == hContext +/// + NULL == hIPCMem +/// - ::UR_RESULT_ERROR_INVALID_CONTEXT +/// - ::UR_RESULT_ERROR_INVALID_NULL_POINTER +/// + NULL == ppMem +/// - ::UR_RESULT_ERROR_OUT_OF_HOST_MEMORY +/// - ::UR_RESULT_ERROR_OUT_OF_RESOURCES +UR_APIEXPORT ur_result_t UR_APICALL urIPCOpenMemHandleExp( + /// [in] handle of the context object + ur_context_handle_t hContext, + /// [in] pointer to the resulting IPC memory handle + ur_exp_ipc_mem_handle_t hIPCMem, + /// [out] pointer to a pointer to device USM memory + void **ppMem); + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Closes an inter-process memory handle +/// +/// @returns +/// - ::UR_RESULT_SUCCESS +/// - ::UR_RESULT_ERROR_UNINITIALIZED +/// - ::UR_RESULT_ERROR_DEVICE_LOST +/// - ::UR_RESULT_ERROR_ADAPTER_SPECIFIC +/// - ::UR_RESULT_ERROR_INVALID_NULL_HANDLE +/// + `NULL == hContext` +/// + NULL == hContext +/// - ::UR_RESULT_ERROR_INVALID_CONTEXT +/// - ::UR_RESULT_ERROR_INVALID_NULL_POINTER +/// + NULL == pMem +/// - ::UR_RESULT_ERROR_OUT_OF_HOST_MEMORY +/// - ::UR_RESULT_ERROR_OUT_OF_RESOURCES +UR_APIEXPORT ur_result_t UR_APICALL urIPCCloseMemHandleExp( + /// [in] handle of the context object + ur_context_handle_t hContext, + /// [in] pointer to device USM memory opened through urIPCOpenMemHandleExp + void *pMem); + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Gets the data of an inter-process memory handle +/// +/// @returns +/// - ::UR_RESULT_SUCCESS +/// - ::UR_RESULT_ERROR_UNINITIALIZED +/// - ::UR_RESULT_ERROR_DEVICE_LOST +/// - ::UR_RESULT_ERROR_ADAPTER_SPECIFIC +/// - ::UR_RESULT_ERROR_INVALID_NULL_HANDLE +/// + `NULL == hContext` +/// + NULL == hContext +/// + NULL == hIPCMem +/// - ::UR_RESULT_ERROR_INVALID_CONTEXT +/// - ::UR_RESULT_ERROR_OUT_OF_HOST_MEMORY +/// - ::UR_RESULT_ERROR_OUT_OF_RESOURCES +UR_APIEXPORT ur_result_t UR_APICALL urIPCGetMemHandleDataExp( + /// [in] handle of the context object + ur_context_handle_t hContext, + /// [in] the IPC memory handle + ur_exp_ipc_mem_handle_t hIPCMem, + /// [out][optional] a pointer to the IPC memory handle data + const void **ppIPCHandleData, + /// [out][optional] size of the resulting IPC memory handle data + size_t *pIPCMemHandleDataSizeRet); + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Creates an inter-process memory handle from handle data +/// +/// @returns +/// - ::UR_RESULT_SUCCESS +/// - ::UR_RESULT_ERROR_UNINITIALIZED +/// - ::UR_RESULT_ERROR_DEVICE_LOST +/// - ::UR_RESULT_ERROR_ADAPTER_SPECIFIC +/// - ::UR_RESULT_ERROR_INVALID_NULL_HANDLE +/// + `NULL == hContext` +/// + `NULL == hDevice` +/// + NULL == hContext +/// + NULL == hDevice +/// - ::UR_RESULT_ERROR_INVALID_NULL_POINTER +/// + `NULL == phIPCMem` +/// + NULL == ipcMemHandleData +/// + NULL == phIPCMem +/// - ::UR_RESULT_ERROR_INVALID_CONTEXT +/// - ::UR_RESULT_ERROR_INVALID_VALUE +/// + ipcMemHandleDataSize is not the same as the size of IPC memory +/// handle data +/// - ::UR_RESULT_ERROR_OUT_OF_HOST_MEMORY +/// - ::UR_RESULT_ERROR_OUT_OF_RESOURCES +UR_APIEXPORT ur_result_t UR_APICALL urIPCCreateMemHandleFromDataExp( + /// [in] handle of the context object + ur_context_handle_t hContext, + /// [in] handle of the device object the corresponding USM device memory + /// was allocated on + ur_device_handle_t hDevice, + /// [in] the IPC memory handle data + const void *ipcMemHandleData, + /// [in] size of the IPC memory handle data + size_t ipcMemHandleDataSize, + /// [out] the IPC memory handle + ur_exp_ipc_mem_handle_t *phIPCMem); + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Destroys an inter-process memory handle created through +/// urIPCCreateMemHandleFromDataExp +/// +/// @returns +/// - ::UR_RESULT_SUCCESS +/// - ::UR_RESULT_ERROR_UNINITIALIZED +/// - ::UR_RESULT_ERROR_DEVICE_LOST +/// - ::UR_RESULT_ERROR_ADAPTER_SPECIFIC +/// - ::UR_RESULT_ERROR_INVALID_NULL_HANDLE +/// + `NULL == hContext` +/// + NULL == hContext +/// + NULL == hIPCMem +/// - ::UR_RESULT_ERROR_INVALID_CONTEXT +/// - ::UR_RESULT_ERROR_INVALID_VALUE +/// + hIPCMem was not created through CreateMemHandleFromDataExp +/// - ::UR_RESULT_ERROR_OUT_OF_HOST_MEMORY +/// - ::UR_RESULT_ERROR_OUT_OF_RESOURCES +UR_APIEXPORT ur_result_t UR_APICALL urIPCDestroyMemHandleExp( + /// [in] handle of the context object + ur_context_handle_t hContext, + /// [in] the IPC memory handle + ur_exp_ipc_mem_handle_t hIPCMem); + #if !defined(__GNUC__) #pragma endregion #endif @@ -15422,6 +15631,76 @@ typedef struct ur_command_buffer_get_native_handle_exp_params_t { ur_native_handle_t **pphNativeCommandBuffer; } ur_command_buffer_get_native_handle_exp_params_t; +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function parameters for urIPCGetMemHandleExp +/// @details Each entry is a pointer to the parameter passed to the function; +/// allowing the callback the ability to modify the parameter's value +typedef struct ur_ipc_get_mem_handle_exp_params_t { + ur_context_handle_t *phContext; + void **ppMem; + ur_exp_ipc_mem_handle_t **pphIPCMem; +} ur_ipc_get_mem_handle_exp_params_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function parameters for urIPCPutMemHandleExp +/// @details Each entry is a pointer to the parameter passed to the function; +/// allowing the callback the ability to modify the parameter's value +typedef struct ur_ipc_put_mem_handle_exp_params_t { + ur_context_handle_t *phContext; + ur_exp_ipc_mem_handle_t *phIPCMem; +} ur_ipc_put_mem_handle_exp_params_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function parameters for urIPCOpenMemHandleExp +/// @details Each entry is a pointer to the parameter passed to the function; +/// allowing the callback the ability to modify the parameter's value +typedef struct ur_ipc_open_mem_handle_exp_params_t { + ur_context_handle_t *phContext; + ur_exp_ipc_mem_handle_t *phIPCMem; + void ***pppMem; +} ur_ipc_open_mem_handle_exp_params_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function parameters for urIPCCloseMemHandleExp +/// @details Each entry is a pointer to the parameter passed to the function; +/// allowing the callback the ability to modify the parameter's value +typedef struct ur_ipc_close_mem_handle_exp_params_t { + ur_context_handle_t *phContext; + void **ppMem; +} ur_ipc_close_mem_handle_exp_params_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function parameters for urIPCGetMemHandleDataExp +/// @details Each entry is a pointer to the parameter passed to the function; +/// allowing the callback the ability to modify the parameter's value +typedef struct ur_ipc_get_mem_handle_data_exp_params_t { + ur_context_handle_t *phContext; + ur_exp_ipc_mem_handle_t *phIPCMem; + const void ***pppIPCHandleData; + size_t **ppIPCMemHandleDataSizeRet; +} ur_ipc_get_mem_handle_data_exp_params_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function parameters for urIPCCreateMemHandleFromDataExp +/// @details Each entry is a pointer to the parameter passed to the function; +/// allowing the callback the ability to modify the parameter's value +typedef struct ur_ipc_create_mem_handle_from_data_exp_params_t { + ur_context_handle_t *phContext; + ur_device_handle_t *phDevice; + const void **pipcMemHandleData; + size_t *pipcMemHandleDataSize; + ur_exp_ipc_mem_handle_t **pphIPCMem; +} ur_ipc_create_mem_handle_from_data_exp_params_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function parameters for urIPCDestroyMemHandleExp +/// @details Each entry is a pointer to the parameter passed to the function; +/// allowing the callback the ability to modify the parameter's value +typedef struct ur_ipc_destroy_mem_handle_exp_params_t { + ur_context_handle_t *phContext; + ur_exp_ipc_mem_handle_t *phIPCMem; +} ur_ipc_destroy_mem_handle_exp_params_t; + /////////////////////////////////////////////////////////////////////////////// /// @brief Function parameters for urMemoryExportAllocExportableMemoryExp /// @details Each entry is a pointer to the parameter passed to the function; diff --git a/unified-runtime/include/ur_api_funcs.def b/unified-runtime/include/ur_api_funcs.def index f0c92445b9238..f6e347cb16380 100644 --- a/unified-runtime/include/ur_api_funcs.def +++ b/unified-runtime/include/ur_api_funcs.def @@ -206,6 +206,13 @@ _UR_API(urCommandBufferUpdateSignalEventExp) _UR_API(urCommandBufferUpdateWaitEventsExp) _UR_API(urCommandBufferGetInfoExp) _UR_API(urCommandBufferGetNativeHandleExp) +_UR_API(urIPCGetMemHandleExp) +_UR_API(urIPCPutMemHandleExp) +_UR_API(urIPCOpenMemHandleExp) +_UR_API(urIPCCloseMemHandleExp) +_UR_API(urIPCGetMemHandleDataExp) +_UR_API(urIPCCreateMemHandleFromDataExp) +_UR_API(urIPCDestroyMemHandleExp) _UR_API(urMemoryExportAllocExportableMemoryExp) _UR_API(urMemoryExportFreeExportableMemoryExp) _UR_API(urMemoryExportExportMemoryHandleExp) diff --git a/unified-runtime/include/ur_ddi.h b/unified-runtime/include/ur_ddi.h index 8ab686aa583cc..f26c71af2d67c 100644 --- a/unified-runtime/include/ur_ddi.h +++ b/unified-runtime/include/ur_ddi.h @@ -1787,6 +1787,74 @@ UR_DLLEXPORT ur_result_t UR_APICALL urGetCommandBufferExpProcAddrTable( typedef ur_result_t(UR_APICALL *ur_pfnGetCommandBufferExpProcAddrTable_t)( ur_api_version_t, ur_command_buffer_exp_dditable_t *); +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function-pointer for urIPCGetMemHandleExp +typedef ur_result_t(UR_APICALL *ur_pfnIPCGetMemHandleExp_t)( + ur_context_handle_t, void *, ur_exp_ipc_mem_handle_t *); + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function-pointer for urIPCPutMemHandleExp +typedef ur_result_t(UR_APICALL *ur_pfnIPCPutMemHandleExp_t)( + ur_context_handle_t, ur_exp_ipc_mem_handle_t); + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function-pointer for urIPCOpenMemHandleExp +typedef ur_result_t(UR_APICALL *ur_pfnIPCOpenMemHandleExp_t)( + ur_context_handle_t, ur_exp_ipc_mem_handle_t, void **); + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function-pointer for urIPCCloseMemHandleExp +typedef ur_result_t(UR_APICALL *ur_pfnIPCCloseMemHandleExp_t)( + ur_context_handle_t, void *); + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function-pointer for urIPCGetMemHandleDataExp +typedef ur_result_t(UR_APICALL *ur_pfnIPCGetMemHandleDataExp_t)( + ur_context_handle_t, ur_exp_ipc_mem_handle_t, const void **, size_t *); + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function-pointer for urIPCCreateMemHandleFromDataExp +typedef ur_result_t(UR_APICALL *ur_pfnIPCCreateMemHandleFromDataExp_t)( + ur_context_handle_t, ur_device_handle_t, const void *, size_t, + ur_exp_ipc_mem_handle_t *); + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function-pointer for urIPCDestroyMemHandleExp +typedef ur_result_t(UR_APICALL *ur_pfnIPCDestroyMemHandleExp_t)( + ur_context_handle_t, ur_exp_ipc_mem_handle_t); + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Table of IPCExp functions pointers +typedef struct ur_ipc_exp_dditable_t { + ur_pfnIPCGetMemHandleExp_t pfnGetMemHandleExp; + ur_pfnIPCPutMemHandleExp_t pfnPutMemHandleExp; + ur_pfnIPCOpenMemHandleExp_t pfnOpenMemHandleExp; + ur_pfnIPCCloseMemHandleExp_t pfnCloseMemHandleExp; + ur_pfnIPCGetMemHandleDataExp_t pfnGetMemHandleDataExp; + ur_pfnIPCCreateMemHandleFromDataExp_t pfnCreateMemHandleFromDataExp; + ur_pfnIPCDestroyMemHandleExp_t pfnDestroyMemHandleExp; +} ur_ipc_exp_dditable_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Exported function for filling application's IPCExp table +/// with current process' addresses +/// +/// @returns +/// - ::UR_RESULT_SUCCESS +/// - ::UR_RESULT_ERROR_UNINITIALIZED +/// - ::UR_RESULT_ERROR_INVALID_NULL_POINTER +/// - ::UR_RESULT_ERROR_UNSUPPORTED_VERSION +UR_DLLEXPORT ur_result_t UR_APICALL urGetIPCExpProcAddrTable( + /// [in] API version requested + ur_api_version_t version, + /// [in,out] pointer to table of DDI function pointers + ur_ipc_exp_dditable_t *pDdiTable); + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function-pointer for urGetIPCExpProcAddrTable +typedef ur_result_t(UR_APICALL *ur_pfnGetIPCExpProcAddrTable_t)( + ur_api_version_t, ur_ipc_exp_dditable_t *); + /////////////////////////////////////////////////////////////////////////////// /// @brief Function-pointer for urMemoryExportAllocExportableMemoryExp typedef ur_result_t(UR_APICALL *ur_pfnMemoryExportAllocExportableMemoryExp_t)( @@ -2049,6 +2117,7 @@ typedef struct ur_dditable_t { ur_usm_exp_dditable_t USMExp; ur_bindless_images_exp_dditable_t BindlessImagesExp; ur_command_buffer_exp_dditable_t CommandBufferExp; + ur_ipc_exp_dditable_t IPCExp; ur_memory_export_exp_dditable_t MemoryExportExp; ur_usm_p2p_exp_dditable_t UsmP2PExp; ur_virtual_mem_dditable_t VirtualMem; diff --git a/unified-runtime/include/ur_print.h b/unified-runtime/include/ur_print.h index 8130df0c5bec4..99a80097b522d 100644 --- a/unified-runtime/include/ur_print.h +++ b/unified-runtime/include/ur_print.h @@ -3490,6 +3490,76 @@ urPrintCommandBufferGetNativeHandleExpParams( const struct ur_command_buffer_get_native_handle_exp_params_t *params, char *buffer, const size_t buff_size, size_t *out_size); +/////////////////////////////////////////////////////////////////////////////// +/// @brief Print ur_ipc_get_mem_handle_exp_params_t struct +/// @returns +/// - ::UR_RESULT_SUCCESS +/// - ::UR_RESULT_ERROR_INVALID_SIZE +/// - `buff_size < out_size` +UR_APIEXPORT ur_result_t UR_APICALL urPrintIpcGetMemHandleExpParams( + const struct ur_ipc_get_mem_handle_exp_params_t *params, char *buffer, + const size_t buff_size, size_t *out_size); + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Print ur_ipc_put_mem_handle_exp_params_t struct +/// @returns +/// - ::UR_RESULT_SUCCESS +/// - ::UR_RESULT_ERROR_INVALID_SIZE +/// - `buff_size < out_size` +UR_APIEXPORT ur_result_t UR_APICALL urPrintIpcPutMemHandleExpParams( + const struct ur_ipc_put_mem_handle_exp_params_t *params, char *buffer, + const size_t buff_size, size_t *out_size); + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Print ur_ipc_open_mem_handle_exp_params_t struct +/// @returns +/// - ::UR_RESULT_SUCCESS +/// - ::UR_RESULT_ERROR_INVALID_SIZE +/// - `buff_size < out_size` +UR_APIEXPORT ur_result_t UR_APICALL urPrintIpcOpenMemHandleExpParams( + const struct ur_ipc_open_mem_handle_exp_params_t *params, char *buffer, + const size_t buff_size, size_t *out_size); + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Print ur_ipc_close_mem_handle_exp_params_t struct +/// @returns +/// - ::UR_RESULT_SUCCESS +/// - ::UR_RESULT_ERROR_INVALID_SIZE +/// - `buff_size < out_size` +UR_APIEXPORT ur_result_t UR_APICALL urPrintIpcCloseMemHandleExpParams( + const struct ur_ipc_close_mem_handle_exp_params_t *params, char *buffer, + const size_t buff_size, size_t *out_size); + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Print ur_ipc_get_mem_handle_data_exp_params_t struct +/// @returns +/// - ::UR_RESULT_SUCCESS +/// - ::UR_RESULT_ERROR_INVALID_SIZE +/// - `buff_size < out_size` +UR_APIEXPORT ur_result_t UR_APICALL urPrintIpcGetMemHandleDataExpParams( + const struct ur_ipc_get_mem_handle_data_exp_params_t *params, char *buffer, + const size_t buff_size, size_t *out_size); + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Print ur_ipc_create_mem_handle_from_data_exp_params_t struct +/// @returns +/// - ::UR_RESULT_SUCCESS +/// - ::UR_RESULT_ERROR_INVALID_SIZE +/// - `buff_size < out_size` +UR_APIEXPORT ur_result_t UR_APICALL urPrintIpcCreateMemHandleFromDataExpParams( + const struct ur_ipc_create_mem_handle_from_data_exp_params_t *params, + char *buffer, const size_t buff_size, size_t *out_size); + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Print ur_ipc_destroy_mem_handle_exp_params_t struct +/// @returns +/// - ::UR_RESULT_SUCCESS +/// - ::UR_RESULT_ERROR_INVALID_SIZE +/// - `buff_size < out_size` +UR_APIEXPORT ur_result_t UR_APICALL urPrintIpcDestroyMemHandleExpParams( + const struct ur_ipc_destroy_mem_handle_exp_params_t *params, char *buffer, + const size_t buff_size, size_t *out_size); + /////////////////////////////////////////////////////////////////////////////// /// @brief Print ur_memory_export_alloc_exportable_memory_exp_params_t struct /// @returns diff --git a/unified-runtime/include/ur_print.hpp b/unified-runtime/include/ur_print.hpp index 15c50dd0eb479..48caa9701f038 100644 --- a/unified-runtime/include/ur_print.hpp +++ b/unified-runtime/include/ur_print.hpp @@ -42,6 +42,7 @@ template <> struct is_handle : std::true_type {}; template <> struct is_handle : std::true_type {}; +template <> struct is_handle : std::true_type {}; template inline constexpr bool is_handle_v = is_handle::value; template inline ur_result_t printPtr(std::ostream &os, const T *ptr); @@ -1274,6 +1275,27 @@ inline std::ostream &operator<<(std::ostream &os, enum ur_function_t value) { case UR_FUNCTION_BINDLESS_IMAGES_SUPPORTS_IMPORTING_HANDLE_TYPE_EXP: os << "UR_FUNCTION_BINDLESS_IMAGES_SUPPORTS_IMPORTING_HANDLE_TYPE_EXP"; break; + case UR_FUNCTION_IPC_GET_MEM_HANDLE_EXP: + os << "UR_FUNCTION_IPC_GET_MEM_HANDLE_EXP"; + break; + case UR_FUNCTION_IPC_PUT_MEM_HANDLE_EXP: + os << "UR_FUNCTION_IPC_PUT_MEM_HANDLE_EXP"; + break; + case UR_FUNCTION_IPC_OPEN_MEM_HANDLE_EXP: + os << "UR_FUNCTION_IPC_OPEN_MEM_HANDLE_EXP"; + break; + case UR_FUNCTION_IPC_CLOSE_MEM_HANDLE_EXP: + os << "UR_FUNCTION_IPC_CLOSE_MEM_HANDLE_EXP"; + break; + case UR_FUNCTION_IPC_GET_MEM_HANDLE_DATA_EXP: + os << "UR_FUNCTION_IPC_GET_MEM_HANDLE_DATA_EXP"; + break; + case UR_FUNCTION_IPC_CREATE_MEM_HANDLE_FROM_DATA_EXP: + os << "UR_FUNCTION_IPC_CREATE_MEM_HANDLE_FROM_DATA_EXP"; + break; + case UR_FUNCTION_IPC_DESTROY_MEM_HANDLE_EXP: + os << "UR_FUNCTION_IPC_DESTROY_MEM_HANDLE_EXP"; + break; default: os << "unknown enumerator"; break; @@ -3116,6 +3138,9 @@ inline std::ostream &operator<<(std::ostream &os, enum ur_device_info_t value) { case UR_DEVICE_INFO_2D_BLOCK_ARRAY_CAPABILITIES_EXP: os << "UR_DEVICE_INFO_2D_BLOCK_ARRAY_CAPABILITIES_EXP"; break; + case UR_DEVICE_INFO_IPC_MEMORY_SUPPORT_EXP: + os << "UR_DEVICE_INFO_IPC_MEMORY_SUPPORT_EXP"; + break; case UR_DEVICE_INFO_ASYNC_USM_ALLOCATIONS_SUPPORT_EXP: os << "UR_DEVICE_INFO_ASYNC_USM_ALLOCATIONS_SUPPORT_EXP"; break; @@ -5244,6 +5269,19 @@ inline ur_result_t printTagged(std::ostream &os, const void *ptr, os << ")"; } break; + case UR_DEVICE_INFO_IPC_MEMORY_SUPPORT_EXP: { + const ur_bool_t *tptr = (const ur_bool_t *)ptr; + if (sizeof(ur_bool_t) > size) { + os << "invalid size (is: " << size + << ", expected: >=" << sizeof(ur_bool_t) << ")"; + return UR_RESULT_ERROR_INVALID_SIZE; + } + os << (const void *)(tptr) << " ("; + + os << *tptr; + + os << ")"; + } break; case UR_DEVICE_INFO_ASYNC_USM_ALLOCATIONS_SUPPORT_EXP: { const ur_bool_t *tptr = (const ur_bool_t *)ptr; if (sizeof(ur_bool_t) > size) { @@ -20258,6 +20296,185 @@ operator<<(std::ostream &os, [[maybe_unused]] const struct return os; } +/////////////////////////////////////////////////////////////////////////////// +/// @brief Print operator for the ur_ipc_get_mem_handle_exp_params_t type +/// @returns +/// std::ostream & +inline std::ostream &operator<<( + std::ostream &os, + [[maybe_unused]] const struct ur_ipc_get_mem_handle_exp_params_t *params) { + + os << ".hContext = "; + + ur::details::printPtr(os, *(params->phContext)); + + os << ", "; + os << ".pMem = "; + + os << *(params->ppMem); + + os << ", "; + os << ".phIPCMem = "; + + ur::details::printPtr(os, *(params->pphIPCMem)); + + return os; +} + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Print operator for the ur_ipc_put_mem_handle_exp_params_t type +/// @returns +/// std::ostream & +inline std::ostream &operator<<( + std::ostream &os, + [[maybe_unused]] const struct ur_ipc_put_mem_handle_exp_params_t *params) { + + os << ".hContext = "; + + ur::details::printPtr(os, *(params->phContext)); + + os << ", "; + os << ".hIPCMem = "; + + ur::details::printPtr(os, *(params->phIPCMem)); + + return os; +} + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Print operator for the ur_ipc_open_mem_handle_exp_params_t type +/// @returns +/// std::ostream & +inline std::ostream &operator<<( + std::ostream &os, + [[maybe_unused]] const struct ur_ipc_open_mem_handle_exp_params_t *params) { + + os << ".hContext = "; + + ur::details::printPtr(os, *(params->phContext)); + + os << ", "; + os << ".hIPCMem = "; + + ur::details::printPtr(os, *(params->phIPCMem)); + + os << ", "; + os << ".ppMem = "; + + os << *(params->pppMem); + + return os; +} + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Print operator for the ur_ipc_close_mem_handle_exp_params_t type +/// @returns +/// std::ostream & +inline std::ostream & +operator<<(std::ostream &os, + [[maybe_unused]] const struct ur_ipc_close_mem_handle_exp_params_t + *params) { + + os << ".hContext = "; + + ur::details::printPtr(os, *(params->phContext)); + + os << ", "; + os << ".pMem = "; + + os << *(params->ppMem); + + return os; +} + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Print operator for the ur_ipc_get_mem_handle_data_exp_params_t type +/// @returns +/// std::ostream & +inline std::ostream & +operator<<(std::ostream &os, + [[maybe_unused]] const struct ur_ipc_get_mem_handle_data_exp_params_t + *params) { + + os << ".hContext = "; + + ur::details::printPtr(os, *(params->phContext)); + + os << ", "; + os << ".hIPCMem = "; + + ur::details::printPtr(os, *(params->phIPCMem)); + + os << ", "; + os << ".ppIPCHandleData = "; + + ur::details::printPtr(os, *(params->pppIPCHandleData)); + + os << ", "; + os << ".pIPCMemHandleDataSizeRet = "; + + ur::details::printPtr(os, *(params->ppIPCMemHandleDataSizeRet)); + + return os; +} + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Print operator for the +/// ur_ipc_create_mem_handle_from_data_exp_params_t type +/// @returns +/// std::ostream & +inline std::ostream & +operator<<(std::ostream &os, [[maybe_unused]] const struct + ur_ipc_create_mem_handle_from_data_exp_params_t *params) { + + os << ".hContext = "; + + ur::details::printPtr(os, *(params->phContext)); + + os << ", "; + os << ".hDevice = "; + + ur::details::printPtr(os, *(params->phDevice)); + + os << ", "; + os << ".ipcMemHandleData = "; + + os << *(params->pipcMemHandleData); + + os << ", "; + os << ".ipcMemHandleDataSize = "; + + os << *(params->pipcMemHandleDataSize); + + os << ", "; + os << ".phIPCMem = "; + + ur::details::printPtr(os, *(params->pphIPCMem)); + + return os; +} + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Print operator for the ur_ipc_destroy_mem_handle_exp_params_t type +/// @returns +/// std::ostream & +inline std::ostream & +operator<<(std::ostream &os, + [[maybe_unused]] const struct ur_ipc_destroy_mem_handle_exp_params_t + *params) { + + os << ".hContext = "; + + ur::details::printPtr(os, *(params->phContext)); + + os << ", "; + os << ".hIPCMem = "; + + ur::details::printPtr(os, *(params->phIPCMem)); + + return os; +} + /////////////////////////////////////////////////////////////////////////////// /// @brief Print operator for the /// ur_memory_export_alloc_exportable_memory_exp_params_t type @@ -21722,6 +21939,28 @@ inline ur_result_t UR_APICALL printFunctionParams(std::ostream &os, os << (const struct ur_command_buffer_get_native_handle_exp_params_t *) params; } break; + case UR_FUNCTION_IPC_GET_MEM_HANDLE_EXP: { + os << (const struct ur_ipc_get_mem_handle_exp_params_t *)params; + } break; + case UR_FUNCTION_IPC_PUT_MEM_HANDLE_EXP: { + os << (const struct ur_ipc_put_mem_handle_exp_params_t *)params; + } break; + case UR_FUNCTION_IPC_OPEN_MEM_HANDLE_EXP: { + os << (const struct ur_ipc_open_mem_handle_exp_params_t *)params; + } break; + case UR_FUNCTION_IPC_CLOSE_MEM_HANDLE_EXP: { + os << (const struct ur_ipc_close_mem_handle_exp_params_t *)params; + } break; + case UR_FUNCTION_IPC_GET_MEM_HANDLE_DATA_EXP: { + os << (const struct ur_ipc_get_mem_handle_data_exp_params_t *)params; + } break; + case UR_FUNCTION_IPC_CREATE_MEM_HANDLE_FROM_DATA_EXP: { + os << (const struct ur_ipc_create_mem_handle_from_data_exp_params_t *) + params; + } break; + case UR_FUNCTION_IPC_DESTROY_MEM_HANDLE_EXP: { + os << (const struct ur_ipc_destroy_mem_handle_exp_params_t *)params; + } break; case UR_FUNCTION_MEMORY_EXPORT_ALLOC_EXPORTABLE_MEMORY_EXP: { os << (const struct ur_memory_export_alloc_exportable_memory_exp_params_t *) params; diff --git a/unified-runtime/scripts/core/EXP-INTER-PROCESS-COMMUNICATION.rst b/unified-runtime/scripts/core/EXP-INTER-PROCESS-COMMUNICATION.rst new file mode 100644 index 0000000000000..1b0e0a5735eca --- /dev/null +++ b/unified-runtime/scripts/core/EXP-INTER-PROCESS-COMMUNICATION.rst @@ -0,0 +1,71 @@ +<% + OneApi=tags['$OneApi'] + x=tags['$x'] + X=x.upper() +%> + +.. _experimental-inter-process-communication: + +================================================================================ +Inter Process Communication +================================================================================ + +.. warning:: + + Experimental features: + + * May be replaced, updated, or removed at any time. + * Do not require maintaining API/ABI stability of their own additions over + time. + * Do not require conformance testing of their own additions. + + +Motivation +-------------------------------------------------------------------------------- +This extension introduces functionality for allowing processes to share common +objects, such as device USM memory allocations. Doing so lets processes actively +communicate with each other through the devices, by explicitly managing handles +that represent shareable objects for inter-process communication. + +API +-------------------------------------------------------------------------------- + +Enums +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +* ${x}_device_info_t + * ${X}_DEVICE_INFO_IPC_MEMORY_SUPPORT_EXP + +Types +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +* ${x}_exp_ipc_mem_handle_t + +Functions +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +* Inter-Process Communication + * ${x}IPCGetMemHandleExp + * ${x}IPCPutMemHandleExp + * ${x}IPCOpenMemHandleExp + * ${x}IPCCloseMemHandleExp + * ${x}IPCGetMemHandleDataExp + * ${x}IPCCreateMemHandleFromDataExp + * ${x}IPCDestroyMemHandleExp + +Changelog +-------------------------------------------------------------------------------- + ++-----------+------------------------+ +| Revision | Changes | ++===========+========================+ +| 1.0 | Initial Draft | ++-----------+------------------------+ + +Support +-------------------------------------------------------------------------------- + +Adapters which support this experimental feature *must* return true for the new +``${X}_DEVICE_INFO_IPC_MEMORY_SUPPORT_EXP`` device info query. + +Contributors +-------------------------------------------------------------------------------- + +* Larsen, Steffen `steffen.larsen@intel.com `_ diff --git a/unified-runtime/scripts/core/exp-inter-process-communication.yml b/unified-runtime/scripts/core/exp-inter-process-communication.yml new file mode 100644 index 0000000000000..5812430658a1c --- /dev/null +++ b/unified-runtime/scripts/core/exp-inter-process-communication.yml @@ -0,0 +1,201 @@ +# +# Copyright (C) 2025 Intel Corporation +# +# Part of the Unified-Runtime Project, under the Apache License v2.0 with LLVM +# Exceptions. +# See LICENSE.TXT +# +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +# +# See YaML.md for syntax definition +# +--- #-------------------------------------------------------------------------- +type: header +desc: "Intel $OneApi Unified Runtime Experimental APIs for Inter Process Communication" +ordinal: "99" +--- #-------------------------------------------------------------------------- +type: enum +extend: true +typed_etors: true +desc: "Extension enums to $x_device_info_t to support inter-process communicable memory handles." +name: $x_device_info_t +etors: + - name: IPC_MEMORY_SUPPORT_EXP + value: "0x2023" + desc: "[$x_bool_t] returns true if the device supports inter-process communicable memory handles" +--- #-------------------------------------------------------------------------- +type: handle +desc: "Handle of inter-process communicable memory" +name: "$x_exp_ipc_mem_handle_t" +--- #-------------------------------------------------------------------------- +type: function +desc: "Gets an inter-process memory handle for a pointer to device USM memory" +class: $xIPC +name: GetMemHandleExp +ordinal: "0" +params: + - type: $x_context_handle_t + name: hContext + desc: "[in] handle of the context object" + - type: void * + name: pMem + desc: "[in] pointer to device USM memory" + - type: $x_exp_ipc_mem_handle_t* + name: phIPCMem + desc: "[out][alloc] pointer to the resulting IPC memory handle" +returns: + - $X_RESULT_ERROR_INVALID_CONTEXT + - $X_RESULT_ERROR_INVALID_NULL_HANDLE: + - "NULL == hContext" + - $X_RESULT_ERROR_INVALID_NULL_POINTER: + - "NULL == phIPCMem" + - $X_RESULT_ERROR_OUT_OF_HOST_MEMORY + - $X_RESULT_ERROR_OUT_OF_RESOURCES +--- #-------------------------------------------------------------------------- +type: function +desc: "Releases an inter-process memory handle" +class: $xIPC +name: PutMemHandleExp +ordinal: "0" +params: + - type: $x_context_handle_t + name: hContext + desc: "[in] handle of the context object" + - type: $x_exp_ipc_mem_handle_t + name: hIPCMem + desc: "[in] the IPC memory handle" +returns: + - $X_RESULT_ERROR_INVALID_CONTEXT + - $X_RESULT_ERROR_INVALID_NULL_HANDLE: + - "NULL == hContext" + - "NULL == hIPCMem" + - $X_RESULT_ERROR_OUT_OF_HOST_MEMORY + - $X_RESULT_ERROR_OUT_OF_RESOURCES +--- #-------------------------------------------------------------------------- +type: function +desc: "Opens an inter-process memory handle to get the corresponding pointer to device USM memory" +class: $xIPC +name: OpenMemHandleExp +ordinal: "0" +params: + - type: $x_context_handle_t + name: hContext + desc: "[in] handle of the context object" + - type: $x_exp_ipc_mem_handle_t + name: hIPCMem + desc: "[in] pointer to the resulting IPC memory handle" + - type: void ** + name: ppMem + desc: "[out] pointer to a pointer to device USM memory" +returns: + - $X_RESULT_ERROR_INVALID_CONTEXT + - $X_RESULT_ERROR_INVALID_NULL_HANDLE: + - "NULL == hContext" + - "NULL == hIPCMem" + - $X_RESULT_ERROR_INVALID_NULL_POINTER: + - "NULL == ppMem" + - $X_RESULT_ERROR_OUT_OF_HOST_MEMORY + - $X_RESULT_ERROR_OUT_OF_RESOURCES +--- #-------------------------------------------------------------------------- +type: function +desc: "Closes an inter-process memory handle" +class: $xIPC +name: CloseMemHandleExp +ordinal: "0" +params: + - type: $x_context_handle_t + name: hContext + desc: "[in] handle of the context object" + - type: void * + name: pMem + desc: "[in] pointer to device USM memory opened through urIPCOpenMemHandleExp" +returns: + - $X_RESULT_ERROR_INVALID_CONTEXT + - $X_RESULT_ERROR_INVALID_NULL_HANDLE: + - "NULL == hContext" + - $X_RESULT_ERROR_INVALID_NULL_POINTER: + - "NULL == pMem" + - $X_RESULT_ERROR_OUT_OF_HOST_MEMORY + - $X_RESULT_ERROR_OUT_OF_RESOURCES +--- #-------------------------------------------------------------------------- +type: function +desc: "Gets the data of an inter-process memory handle" +class: $xIPC +name: GetMemHandleDataExp +ordinal: "0" +params: + - type: $x_context_handle_t + name: hContext + desc: "[in] handle of the context object" + - type: $x_exp_ipc_mem_handle_t + name: hIPCMem + desc: "[in] the IPC memory handle" + - type: const void** + name: ppIPCHandleData + desc: "[out][optional] a pointer to the IPC memory handle data" + - type: size_t* + name: pIPCMemHandleDataSizeRet + desc: "[out][optional] size of the resulting IPC memory handle data" +returns: + - $X_RESULT_ERROR_INVALID_CONTEXT + - $X_RESULT_ERROR_INVALID_NULL_HANDLE: + - "NULL == hContext" + - "NULL == hIPCMem" + - $X_RESULT_ERROR_OUT_OF_HOST_MEMORY + - $X_RESULT_ERROR_OUT_OF_RESOURCES +--- #-------------------------------------------------------------------------- +type: function +desc: "Creates an inter-process memory handle from handle data" +class: $xIPC +name: CreateMemHandleFromDataExp +ordinal: "0" +params: + - type: $x_context_handle_t + name: hContext + desc: "[in] handle of the context object" + - type: $x_device_handle_t + name: hDevice + desc: "[in] handle of the device object the corresponding USM device memory was allocated on" + - type: const void * + name: ipcMemHandleData + desc: "[in] the IPC memory handle data" + - type: size_t + name: ipcMemHandleDataSize + desc: "[in] size of the IPC memory handle data" + - type: $x_exp_ipc_mem_handle_t* + name: phIPCMem + desc: "[out] the IPC memory handle" +returns: + - $X_RESULT_ERROR_INVALID_CONTEXT + - $X_RESULT_ERROR_INVALID_NULL_HANDLE: + - "NULL == hContext" + - "NULL == hDevice" + - $X_RESULT_ERROR_INVALID_NULL_POINTER: + - "NULL == ipcMemHandleData" + - "NULL == phIPCMem" + - $X_RESULT_ERROR_INVALID_VALUE: + - "ipcMemHandleDataSize is not the same as the size of IPC memory handle data" + - $X_RESULT_ERROR_OUT_OF_HOST_MEMORY + - $X_RESULT_ERROR_OUT_OF_RESOURCES +--- #-------------------------------------------------------------------------- +type: function +desc: "Destroys an inter-process memory handle created through urIPCCreateMemHandleFromDataExp" +class: $xIPC +name: DestroyMemHandleExp +ordinal: "0" +params: + - type: $x_context_handle_t + name: hContext + desc: "[in] handle of the context object" + - type: $x_exp_ipc_mem_handle_t + name: hIPCMem + desc: "[in] the IPC memory handle" +returns: + - $X_RESULT_ERROR_INVALID_CONTEXT + - $X_RESULT_ERROR_INVALID_NULL_HANDLE: + - "NULL == hContext" + - "NULL == hIPCMem" + - $X_RESULT_ERROR_INVALID_VALUE: + - "hIPCMem was not created through CreateMemHandleFromDataExp" + - $X_RESULT_ERROR_OUT_OF_HOST_MEMORY + - $X_RESULT_ERROR_OUT_OF_RESOURCES diff --git a/unified-runtime/scripts/core/registry.yml b/unified-runtime/scripts/core/registry.yml index a6237d93bf5ce..bfa91ae5cdc06 100644 --- a/unified-runtime/scripts/core/registry.yml +++ b/unified-runtime/scripts/core/registry.yml @@ -670,6 +670,27 @@ etors: - name: BINDLESS_IMAGES_SUPPORTS_IMPORTING_HANDLE_TYPE_EXP desc: Enumerator for $xBindlessImagesSupportsImportingHandleTypeExp value: '288' +- name: IPC_GET_MEM_HANDLE_EXP + desc: Enumerator for $xIPCGetMemHandleExp + value: '289' +- name: IPC_PUT_MEM_HANDLE_EXP + desc: Enumerator for $xIPCPutMemHandleExp + value: '290' +- name: IPC_OPEN_MEM_HANDLE_EXP + desc: Enumerator for $xIPCOpenMemHandleExp + value: '291' +- name: IPC_CLOSE_MEM_HANDLE_EXP + desc: Enumerator for $xIPCCloseMemHandleExp + value: '292' +- name: IPC_GET_MEM_HANDLE_DATA_EXP + desc: Enumerator for $xIPCGetMemHandleDataExp + value: '293' +- name: IPC_CREATE_MEM_HANDLE_FROM_DATA_EXP + desc: Enumerator for $xIPCCreateMemHandleFromDataExp + value: '294' +- name: IPC_DESTROY_MEM_HANDLE_EXP + desc: Enumerator for $xIPCDestroyMemHandleExp + value: '295' --- type: enum desc: Defines structure types diff --git a/unified-runtime/source/adapters/adapter.def.in b/unified-runtime/source/adapters/adapter.def.in index edccce444d2e0..aa3b55765ce3c 100644 --- a/unified-runtime/source/adapters/adapter.def.in +++ b/unified-runtime/source/adapters/adapter.def.in @@ -7,6 +7,7 @@ EXPORTS urGetEnqueueProcAddrTable urGetEnqueueExpProcAddrTable urGetEventProcAddrTable + urGetIPCExpProcAddrTable urGetKernelProcAddrTable urGetMemProcAddrTable urGetMemoryExportExpProcAddrTable diff --git a/unified-runtime/source/adapters/adapter.map.in b/unified-runtime/source/adapters/adapter.map.in index 54ff7d6b93f31..4be9b9b1348b7 100644 --- a/unified-runtime/source/adapters/adapter.map.in +++ b/unified-runtime/source/adapters/adapter.map.in @@ -7,6 +7,7 @@ urGetEnqueueProcAddrTable; urGetEnqueueExpProcAddrTable; urGetEventProcAddrTable; + urGetIPCExpProcAddrTable; urGetKernelProcAddrTable; urGetMemProcAddrTable; urGetMemoryExportExpProcAddrTable; diff --git a/unified-runtime/source/adapters/cuda/device.cpp b/unified-runtime/source/adapters/cuda/device.cpp index 03d9a13999f84..ddc4c7a115e26 100644 --- a/unified-runtime/source/adapters/cuda/device.cpp +++ b/unified-runtime/source/adapters/cuda/device.cpp @@ -1146,6 +1146,13 @@ UR_APIEXPORT ur_result_t UR_APICALL urDeviceGetInfo(ur_device_handle_t hDevice, case UR_DEVICE_INFO_2D_BLOCK_ARRAY_CAPABILITIES_EXP: return ReturnValue( static_cast(0)); + case UR_DEVICE_INFO_IPC_MEMORY_SUPPORT_EXP: { + int IPCSupported = 0; + UR_CHECK_ERROR(cuDeviceGetAttribute(&IPCSupported, + CU_DEVICE_ATTRIBUTE_IPC_EVENT_SUPPORTED, + hDevice->get())); + return ReturnValue(static_cast(IPCSupported)); + } case UR_DEVICE_INFO_COMMAND_BUFFER_SUPPORT_EXP: case UR_DEVICE_INFO_COMMAND_BUFFER_EVENT_SUPPORT_EXP: return ReturnValue(true); diff --git a/unified-runtime/source/adapters/cuda/memory.cpp b/unified-runtime/source/adapters/cuda/memory.cpp index b48252de6a816..751abbd9320b0 100644 --- a/unified-runtime/source/adapters/cuda/memory.cpp +++ b/unified-runtime/source/adapters/cuda/memory.cpp @@ -15,6 +15,7 @@ #include "enqueue.hpp" #include "memory.hpp" #include "umf_helpers.hpp" +#include "usm.hpp" /// Creates a UR Memory object using a CUDA memory allocation. /// Can trigger a manual copy depending on the mode. @@ -589,3 +590,92 @@ CUsurfObject SurfaceMem::getSurface(const ur_device_handle_t Device) { } return SurfObjs[OuterMemStruct->getContext()->getDeviceIndex(Device)]; } + +UR_APIEXPORT ur_result_t UR_APICALL urIPCGetMemHandleExp( + ur_context_handle_t, void *pMem, ur_exp_ipc_mem_handle_t *phIPCMem) { + auto resHandle = std::make_unique(); + resHandle->CreatedFromData = false; + + auto umfRet = umfPoolByPtr(pMem, &resHandle->UMFPool); + if (umfRet != UMF_RESULT_SUCCESS || !resHandle->UMFPool) + return UR_RESULT_ERROR_UNKNOWN; + + umfRet = umfGetIPCHandle(pMem, &resHandle->UMFHandle, &resHandle->HandleSize); + if (umfRet != UMF_RESULT_SUCCESS || !resHandle->UMFHandle || + resHandle->HandleSize == 0) + return UR_RESULT_ERROR_UNKNOWN; + + *phIPCMem = resHandle.release(); + return UR_RESULT_SUCCESS; +} + +UR_APIEXPORT ur_result_t UR_APICALL +urIPCPutMemHandleExp(ur_context_handle_t, ur_exp_ipc_mem_handle_t hIPCMem) { + auto umfRet = umfPutIPCHandle(hIPCMem->UMFHandle); + if (umfRet != UMF_RESULT_SUCCESS) + return UR_RESULT_ERROR_UNKNOWN; + std::free(hIPCMem); + return UR_RESULT_SUCCESS; +} + +UR_APIEXPORT ur_result_t UR_APICALL urIPCOpenMemHandleExp( + ur_context_handle_t, ur_exp_ipc_mem_handle_t hIPCMem, void **ppMem) { + umf_ipc_handler_handle_t umfIPCHandler; + auto umfRet = umfPoolGetIPCHandler(hIPCMem->UMFPool, &umfIPCHandler); + if (umfRet != UMF_RESULT_SUCCESS || !umfIPCHandler) + return UR_RESULT_ERROR_UNKNOWN; + + umfRet = umfOpenIPCHandle(umfIPCHandler, hIPCMem->UMFHandle, ppMem); + return umfRet == UMF_RESULT_SUCCESS ? UR_RESULT_SUCCESS + : UR_RESULT_ERROR_UNKNOWN; +} + +UR_APIEXPORT ur_result_t UR_APICALL urIPCCloseMemHandleExp(ur_context_handle_t, + void *pMem) { + auto umfRet = umfCloseIPCHandle(pMem); + return umfRet == UMF_RESULT_SUCCESS ? UR_RESULT_SUCCESS + : UR_RESULT_ERROR_UNKNOWN; +} + +UR_APIEXPORT ur_result_t UR_APICALL urIPCGetMemHandleDataExp( + ur_context_handle_t, ur_exp_ipc_mem_handle_t hIPCMem, + const void **ppIPCHandleData, size_t *pIPCMemHandleDataSizeRet) { + if (ppIPCHandleData) + *ppIPCHandleData = hIPCMem->UMFHandle; + if (pIPCMemHandleDataSizeRet) + *pIPCMemHandleDataSizeRet = hIPCMem->HandleSize; + return UR_RESULT_SUCCESS; +} + +UR_APIEXPORT ur_result_t UR_APICALL urIPCCreateMemHandleFromDataExp( + ur_context_handle_t, ur_device_handle_t hDevice, + const void *pIPCMemHandleData, size_t ipcMemHandleDataSize, + ur_exp_ipc_mem_handle_t *phIPCMem) { + umf_memory_pool_handle_t umfPool = hDevice->MemoryPoolDevice; + + size_t umfHandleSize = 0; + auto umfRet = umfPoolGetIPCHandleSize(umfPool, &umfHandleSize); + if (umfRet != UMF_RESULT_SUCCESS || umfHandleSize == 0) + return UR_RESULT_ERROR_UNKNOWN; + + if (umfHandleSize != ipcMemHandleDataSize) + return UR_RESULT_ERROR_INVALID_VALUE; + + auto resHandle = std::make_unique(); + resHandle->UMFPool = umfPool; + resHandle->UMFHandle = + reinterpret_cast(std::malloc(umfHandleSize)); + std::memcpy(resHandle->UMFHandle, pIPCMemHandleData, umfHandleSize); + resHandle->HandleSize = umfHandleSize; + resHandle->CreatedFromData = true; + *phIPCMem = resHandle.release(); + return UR_RESULT_SUCCESS; +} + +UR_APIEXPORT ur_result_t UR_APICALL +urIPCDestroyMemHandleExp(ur_context_handle_t, ur_exp_ipc_mem_handle_t hIPCMem) { + if (!hIPCMem->CreatedFromData) + return UR_RESULT_ERROR_INVALID_VALUE; + std::free(hIPCMem); + return UR_RESULT_SUCCESS; +} diff --git a/unified-runtime/source/adapters/cuda/memory.hpp b/unified-runtime/source/adapters/cuda/memory.hpp index 6bb817f1efee8..222da95c7824f 100644 --- a/unified-runtime/source/adapters/cuda/memory.hpp +++ b/unified-runtime/source/adapters/cuda/memory.hpp @@ -19,6 +19,7 @@ #include "common/ur_ref_count.hpp" #include "context.hpp" #include "queue.hpp" +#include ur_result_t allocateMemObjOnDeviceIfNeeded(ur_mem_handle_t, const ur_device_handle_t); @@ -439,3 +440,10 @@ struct ur_mem_handle_t_ : ur::cuda::handle_base { } } }; + +struct ur_exp_ipc_mem_handle_t_ { + umf_memory_pool_handle_t UMFPool; + umf_ipc_handle_t UMFHandle = nullptr; + size_t HandleSize = 0; + bool CreatedFromData = false; +}; diff --git a/unified-runtime/source/adapters/cuda/ur_interface_loader.cpp b/unified-runtime/source/adapters/cuda/ur_interface_loader.cpp index 8430df0ab0678..2d24a5b6c730f 100644 --- a/unified-runtime/source/adapters/cuda/ur_interface_loader.cpp +++ b/unified-runtime/source/adapters/cuda/ur_interface_loader.cpp @@ -458,6 +458,24 @@ UR_DLLEXPORT ur_result_t UR_APICALL urGetEnqueueExpProcAddrTable( return UR_RESULT_SUCCESS; } +UR_DLLEXPORT ur_result_t UR_APICALL urGetIPCExpProcAddrTable( + ur_api_version_t version, ur_ipc_exp_dditable_t *pDdiTable) { + auto result = validateProcInputs(version, pDdiTable); + if (UR_RESULT_SUCCESS != result) { + return result; + } + + pDdiTable->pfnGetMemHandleExp = urIPCGetMemHandleExp; + pDdiTable->pfnPutMemHandleExp = urIPCPutMemHandleExp; + pDdiTable->pfnOpenMemHandleExp = urIPCOpenMemHandleExp; + pDdiTable->pfnCloseMemHandleExp = urIPCCloseMemHandleExp; + pDdiTable->pfnGetMemHandleDataExp = urIPCGetMemHandleDataExp; + pDdiTable->pfnCreateMemHandleFromDataExp = urIPCCreateMemHandleFromDataExp; + pDdiTable->pfnDestroyMemHandleExp = urIPCDestroyMemHandleExp; + + return UR_RESULT_SUCCESS; +} + UR_DLLEXPORT ur_result_t UR_APICALL urGetProgramExpProcAddrTable( ur_api_version_t version, ur_program_exp_dditable_t *pDdiTable) { auto result = validateProcInputs(version, pDdiTable); @@ -480,6 +498,7 @@ UR_DLLEXPORT ur_result_t UR_APICALL urAllAddrTable(ur_api_version_t version, urGetContextProcAddrTable(version, &pDdiTable->Context); urGetEnqueueProcAddrTable(version, &pDdiTable->Enqueue); urGetEnqueueExpProcAddrTable(version, &pDdiTable->EnqueueExp); + urGetIPCExpProcAddrTable(version, &pDdiTable->IPCExp); urGetEventProcAddrTable(version, &pDdiTable->Event); urGetKernelProcAddrTable(version, &pDdiTable->Kernel); urGetMemProcAddrTable(version, &pDdiTable->Mem); diff --git a/unified-runtime/source/adapters/hip/device.cpp b/unified-runtime/source/adapters/hip/device.cpp index c48033ec88826..f71d86c3f4a5e 100644 --- a/unified-runtime/source/adapters/hip/device.cpp +++ b/unified-runtime/source/adapters/hip/device.cpp @@ -999,6 +999,8 @@ UR_APIEXPORT ur_result_t UR_APICALL urDeviceGetInfo(ur_device_handle_t hDevice, case UR_DEVICE_INFO_2D_BLOCK_ARRAY_CAPABILITIES_EXP: return ReturnValue( static_cast(0)); + case UR_DEVICE_INFO_IPC_MEMORY_SUPPORT_EXP: + return ReturnValue(false); case UR_DEVICE_INFO_COMMAND_BUFFER_SUPPORT_EXP: { int RuntimeVersion = 0; UR_CHECK_ERROR(hipRuntimeGetVersion(&RuntimeVersion)); diff --git a/unified-runtime/source/adapters/hip/memory.cpp b/unified-runtime/source/adapters/hip/memory.cpp index 7995b15d36f84..a678ac7914416 100644 --- a/unified-runtime/source/adapters/hip/memory.cpp +++ b/unified-runtime/source/adapters/hip/memory.cpp @@ -640,3 +640,39 @@ hipSurfaceObject_t SurfaceMem::getSurface(const ur_device_handle_t Device) { } return SurfObjs[OuterMemStruct->getContext()->getDeviceIndex(Device)]; } + +UR_APIEXPORT ur_result_t UR_APICALL +urIPCGetMemHandleExp(ur_context_handle_t, void *, ur_exp_ipc_mem_handle_t *) { + return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; +} + +UR_APIEXPORT ur_result_t UR_APICALL +urIPCPutMemHandleExp(ur_context_handle_t, ur_exp_ipc_mem_handle_t) { + return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; +} + +UR_APIEXPORT ur_result_t UR_APICALL +urIPCOpenMemHandleExp(ur_context_handle_t, ur_exp_ipc_mem_handle_t, void **) { + return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; +} + +UR_APIEXPORT ur_result_t UR_APICALL urIPCCloseMemHandleExp(ur_context_handle_t, + void *) { + return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; +} + +UR_APIEXPORT ur_result_t UR_APICALL urIPCGetMemHandleDataExp( + ur_context_handle_t, ur_exp_ipc_mem_handle_t, const void **, size_t *) { + return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; +} + +UR_APIEXPORT ur_result_t UR_APICALL urIPCCreateMemHandleFromDataExp( + ur_context_handle_t, ur_device_handle_t, const void *, size_t, + ur_exp_ipc_mem_handle_t *) { + return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; +} + +UR_APIEXPORT ur_result_t UR_APICALL +urIPCDestroyMemHandleExp(ur_context_handle_t, ur_exp_ipc_mem_handle_t) { + return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; +} diff --git a/unified-runtime/source/adapters/hip/memory.hpp b/unified-runtime/source/adapters/hip/memory.hpp index 239e3949c740c..d825d153b04ce 100644 --- a/unified-runtime/source/adapters/hip/memory.hpp +++ b/unified-runtime/source/adapters/hip/memory.hpp @@ -433,3 +433,6 @@ struct ur_mem_handle_t_ : ur::hip::handle_base { } } }; + +// IPC is currently not supported in the HIP adaptor. +struct ur_exp_ipc_mem_handle_t_ {}; diff --git a/unified-runtime/source/adapters/hip/ur_interface_loader.cpp b/unified-runtime/source/adapters/hip/ur_interface_loader.cpp index dfb4382cad828..68757af457995 100644 --- a/unified-runtime/source/adapters/hip/ur_interface_loader.cpp +++ b/unified-runtime/source/adapters/hip/ur_interface_loader.cpp @@ -451,6 +451,24 @@ UR_DLLEXPORT ur_result_t UR_APICALL urGetEnqueueExpProcAddrTable( return UR_RESULT_SUCCESS; } +UR_DLLEXPORT ur_result_t UR_APICALL urGetIPCExpProcAddrTable( + ur_api_version_t version, ur_ipc_exp_dditable_t *pDdiTable) { + auto result = validateProcInputs(version, pDdiTable); + if (UR_RESULT_SUCCESS != result) { + return result; + } + + pDdiTable->pfnGetMemHandleExp = urIPCGetMemHandleExp; + pDdiTable->pfnPutMemHandleExp = urIPCPutMemHandleExp; + pDdiTable->pfnOpenMemHandleExp = urIPCOpenMemHandleExp; + pDdiTable->pfnCloseMemHandleExp = urIPCCloseMemHandleExp; + pDdiTable->pfnGetMemHandleDataExp = urIPCGetMemHandleDataExp; + pDdiTable->pfnCreateMemHandleFromDataExp = urIPCCreateMemHandleFromDataExp; + pDdiTable->pfnDestroyMemHandleExp = urIPCDestroyMemHandleExp; + + return UR_RESULT_SUCCESS; +} + UR_DLLEXPORT ur_result_t UR_APICALL urGetProgramExpProcAddrTable( ur_api_version_t version, ur_program_exp_dditable_t *pDdiTable) { auto result = validateProcInputs(version, pDdiTable); @@ -473,6 +491,7 @@ UR_DLLEXPORT ur_result_t UR_APICALL urAllAddrTable(ur_api_version_t version, urGetContextProcAddrTable(version, &pDdiTable->Context); urGetEnqueueProcAddrTable(version, &pDdiTable->Enqueue); urGetEnqueueExpProcAddrTable(version, &pDdiTable->EnqueueExp); + urGetIPCExpProcAddrTable(version, &pDdiTable->IPCExp); urGetEventProcAddrTable(version, &pDdiTable->Event); urGetKernelProcAddrTable(version, &pDdiTable->Kernel); urGetMemProcAddrTable(version, &pDdiTable->Mem); diff --git a/unified-runtime/source/adapters/level_zero/device.cpp b/unified-runtime/source/adapters/level_zero/device.cpp index a00d816d5ed61..37d488bd34239 100644 --- a/unified-runtime/source/adapters/level_zero/device.cpp +++ b/unified-runtime/source/adapters/level_zero/device.cpp @@ -1276,6 +1276,8 @@ ur_result_t urDeviceGetInfo( return UR_RESULT_ERROR_UNSUPPORTED_ENUMERATION; #endif } + case UR_DEVICE_INFO_IPC_MEMORY_SUPPORT_EXP: + return ReturnValue(true); case UR_DEVICE_INFO_ASYNC_BARRIER: return ReturnValue(false); case UR_DEVICE_INFO_HOST_PIPE_READ_WRITE_SUPPORT: diff --git a/unified-runtime/source/adapters/level_zero/memory.cpp b/unified-runtime/source/adapters/level_zero/memory.cpp index 107fcc2d1c2f5..88fadffde0af6 100644 --- a/unified-runtime/source/adapters/level_zero/memory.cpp +++ b/unified-runtime/source/adapters/level_zero/memory.cpp @@ -1952,6 +1952,101 @@ ur_result_t urEnqueueWriteHostPipe( return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; } +ur_result_t urIPCGetMemHandleExp(ur_context_handle_t, void *pMem, + ur_exp_ipc_mem_handle_t *phIPCMem) { + auto resHandle = std::make_unique(); + resHandle->CreatedFromData = false; + + auto umfRet = umfPoolByPtr(pMem, &resHandle->UMFPool); + if (umfRet != UMF_RESULT_SUCCESS || !resHandle->UMFPool) + return UR_RESULT_ERROR_UNKNOWN; + + umfRet = umfGetIPCHandle(pMem, &resHandle->UMFHandle, &resHandle->HandleSize); + if (umfRet != UMF_RESULT_SUCCESS || !resHandle->UMFHandle || + resHandle->HandleSize == 0) + return UR_RESULT_ERROR_UNKNOWN; + + *phIPCMem = resHandle.release(); + return UR_RESULT_SUCCESS; +} + +ur_result_t urIPCPutMemHandleExp(ur_context_handle_t, + ur_exp_ipc_mem_handle_t hIPCMem) { + auto umfRet = umfPutIPCHandle(hIPCMem->UMFHandle); + if (umfRet != UMF_RESULT_SUCCESS) + return UR_RESULT_ERROR_UNKNOWN; + std::free(hIPCMem); + return UR_RESULT_SUCCESS; +} + +ur_result_t urIPCOpenMemHandleExp(ur_context_handle_t, + ur_exp_ipc_mem_handle_t hIPCMem, + void **ppMem) { + umf_ipc_handler_handle_t umfIPCHandler; + auto umfRet = umfPoolGetIPCHandler(hIPCMem->UMFPool, &umfIPCHandler); + if (umfRet != UMF_RESULT_SUCCESS || !umfIPCHandler) + return UR_RESULT_ERROR_UNKNOWN; + + umfRet = umfOpenIPCHandle(umfIPCHandler, hIPCMem->UMFHandle, ppMem); + return umfRet == UMF_RESULT_SUCCESS ? UR_RESULT_SUCCESS + : UR_RESULT_ERROR_UNKNOWN; +} + +ur_result_t urIPCCloseMemHandleExp(ur_context_handle_t, void *pMem) { + auto umfRet = umfCloseIPCHandle(pMem); + return umfRet == UMF_RESULT_SUCCESS ? UR_RESULT_SUCCESS + : UR_RESULT_ERROR_UNKNOWN; +} + +ur_result_t urIPCGetMemHandleDataExp(ur_context_handle_t, + ur_exp_ipc_mem_handle_t hIPCMem, + const void **ppIPCHandleData, + size_t *pIPCMemHandleDataSizeRet) { + if (ppIPCHandleData) + *ppIPCHandleData = hIPCMem->UMFHandle; + if (pIPCMemHandleDataSizeRet) + *pIPCMemHandleDataSizeRet = hIPCMem->HandleSize; + return UR_RESULT_SUCCESS; +} + +ur_result_t urIPCCreateMemHandleFromDataExp(ur_context_handle_t hContext, + ur_device_handle_t hDevice, + const void *pIPCMemHandleData, + size_t ipcMemHandleDataSize, + ur_exp_ipc_mem_handle_t *phIPCMem) { + auto *pool = hContext->DefaultPool.getPool(usm::pool_descriptor{ + &hContext->DefaultPool, hContext, hDevice, UR_USM_TYPE_DEVICE, false}); + if (!pool) + return UR_RESULT_ERROR_INVALID_CONTEXT; + umf_memory_pool_handle_t umfPool = pool->UmfPool.get(); + + size_t umfHandleSize = 0; + auto umfRet = umfPoolGetIPCHandleSize(umfPool, &umfHandleSize); + if (umfRet != UMF_RESULT_SUCCESS || umfHandleSize == 0) + return UR_RESULT_ERROR_UNKNOWN; + + if (umfHandleSize != ipcMemHandleDataSize) + return UR_RESULT_ERROR_INVALID_VALUE; + + auto resHandle = std::make_unique(); + resHandle->UMFPool = umfPool; + resHandle->UMFHandle = + reinterpret_cast(std::malloc(umfHandleSize)); + std::memcpy(resHandle->UMFHandle, pIPCMemHandleData, umfHandleSize); + resHandle->HandleSize = umfHandleSize; + resHandle->CreatedFromData = true; + *phIPCMem = resHandle.release(); + return UR_RESULT_SUCCESS; +} + +ur_result_t urIPCDestroyMemHandleExp(ur_context_handle_t, + ur_exp_ipc_mem_handle_t hIPCMem) { + if (!hIPCMem->CreatedFromData) + return UR_RESULT_ERROR_INVALID_VALUE; + std::free(hIPCMem); + return UR_RESULT_SUCCESS; +} + } // namespace ur::level_zero // If indirect access tracking is enabled then performs reference counting, diff --git a/unified-runtime/source/adapters/level_zero/memory.hpp b/unified-runtime/source/adapters/level_zero/memory.hpp index f58f189b21c77..052aa5d9504da 100644 --- a/unified-runtime/source/adapters/level_zero/memory.hpp +++ b/unified-runtime/source/adapters/level_zero/memory.hpp @@ -25,6 +25,7 @@ #include "program.hpp" #include "queue.hpp" #include "sampler.hpp" +#include struct ur_device_handle_t_; @@ -243,6 +244,13 @@ struct ur_image final : ur_mem_handle_t_ { ze_image_handle_t ZeImage; }; +struct ur_exp_ipc_mem_handle_t_ { + umf_memory_pool_handle_t UMFPool; + umf_ipc_handle_t UMFHandle = nullptr; + size_t HandleSize = 0; + bool CreatedFromData = false; +}; + template ur_result_t createUrMemFromZeImage(ur_context_handle_t Context, ze_image_handle_t ZeImage, diff --git a/unified-runtime/source/adapters/level_zero/ur_interface_loader.cpp b/unified-runtime/source/adapters/level_zero/ur_interface_loader.cpp index 13d7274e7aebf..a98471f61f64c 100644 --- a/unified-runtime/source/adapters/level_zero/ur_interface_loader.cpp +++ b/unified-runtime/source/adapters/level_zero/ur_interface_loader.cpp @@ -257,6 +257,25 @@ UR_APIEXPORT ur_result_t UR_APICALL urGetEventProcAddrTable( return result; } +UR_APIEXPORT ur_result_t UR_APICALL urGetIPCExpProcAddrTable( + ur_api_version_t version, ur_ipc_exp_dditable_t *pDdiTable) { + auto result = validateProcInputs(version, pDdiTable); + if (UR_RESULT_SUCCESS != result) { + return result; + } + + pDdiTable->pfnGetMemHandleExp = ur::level_zero::urIPCGetMemHandleExp; + pDdiTable->pfnPutMemHandleExp = ur::level_zero::urIPCPutMemHandleExp; + pDdiTable->pfnOpenMemHandleExp = ur::level_zero::urIPCOpenMemHandleExp; + pDdiTable->pfnCloseMemHandleExp = ur::level_zero::urIPCCloseMemHandleExp; + pDdiTable->pfnGetMemHandleDataExp = ur::level_zero::urIPCGetMemHandleDataExp; + pDdiTable->pfnCreateMemHandleFromDataExp = + ur::level_zero::urIPCCreateMemHandleFromDataExp; + pDdiTable->pfnDestroyMemHandleExp = ur::level_zero::urIPCDestroyMemHandleExp; + + return result; +} + UR_APIEXPORT ur_result_t UR_APICALL urGetKernelProcAddrTable( ur_api_version_t version, ur_kernel_dditable_t *pDdiTable) { auto result = validateProcInputs(version, pDdiTable); @@ -595,6 +614,10 @@ ur_result_t populateDdiTable(ur_dditable_t *ddi) { NAMESPACE_::urGetEventProcAddrTable(UR_API_VERSION_CURRENT, &ddi->Event); if (result != UR_RESULT_SUCCESS) return result; + result = NAMESPACE_::urGetIPCExpProcAddrTable(UR_API_VERSION_CURRENT, + &ddi->IPCExp); + if (result != UR_RESULT_SUCCESS) + return result; result = NAMESPACE_::urGetKernelProcAddrTable(UR_API_VERSION_CURRENT, &ddi->Kernel); if (result != UR_RESULT_SUCCESS) diff --git a/unified-runtime/source/adapters/level_zero/ur_interface_loader.hpp b/unified-runtime/source/adapters/level_zero/ur_interface_loader.hpp index df8e93c1f768a..7ab153caa04bf 100644 --- a/unified-runtime/source/adapters/level_zero/ur_interface_loader.hpp +++ b/unified-runtime/source/adapters/level_zero/ur_interface_loader.hpp @@ -768,6 +768,25 @@ urCommandBufferGetNativeHandleExp(ur_exp_command_buffer_handle_t hCommandBuffer, ur_result_t urEnqueueTimestampRecordingExp( ur_queue_handle_t hQueue, bool blocking, uint32_t numEventsInWaitList, const ur_event_handle_t *phEventWaitList, ur_event_handle_t *phEvent); +ur_result_t urIPCGetMemHandleExp(ur_context_handle_t hContext, void *pMem, + ur_exp_ipc_mem_handle_t *phIPCMem); +ur_result_t urIPCPutMemHandleExp(ur_context_handle_t hContext, + ur_exp_ipc_mem_handle_t hIPCMem); +ur_result_t urIPCOpenMemHandleExp(ur_context_handle_t hContext, + ur_exp_ipc_mem_handle_t hIPCMem, + void **ppMem); +ur_result_t urIPCCloseMemHandleExp(ur_context_handle_t hContext, void *pMem); +ur_result_t urIPCGetMemHandleDataExp(ur_context_handle_t hContext, + ur_exp_ipc_mem_handle_t hIPCMem, + const void **ppIPCHandleData, + size_t *pIPCMemHandleDataSizeRet); +ur_result_t urIPCCreateMemHandleFromDataExp(ur_context_handle_t hContext, + ur_device_handle_t hDevice, + const void *ipcMemHandleData, + size_t ipcMemHandleDataSize, + ur_exp_ipc_mem_handle_t *phIPCMem); +ur_result_t urIPCDestroyMemHandleExp(ur_context_handle_t hContext, + ur_exp_ipc_mem_handle_t hIPCMem); ur_result_t urMemoryExportAllocExportableMemoryExp( ur_context_handle_t hContext, ur_device_handle_t hDevice, size_t alignment, size_t size, ur_exp_external_mem_type_t handleTypeToExport, void **ppMem); diff --git a/unified-runtime/source/adapters/level_zero/usm.hpp b/unified-runtime/source/adapters/level_zero/usm.hpp index aa7558926b5ed..d3e2e344f149f 100644 --- a/unified-runtime/source/adapters/level_zero/usm.hpp +++ b/unified-runtime/source/adapters/level_zero/usm.hpp @@ -84,12 +84,12 @@ struct ur_usm_pool_handle_t_ : ur_object { size_t getPeakReservedSize(); size_t getTotalUsedSize(); size_t getPeakUsedSize(); + UsmPool *getPool(const usm::pool_descriptor &Desc); ur_context_handle_t Context; ur::RefCount RefCount; private: - UsmPool *getPool(const usm::pool_descriptor &Desc); usm::pool_manager PoolManager; AllocationStats AllocStats; }; diff --git a/unified-runtime/source/adapters/level_zero/v2/memory.cpp b/unified-runtime/source/adapters/level_zero/v2/memory.cpp index 1b6855e630994..1375723f75be9 100644 --- a/unified-runtime/source/adapters/level_zero/v2/memory.cpp +++ b/unified-runtime/source/adapters/level_zero/v2/memory.cpp @@ -775,4 +775,100 @@ ur_result_t urMemImageGetInfo(ur_mem_handle_t /*hMemory*/, return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; } +ur_result_t urIPCGetMemHandleExp(ur_context_handle_t, void *pMem, + ur_exp_ipc_mem_handle_t *phIPCMem) { + auto resHandle = std::make_unique(); + resHandle->CreatedFromData = false; + + auto umfRet = umfPoolByPtr(pMem, &resHandle->UMFPool); + if (umfRet != UMF_RESULT_SUCCESS || !resHandle->UMFPool) + return UR_RESULT_ERROR_UNKNOWN; + + umfRet = umfGetIPCHandle(pMem, &resHandle->UMFHandle, &resHandle->HandleSize); + if (umfRet != UMF_RESULT_SUCCESS || !resHandle->UMFHandle || + resHandle->HandleSize == 0) + return UR_RESULT_ERROR_UNKNOWN; + + *phIPCMem = resHandle.release(); + return UR_RESULT_SUCCESS; +} + +ur_result_t urIPCPutMemHandleExp(ur_context_handle_t, + ur_exp_ipc_mem_handle_t hIPCMem) { + auto umfRet = umfPutIPCHandle(hIPCMem->UMFHandle); + if (umfRet != UMF_RESULT_SUCCESS) + return UR_RESULT_ERROR_UNKNOWN; + std::free(hIPCMem); + return UR_RESULT_SUCCESS; +} + +ur_result_t urIPCOpenMemHandleExp(ur_context_handle_t, + ur_exp_ipc_mem_handle_t hIPCMem, + void **ppMem) { + umf_ipc_handler_handle_t umfIPCHandler; + auto umfRet = umfPoolGetIPCHandler(hIPCMem->UMFPool, &umfIPCHandler); + if (umfRet != UMF_RESULT_SUCCESS || !umfIPCHandler) + return UR_RESULT_ERROR_UNKNOWN; + + umfRet = umfOpenIPCHandle(umfIPCHandler, hIPCMem->UMFHandle, ppMem); + return umfRet == UMF_RESULT_SUCCESS ? UR_RESULT_SUCCESS + : UR_RESULT_ERROR_UNKNOWN; +} + +ur_result_t urIPCCloseMemHandleExp(ur_context_handle_t, void *pMem) { + auto umfRet = umfCloseIPCHandle(pMem); + return umfRet == UMF_RESULT_SUCCESS ? UR_RESULT_SUCCESS + : UR_RESULT_ERROR_UNKNOWN; +} + +ur_result_t urIPCGetMemHandleDataExp(ur_context_handle_t, + ur_exp_ipc_mem_handle_t hIPCMem, + const void **ppIPCHandleData, + size_t *pIPCMemHandleDataSizeRet) { + if (ppIPCHandleData) + *ppIPCHandleData = hIPCMem->UMFHandle; + if (pIPCMemHandleDataSizeRet) + *pIPCMemHandleDataSizeRet = hIPCMem->HandleSize; + return UR_RESULT_SUCCESS; +} + +ur_result_t urIPCCreateMemHandleFromDataExp(ur_context_handle_t hContext, + ur_device_handle_t hDevice, + const void *pIPCMemHandleData, + size_t ipcMemHandleDataSize, + ur_exp_ipc_mem_handle_t *phIPCMem) { + auto *pool = hContext->getDefaultUSMPool()->getPool( + usm::pool_descriptor{hContext->getDefaultUSMPool(), hContext, hDevice, + UR_USM_TYPE_DEVICE, false}); + if (!pool) + return UR_RESULT_ERROR_INVALID_CONTEXT; + umf_memory_pool_handle_t umfPool = pool->umfPool.get(); + + size_t umfHandleSize = 0; + auto umfRet = umfPoolGetIPCHandleSize(umfPool, &umfHandleSize); + if (umfRet != UMF_RESULT_SUCCESS || umfHandleSize == 0) + return UR_RESULT_ERROR_UNKNOWN; + + if (umfHandleSize != ipcMemHandleDataSize) + return UR_RESULT_ERROR_INVALID_VALUE; + + auto resHandle = std::make_unique(); + resHandle->UMFPool = umfPool; + resHandle->UMFHandle = + reinterpret_cast(std::malloc(umfHandleSize)); + std::memcpy(resHandle->UMFHandle, pIPCMemHandleData, umfHandleSize); + resHandle->HandleSize = umfHandleSize; + resHandle->CreatedFromData = true; + *phIPCMem = resHandle.release(); + return UR_RESULT_SUCCESS; +} + +ur_result_t urIPCDestroyMemHandleExp(ur_context_handle_t, + ur_exp_ipc_mem_handle_t hIPCMem) { + if (!hIPCMem->CreatedFromData) + return UR_RESULT_ERROR_INVALID_VALUE; + std::free(hIPCMem); + return UR_RESULT_SUCCESS; +} + } // namespace ur::level_zero diff --git a/unified-runtime/source/adapters/level_zero/v2/memory.hpp b/unified-runtime/source/adapters/level_zero/v2/memory.hpp index 61b0a00f4043b..9abfcd569fed6 100644 --- a/unified-runtime/source/adapters/level_zero/v2/memory.hpp +++ b/unified-runtime/source/adapters/level_zero/v2/memory.hpp @@ -20,6 +20,7 @@ #include "command_list_manager.hpp" #include "common.hpp" #include "common/ur_ref_count.hpp" +#include using usm_unique_ptr_t = std::unique_ptr>; @@ -292,3 +293,10 @@ struct ur_mem_handle_t_ : ur::handle_base { ur_mem_sub_buffer_t, ur_mem_image_t> mem; }; + +struct ur_exp_ipc_mem_handle_t_ { + umf_memory_pool_handle_t UMFPool; + umf_ipc_handle_t UMFHandle = nullptr; + size_t HandleSize = 0; + bool CreatedFromData = false; +}; diff --git a/unified-runtime/source/adapters/level_zero/v2/usm.hpp b/unified-runtime/source/adapters/level_zero/v2/usm.hpp index 825ecb5fcd8e3..ace4b7411e617 100644 --- a/unified-runtime/source/adapters/level_zero/v2/usm.hpp +++ b/unified-runtime/source/adapters/level_zero/v2/usm.hpp @@ -81,14 +81,14 @@ struct ur_usm_pool_handle_t_ : ur_object { size_t getTotalUsedSize(); size_t getPeakUsedSize(); + UsmPool *getPool(const usm::pool_descriptor &desc); + ur::RefCount RefCount; private: ur_context_handle_t hContext; usm::pool_manager poolManager; AllocationStats allocStats; - - UsmPool *getPool(const usm::pool_descriptor &desc); }; struct UsmPool { diff --git a/unified-runtime/source/adapters/mock/ur_mock.cpp b/unified-runtime/source/adapters/mock/ur_mock.cpp index 142a706146a9b..bd2112793a3a1 100644 --- a/unified-runtime/source/adapters/mock/ur_mock.cpp +++ b/unified-runtime/source/adapters/mock/ur_mock.cpp @@ -103,6 +103,7 @@ context_t::context_t() { urGetContextProcAddrTable(version, &urDdiTable.Context); urGetEnqueueProcAddrTable(version, &urDdiTable.Enqueue); urGetEnqueueExpProcAddrTable(version, &urDdiTable.EnqueueExp); + urGetIPCExpProcAddrTable(version, &urDdiTable.IPCExp); urGetEventProcAddrTable(version, &urDdiTable.Event); urGetKernelProcAddrTable(version, &urDdiTable.Kernel); urGetMemProcAddrTable(version, &urDdiTable.Mem); diff --git a/unified-runtime/source/adapters/mock/ur_mockddi.cpp b/unified-runtime/source/adapters/mock/ur_mockddi.cpp index 7956f048db92e..0cfc348b92866 100644 --- a/unified-runtime/source/adapters/mock/ur_mockddi.cpp +++ b/unified-runtime/source/adapters/mock/ur_mockddi.cpp @@ -11304,6 +11304,334 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueTimestampRecordingExp( return exceptionToResult(std::current_exception()); } +/////////////////////////////////////////////////////////////////////////////// +/// @brief Intercept function for urIPCGetMemHandleExp +__urdlllocal ur_result_t UR_APICALL urIPCGetMemHandleExp( + /// [in] handle of the context object + ur_context_handle_t hContext, + /// [in] pointer to device USM memory + void *pMem, + /// [out][alloc] pointer to the resulting IPC memory handle + ur_exp_ipc_mem_handle_t *phIPCMem) try { + ur_result_t result = UR_RESULT_SUCCESS; + + ur_ipc_get_mem_handle_exp_params_t params = {&hContext, &pMem, &phIPCMem}; + + auto beforeCallback = reinterpret_cast( + mock::getCallbacks().get_before_callback("urIPCGetMemHandleExp")); + if (beforeCallback) { + result = beforeCallback(¶ms); + if (result != UR_RESULT_SUCCESS) { + return result; + } + } + + auto replaceCallback = reinterpret_cast( + mock::getCallbacks().get_replace_callback("urIPCGetMemHandleExp")); + if (replaceCallback) { + result = replaceCallback(¶ms); + } else { + + result = UR_RESULT_SUCCESS; + } + + if (result != UR_RESULT_SUCCESS) { + return result; + } + + auto afterCallback = reinterpret_cast( + mock::getCallbacks().get_after_callback("urIPCGetMemHandleExp")); + if (afterCallback) { + return afterCallback(¶ms); + } + + return result; +} catch (...) { + return exceptionToResult(std::current_exception()); +} + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Intercept function for urIPCPutMemHandleExp +__urdlllocal ur_result_t UR_APICALL urIPCPutMemHandleExp( + /// [in] handle of the context object + ur_context_handle_t hContext, + /// [in] the IPC memory handle + ur_exp_ipc_mem_handle_t hIPCMem) try { + ur_result_t result = UR_RESULT_SUCCESS; + + ur_ipc_put_mem_handle_exp_params_t params = {&hContext, &hIPCMem}; + + auto beforeCallback = reinterpret_cast( + mock::getCallbacks().get_before_callback("urIPCPutMemHandleExp")); + if (beforeCallback) { + result = beforeCallback(¶ms); + if (result != UR_RESULT_SUCCESS) { + return result; + } + } + + auto replaceCallback = reinterpret_cast( + mock::getCallbacks().get_replace_callback("urIPCPutMemHandleExp")); + if (replaceCallback) { + result = replaceCallback(¶ms); + } else { + + result = UR_RESULT_SUCCESS; + } + + if (result != UR_RESULT_SUCCESS) { + return result; + } + + auto afterCallback = reinterpret_cast( + mock::getCallbacks().get_after_callback("urIPCPutMemHandleExp")); + if (afterCallback) { + return afterCallback(¶ms); + } + + return result; +} catch (...) { + return exceptionToResult(std::current_exception()); +} + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Intercept function for urIPCOpenMemHandleExp +__urdlllocal ur_result_t UR_APICALL urIPCOpenMemHandleExp( + /// [in] handle of the context object + ur_context_handle_t hContext, + /// [in] pointer to the resulting IPC memory handle + ur_exp_ipc_mem_handle_t hIPCMem, + /// [out] pointer to a pointer to device USM memory + void **ppMem) try { + ur_result_t result = UR_RESULT_SUCCESS; + + ur_ipc_open_mem_handle_exp_params_t params = {&hContext, &hIPCMem, &ppMem}; + + auto beforeCallback = reinterpret_cast( + mock::getCallbacks().get_before_callback("urIPCOpenMemHandleExp")); + if (beforeCallback) { + result = beforeCallback(¶ms); + if (result != UR_RESULT_SUCCESS) { + return result; + } + } + + auto replaceCallback = reinterpret_cast( + mock::getCallbacks().get_replace_callback("urIPCOpenMemHandleExp")); + if (replaceCallback) { + result = replaceCallback(¶ms); + } else { + + result = UR_RESULT_SUCCESS; + } + + if (result != UR_RESULT_SUCCESS) { + return result; + } + + auto afterCallback = reinterpret_cast( + mock::getCallbacks().get_after_callback("urIPCOpenMemHandleExp")); + if (afterCallback) { + return afterCallback(¶ms); + } + + return result; +} catch (...) { + return exceptionToResult(std::current_exception()); +} + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Intercept function for urIPCCloseMemHandleExp +__urdlllocal ur_result_t UR_APICALL urIPCCloseMemHandleExp( + /// [in] handle of the context object + ur_context_handle_t hContext, + /// [in] pointer to device USM memory opened through urIPCOpenMemHandleExp + void *pMem) try { + ur_result_t result = UR_RESULT_SUCCESS; + + ur_ipc_close_mem_handle_exp_params_t params = {&hContext, &pMem}; + + auto beforeCallback = reinterpret_cast( + mock::getCallbacks().get_before_callback("urIPCCloseMemHandleExp")); + if (beforeCallback) { + result = beforeCallback(¶ms); + if (result != UR_RESULT_SUCCESS) { + return result; + } + } + + auto replaceCallback = reinterpret_cast( + mock::getCallbacks().get_replace_callback("urIPCCloseMemHandleExp")); + if (replaceCallback) { + result = replaceCallback(¶ms); + } else { + + result = UR_RESULT_SUCCESS; + } + + if (result != UR_RESULT_SUCCESS) { + return result; + } + + auto afterCallback = reinterpret_cast( + mock::getCallbacks().get_after_callback("urIPCCloseMemHandleExp")); + if (afterCallback) { + return afterCallback(¶ms); + } + + return result; +} catch (...) { + return exceptionToResult(std::current_exception()); +} + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Intercept function for urIPCGetMemHandleDataExp +__urdlllocal ur_result_t UR_APICALL urIPCGetMemHandleDataExp( + /// [in] handle of the context object + ur_context_handle_t hContext, + /// [in] the IPC memory handle + ur_exp_ipc_mem_handle_t hIPCMem, + /// [out][optional] a pointer to the IPC memory handle data + const void **ppIPCHandleData, + /// [out][optional] size of the resulting IPC memory handle data + size_t *pIPCMemHandleDataSizeRet) try { + ur_result_t result = UR_RESULT_SUCCESS; + + ur_ipc_get_mem_handle_data_exp_params_t params = { + &hContext, &hIPCMem, &ppIPCHandleData, &pIPCMemHandleDataSizeRet}; + + auto beforeCallback = reinterpret_cast( + mock::getCallbacks().get_before_callback("urIPCGetMemHandleDataExp")); + if (beforeCallback) { + result = beforeCallback(¶ms); + if (result != UR_RESULT_SUCCESS) { + return result; + } + } + + auto replaceCallback = reinterpret_cast( + mock::getCallbacks().get_replace_callback("urIPCGetMemHandleDataExp")); + if (replaceCallback) { + result = replaceCallback(¶ms); + } else { + + result = UR_RESULT_SUCCESS; + } + + if (result != UR_RESULT_SUCCESS) { + return result; + } + + auto afterCallback = reinterpret_cast( + mock::getCallbacks().get_after_callback("urIPCGetMemHandleDataExp")); + if (afterCallback) { + return afterCallback(¶ms); + } + + return result; +} catch (...) { + return exceptionToResult(std::current_exception()); +} + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Intercept function for urIPCCreateMemHandleFromDataExp +__urdlllocal ur_result_t UR_APICALL urIPCCreateMemHandleFromDataExp( + /// [in] handle of the context object + ur_context_handle_t hContext, + /// [in] handle of the device object the corresponding USM device memory + /// was allocated on + ur_device_handle_t hDevice, + /// [in] the IPC memory handle data + const void *ipcMemHandleData, + /// [in] size of the IPC memory handle data + size_t ipcMemHandleDataSize, + /// [out] the IPC memory handle + ur_exp_ipc_mem_handle_t *phIPCMem) try { + ur_result_t result = UR_RESULT_SUCCESS; + + ur_ipc_create_mem_handle_from_data_exp_params_t params = { + &hContext, &hDevice, &ipcMemHandleData, &ipcMemHandleDataSize, &phIPCMem}; + + auto beforeCallback = reinterpret_cast( + mock::getCallbacks().get_before_callback( + "urIPCCreateMemHandleFromDataExp")); + if (beforeCallback) { + result = beforeCallback(¶ms); + if (result != UR_RESULT_SUCCESS) { + return result; + } + } + + auto replaceCallback = reinterpret_cast( + mock::getCallbacks().get_replace_callback( + "urIPCCreateMemHandleFromDataExp")); + if (replaceCallback) { + result = replaceCallback(¶ms); + } else { + + result = UR_RESULT_SUCCESS; + } + + if (result != UR_RESULT_SUCCESS) { + return result; + } + + auto afterCallback = reinterpret_cast( + mock::getCallbacks().get_after_callback( + "urIPCCreateMemHandleFromDataExp")); + if (afterCallback) { + return afterCallback(¶ms); + } + + return result; +} catch (...) { + return exceptionToResult(std::current_exception()); +} + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Intercept function for urIPCDestroyMemHandleExp +__urdlllocal ur_result_t UR_APICALL urIPCDestroyMemHandleExp( + /// [in] handle of the context object + ur_context_handle_t hContext, + /// [in] the IPC memory handle + ur_exp_ipc_mem_handle_t hIPCMem) try { + ur_result_t result = UR_RESULT_SUCCESS; + + ur_ipc_destroy_mem_handle_exp_params_t params = {&hContext, &hIPCMem}; + + auto beforeCallback = reinterpret_cast( + mock::getCallbacks().get_before_callback("urIPCDestroyMemHandleExp")); + if (beforeCallback) { + result = beforeCallback(¶ms); + if (result != UR_RESULT_SUCCESS) { + return result; + } + } + + auto replaceCallback = reinterpret_cast( + mock::getCallbacks().get_replace_callback("urIPCDestroyMemHandleExp")); + if (replaceCallback) { + result = replaceCallback(¶ms); + } else { + + result = UR_RESULT_SUCCESS; + } + + if (result != UR_RESULT_SUCCESS) { + return result; + } + + auto afterCallback = reinterpret_cast( + mock::getCallbacks().get_after_callback("urIPCDestroyMemHandleExp")); + if (afterCallback) { + return afterCallback(¶ms); + } + + return result; +} catch (...) { + return exceptionToResult(std::current_exception()); +} + /////////////////////////////////////////////////////////////////////////////// /// @brief Intercept function for urMemoryExportAllocExportableMemoryExp __urdlllocal ur_result_t UR_APICALL urMemoryExportAllocExportableMemoryExp( @@ -12481,6 +12809,47 @@ UR_DLLEXPORT ur_result_t UR_APICALL urGetEventProcAddrTable( return exceptionToResult(std::current_exception()); } +/////////////////////////////////////////////////////////////////////////////// +/// @brief Exported function for filling application's IPCExp table +/// with current process' addresses +/// +/// @returns +/// - ::UR_RESULT_SUCCESS +/// - ::UR_RESULT_ERROR_INVALID_NULL_POINTER +/// - ::UR_RESULT_ERROR_UNSUPPORTED_VERSION +UR_DLLEXPORT ur_result_t UR_APICALL urGetIPCExpProcAddrTable( + /// [in] API version requested + ur_api_version_t version, + /// [in,out] pointer to table of DDI function pointers + ur_ipc_exp_dditable_t *pDdiTable) try { + if (nullptr == pDdiTable) + return UR_RESULT_ERROR_INVALID_NULL_POINTER; + + if (driver::d_context.version < version) + return UR_RESULT_ERROR_UNSUPPORTED_VERSION; + + ur_result_t result = UR_RESULT_SUCCESS; + + pDdiTable->pfnGetMemHandleExp = driver::urIPCGetMemHandleExp; + + pDdiTable->pfnPutMemHandleExp = driver::urIPCPutMemHandleExp; + + pDdiTable->pfnOpenMemHandleExp = driver::urIPCOpenMemHandleExp; + + pDdiTable->pfnCloseMemHandleExp = driver::urIPCCloseMemHandleExp; + + pDdiTable->pfnGetMemHandleDataExp = driver::urIPCGetMemHandleDataExp; + + pDdiTable->pfnCreateMemHandleFromDataExp = + driver::urIPCCreateMemHandleFromDataExp; + + pDdiTable->pfnDestroyMemHandleExp = driver::urIPCDestroyMemHandleExp; + + return result; +} catch (...) { + return exceptionToResult(std::current_exception()); +} + /////////////////////////////////////////////////////////////////////////////// /// @brief Exported function for filling application's Kernel table /// with current process' addresses diff --git a/unified-runtime/source/adapters/native_cpu/device.cpp b/unified-runtime/source/adapters/native_cpu/device.cpp index 369b4cd7ed013..4fed1565f8cfd 100644 --- a/unified-runtime/source/adapters/native_cpu/device.cpp +++ b/unified-runtime/source/adapters/native_cpu/device.cpp @@ -376,6 +376,8 @@ UR_APIEXPORT ur_result_t UR_APICALL urDeviceGetInfo(ur_device_handle_t hDevice, case UR_DEVICE_INFO_2D_BLOCK_ARRAY_CAPABILITIES_EXP: return ReturnValue( static_cast(0)); + case UR_DEVICE_INFO_IPC_MEMORY_SUPPORT_EXP: + return ReturnValue(false); case UR_DEVICE_INFO_ATOMIC_FENCE_ORDER_CAPABILITIES: { // Currently for Native CPU fences are implemented using OCK // builtins, so we have different capabilities than atomic operations diff --git a/unified-runtime/source/adapters/native_cpu/memory.cpp b/unified-runtime/source/adapters/native_cpu/memory.cpp index 67eb95f3d9523..a026205eea551 100644 --- a/unified-runtime/source/adapters/native_cpu/memory.cpp +++ b/unified-runtime/source/adapters/native_cpu/memory.cpp @@ -138,3 +138,39 @@ UR_APIEXPORT ur_result_t UR_APICALL urMemImageGetInfo( DIE_NO_IMPLEMENTATION; } + +UR_APIEXPORT ur_result_t UR_APICALL +urIPCGetMemHandleExp(ur_context_handle_t, void *, ur_exp_ipc_mem_handle_t *) { + return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; +} + +UR_APIEXPORT ur_result_t UR_APICALL +urIPCPutMemHandleExp(ur_context_handle_t, ur_exp_ipc_mem_handle_t) { + return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; +} + +UR_APIEXPORT ur_result_t UR_APICALL +urIPCOpenMemHandleExp(ur_context_handle_t, ur_exp_ipc_mem_handle_t, void **) { + return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; +} + +UR_APIEXPORT ur_result_t UR_APICALL urIPCCloseMemHandleExp(ur_context_handle_t, + void *) { + return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; +} + +UR_APIEXPORT ur_result_t UR_APICALL urIPCGetMemHandleDataExp( + ur_context_handle_t, ur_exp_ipc_mem_handle_t, const void **, size_t *) { + return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; +} + +UR_APIEXPORT ur_result_t UR_APICALL urIPCCreateMemHandleFromDataExp( + ur_context_handle_t, ur_device_handle_t, const void *, size_t, + ur_exp_ipc_mem_handle_t *) { + return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; +} + +UR_APIEXPORT ur_result_t UR_APICALL +urIPCDestroyMemHandleExp(ur_context_handle_t, ur_exp_ipc_mem_handle_t) { + return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; +} diff --git a/unified-runtime/source/adapters/native_cpu/memory.hpp b/unified-runtime/source/adapters/native_cpu/memory.hpp index ca6e3e77f5e87..6285287e2457b 100644 --- a/unified-runtime/source/adapters/native_cpu/memory.hpp +++ b/unified-runtime/source/adapters/native_cpu/memory.hpp @@ -69,3 +69,6 @@ struct ur_buffer final : ur_mem_handle_t_ { size_t Origin; // only valid if Parent != nullptr } SubBuffer; }; + +// IPC is currently not supported in the native CPU adaptor. +struct ur_exp_ipc_mem_handle_t_ {}; diff --git a/unified-runtime/source/adapters/native_cpu/ur_interface_loader.cpp b/unified-runtime/source/adapters/native_cpu/ur_interface_loader.cpp index 3f6fe061b4917..c85880f99e08d 100644 --- a/unified-runtime/source/adapters/native_cpu/ur_interface_loader.cpp +++ b/unified-runtime/source/adapters/native_cpu/ur_interface_loader.cpp @@ -435,6 +435,24 @@ UR_DLLEXPORT ur_result_t UR_APICALL urGetEnqueueExpProcAddrTable( return UR_RESULT_SUCCESS; } +UR_DLLEXPORT ur_result_t UR_APICALL urGetIPCExpProcAddrTable( + ur_api_version_t version, ur_ipc_exp_dditable_t *pDdiTable) { + auto result = validateProcInputs(version, pDdiTable); + if (UR_RESULT_SUCCESS != result) { + return result; + } + + pDdiTable->pfnGetMemHandleExp = urIPCGetMemHandleExp; + pDdiTable->pfnPutMemHandleExp = urIPCPutMemHandleExp; + pDdiTable->pfnOpenMemHandleExp = urIPCOpenMemHandleExp; + pDdiTable->pfnCloseMemHandleExp = urIPCCloseMemHandleExp; + pDdiTable->pfnGetMemHandleDataExp = urIPCGetMemHandleDataExp; + pDdiTable->pfnCreateMemHandleFromDataExp = urIPCCreateMemHandleFromDataExp; + pDdiTable->pfnDestroyMemHandleExp = urIPCDestroyMemHandleExp; + + return UR_RESULT_SUCCESS; +} + UR_DLLEXPORT ur_result_t UR_APICALL urGetProgramExpProcAddrTable( ur_api_version_t version, ur_program_exp_dditable_t *pDdiTable) { auto result = validateProcInputs(version, pDdiTable); @@ -457,6 +475,7 @@ UR_DLLEXPORT ur_result_t UR_APICALL urAllAddrTable(ur_api_version_t version, urGetContextProcAddrTable(version, &pDdiTable->Context); urGetEnqueueProcAddrTable(version, &pDdiTable->Enqueue); urGetEnqueueExpProcAddrTable(version, &pDdiTable->EnqueueExp); + urGetIPCExpProcAddrTable(version, &pDdiTable->IPCExp); urGetEventProcAddrTable(version, &pDdiTable->Event); urGetKernelProcAddrTable(version, &pDdiTable->Kernel); urGetMemProcAddrTable(version, &pDdiTable->Mem); diff --git a/unified-runtime/source/adapters/offload/memory.cpp b/unified-runtime/source/adapters/offload/memory.cpp index e27a032a61451..827300cba98b6 100644 --- a/unified-runtime/source/adapters/offload/memory.cpp +++ b/unified-runtime/source/adapters/offload/memory.cpp @@ -142,3 +142,39 @@ UR_APIEXPORT ur_result_t UR_APICALL urMemBufferPartition( return urMemRetain(hBuffer); } + +UR_APIEXPORT ur_result_t UR_APICALL +urIPCGetMemHandleExp(ur_context_handle_t, void *, ur_exp_ipc_mem_handle_t *) { + return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; +} + +UR_APIEXPORT ur_result_t UR_APICALL +urIPCPutMemHandleExp(ur_context_handle_t, ur_exp_ipc_mem_handle_t) { + return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; +} + +UR_APIEXPORT ur_result_t UR_APICALL +urIPCOpenMemHandleExp(ur_context_handle_t, ur_exp_ipc_mem_handle_t, void **) { + return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; +} + +UR_APIEXPORT ur_result_t UR_APICALL urIPCCloseMemHandleExp(ur_context_handle_t, + void *) { + return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; +} + +UR_APIEXPORT ur_result_t UR_APICALL urIPCGetMemHandleDataExp( + ur_context_handle_t, ur_exp_ipc_mem_handle_t, const void **, size_t *) { + return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; +} + +UR_APIEXPORT ur_result_t UR_APICALL urIPCCreateMemHandleFromDataExp( + ur_context_handle_t, ur_device_handle_t, const void *, size_t, + ur_exp_ipc_mem_handle_t *) { + return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; +} + +UR_APIEXPORT ur_result_t UR_APICALL +urIPCDestroyMemHandleExp(ur_context_handle_t, ur_exp_ipc_mem_handle_t) { + return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; +} diff --git a/unified-runtime/source/adapters/offload/memory.hpp b/unified-runtime/source/adapters/offload/memory.hpp index 59b62ea12961a..a4742d7b288d3 100644 --- a/unified-runtime/source/adapters/offload/memory.hpp +++ b/unified-runtime/source/adapters/offload/memory.hpp @@ -117,3 +117,6 @@ struct ur_mem_handle_t_ : RefCounted { return nullptr; } }; + +// IPC is currently not supported in the offload adaptor. +struct ur_exp_ipc_mem_handle_t_ {}; diff --git a/unified-runtime/source/adapters/offload/ur_interface_loader.cpp b/unified-runtime/source/adapters/offload/ur_interface_loader.cpp index 17e5a74679511..1eac719c8bf8c 100644 --- a/unified-runtime/source/adapters/offload/ur_interface_loader.cpp +++ b/unified-runtime/source/adapters/offload/ur_interface_loader.cpp @@ -388,6 +388,24 @@ UR_DLLEXPORT ur_result_t UR_APICALL urGetEnqueueExpProcAddrTable( return UR_RESULT_SUCCESS; } +UR_DLLEXPORT ur_result_t UR_APICALL urGetIPCExpProcAddrTable( + ur_api_version_t version, ur_ipc_exp_dditable_t *pDdiTable) { + auto result = validateProcInputs(version, pDdiTable); + if (UR_RESULT_SUCCESS != result) { + return result; + } + + pDdiTable->pfnGetMemHandleExp = urIPCGetMemHandleExp; + pDdiTable->pfnPutMemHandleExp = urIPCPutMemHandleExp; + pDdiTable->pfnOpenMemHandleExp = urIPCOpenMemHandleExp; + pDdiTable->pfnCloseMemHandleExp = urIPCCloseMemHandleExp; + pDdiTable->pfnGetMemHandleDataExp = urIPCGetMemHandleDataExp; + pDdiTable->pfnCreateMemHandleFromDataExp = urIPCCreateMemHandleFromDataExp; + pDdiTable->pfnDestroyMemHandleExp = urIPCDestroyMemHandleExp; + + return UR_RESULT_SUCCESS; +} + UR_DLLEXPORT ur_result_t UR_APICALL urGetProgramExpProcAddrTable( ur_api_version_t version, ur_program_exp_dditable_t *pDdiTable) { auto result = validateProcInputs(version, pDdiTable); @@ -410,6 +428,7 @@ UR_DLLEXPORT ur_result_t UR_APICALL urAllAddrTable(ur_api_version_t version, urGetContextProcAddrTable(version, &pDdiTable->Context); urGetEnqueueProcAddrTable(version, &pDdiTable->Enqueue); urGetEnqueueExpProcAddrTable(version, &pDdiTable->EnqueueExp); + urGetIPCExpProcAddrTable(version, &pDdiTable->IPCExp); urGetEventProcAddrTable(version, &pDdiTable->Event); urGetKernelProcAddrTable(version, &pDdiTable->Kernel); urGetMemProcAddrTable(version, &pDdiTable->Mem); diff --git a/unified-runtime/source/adapters/opencl/device.cpp b/unified-runtime/source/adapters/opencl/device.cpp index 4f697b05b5c88..d20f17a150aa6 100644 --- a/unified-runtime/source/adapters/opencl/device.cpp +++ b/unified-runtime/source/adapters/opencl/device.cpp @@ -1368,6 +1368,8 @@ UR_APIEXPORT ur_result_t UR_APICALL urDeviceGetInfo(ur_device_handle_t hDevice, return ReturnValue(UR_EXP_DEVICE_2D_BLOCK_ARRAY_CAPABILITY_FLAG_LOAD | UR_EXP_DEVICE_2D_BLOCK_ARRAY_CAPABILITY_FLAG_STORE); } + case UR_DEVICE_INFO_IPC_MEMORY_SUPPORT_EXP: + return ReturnValue(false); case UR_DEVICE_INFO_BFLOAT16_CONVERSIONS_NATIVE: { bool Supported = false; UR_RETURN_ON_FAILURE(hDevice->checkDeviceExtensions( diff --git a/unified-runtime/source/adapters/opencl/memory.cpp b/unified-runtime/source/adapters/opencl/memory.cpp index 19e9509987825..da056f83b1396 100644 --- a/unified-runtime/source/adapters/opencl/memory.cpp +++ b/unified-runtime/source/adapters/opencl/memory.cpp @@ -579,3 +579,39 @@ UR_APIEXPORT ur_result_t UR_APICALL urMemRelease(ur_mem_handle_t hMem) { } return UR_RESULT_SUCCESS; } + +UR_APIEXPORT ur_result_t UR_APICALL +urIPCGetMemHandleExp(ur_context_handle_t, void *, ur_exp_ipc_mem_handle_t *) { + return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; +} + +UR_APIEXPORT ur_result_t UR_APICALL +urIPCPutMemHandleExp(ur_context_handle_t, ur_exp_ipc_mem_handle_t) { + return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; +} + +UR_APIEXPORT ur_result_t UR_APICALL +urIPCOpenMemHandleExp(ur_context_handle_t, ur_exp_ipc_mem_handle_t, void **) { + return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; +} + +UR_APIEXPORT ur_result_t UR_APICALL urIPCCloseMemHandleExp(ur_context_handle_t, + void *) { + return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; +} + +UR_APIEXPORT ur_result_t UR_APICALL urIPCGetMemHandleDataExp( + ur_context_handle_t, ur_exp_ipc_mem_handle_t, const void **, size_t *) { + return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; +} + +UR_APIEXPORT ur_result_t UR_APICALL urIPCCreateMemHandleFromDataExp( + ur_context_handle_t, ur_device_handle_t, const void *, size_t, + ur_exp_ipc_mem_handle_t *) { + return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; +} + +UR_APIEXPORT ur_result_t UR_APICALL +urIPCDestroyMemHandleExp(ur_context_handle_t, ur_exp_ipc_mem_handle_t) { + return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; +} diff --git a/unified-runtime/source/adapters/opencl/memory.hpp b/unified-runtime/source/adapters/opencl/memory.hpp index 847ffafa76021..cc2a868a86a27 100644 --- a/unified-runtime/source/adapters/opencl/memory.hpp +++ b/unified-runtime/source/adapters/opencl/memory.hpp @@ -38,3 +38,6 @@ struct ur_mem_handle_t_ : ur::opencl::handle_base { ur_context_handle_t Ctx, ur_mem_handle_t &Mem); }; + +// IPC is currently not supported in the OpenCL adaptor. +struct ur_exp_ipc_mem_handle_t_ {}; diff --git a/unified-runtime/source/adapters/opencl/ur_interface_loader.cpp b/unified-runtime/source/adapters/opencl/ur_interface_loader.cpp index c619fa36b1ab0..405114b021c31 100644 --- a/unified-runtime/source/adapters/opencl/ur_interface_loader.cpp +++ b/unified-runtime/source/adapters/opencl/ur_interface_loader.cpp @@ -438,6 +438,24 @@ UR_DLLEXPORT ur_result_t UR_APICALL urGetEnqueueExpProcAddrTable( return UR_RESULT_SUCCESS; } +UR_DLLEXPORT ur_result_t UR_APICALL urGetIPCExpProcAddrTable( + ur_api_version_t version, ur_ipc_exp_dditable_t *pDdiTable) { + auto result = validateProcInputs(version, pDdiTable); + if (UR_RESULT_SUCCESS != result) { + return result; + } + + pDdiTable->pfnGetMemHandleExp = urIPCGetMemHandleExp; + pDdiTable->pfnPutMemHandleExp = urIPCPutMemHandleExp; + pDdiTable->pfnOpenMemHandleExp = urIPCOpenMemHandleExp; + pDdiTable->pfnCloseMemHandleExp = urIPCCloseMemHandleExp; + pDdiTable->pfnGetMemHandleDataExp = urIPCGetMemHandleDataExp; + pDdiTable->pfnCreateMemHandleFromDataExp = urIPCCreateMemHandleFromDataExp; + pDdiTable->pfnDestroyMemHandleExp = urIPCDestroyMemHandleExp; + + return UR_RESULT_SUCCESS; +} + UR_DLLEXPORT ur_result_t UR_APICALL urGetProgramExpProcAddrTable( ur_api_version_t version, ur_program_exp_dditable_t *pDdiTable) { auto result = validateProcInputs(version, pDdiTable); @@ -460,6 +478,7 @@ UR_DLLEXPORT ur_result_t UR_APICALL urAllAddrTable(ur_api_version_t version, urGetContextProcAddrTable(version, &pDdiTable->Context); urGetEnqueueProcAddrTable(version, &pDdiTable->Enqueue); urGetEnqueueExpProcAddrTable(version, &pDdiTable->EnqueueExp); + urGetIPCExpProcAddrTable(version, &pDdiTable->IPCExp); urGetEventProcAddrTable(version, &pDdiTable->Event); urGetKernelProcAddrTable(version, &pDdiTable->Kernel); urGetMemProcAddrTable(version, &pDdiTable->Mem); diff --git a/unified-runtime/source/loader/layers/tracing/ur_trcddi.cpp b/unified-runtime/source/loader/layers/tracing/ur_trcddi.cpp index d096d3895c385..f51c0be4e95dc 100644 --- a/unified-runtime/source/loader/layers/tracing/ur_trcddi.cpp +++ b/unified-runtime/source/loader/layers/tracing/ur_trcddi.cpp @@ -9574,6 +9574,283 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueTimestampRecordingExp( return result; } +/////////////////////////////////////////////////////////////////////////////// +/// @brief Intercept function for urIPCGetMemHandleExp +__urdlllocal ur_result_t UR_APICALL urIPCGetMemHandleExp( + /// [in] handle of the context object + ur_context_handle_t hContext, + /// [in] pointer to device USM memory + void *pMem, + /// [out][alloc] pointer to the resulting IPC memory handle + ur_exp_ipc_mem_handle_t *phIPCMem) { + auto pfnGetMemHandleExp = getContext()->urDdiTable.IPCExp.pfnGetMemHandleExp; + + if (nullptr == pfnGetMemHandleExp) + return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; + + ur_ipc_get_mem_handle_exp_params_t params = {&hContext, &pMem, &phIPCMem}; + uint64_t instance = getContext()->notify_begin( + UR_FUNCTION_IPC_GET_MEM_HANDLE_EXP, "urIPCGetMemHandleExp", ¶ms); + + auto &logger = getContext()->logger; + UR_LOG_L(logger, INFO, " ---> urIPCGetMemHandleExp\n"); + + ur_result_t result = pfnGetMemHandleExp(hContext, pMem, phIPCMem); + + getContext()->notify_end(UR_FUNCTION_IPC_GET_MEM_HANDLE_EXP, + "urIPCGetMemHandleExp", ¶ms, &result, instance); + + if (logger.getLevel() <= UR_LOGGER_LEVEL_INFO) { + std::ostringstream args_str; + ur::extras::printFunctionParams( + args_str, UR_FUNCTION_IPC_GET_MEM_HANDLE_EXP, ¶ms); + UR_LOG_L(logger, INFO, " <--- urIPCGetMemHandleExp({}) -> {};\n", + args_str.str(), result); + } + + return result; +} + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Intercept function for urIPCPutMemHandleExp +__urdlllocal ur_result_t UR_APICALL urIPCPutMemHandleExp( + /// [in] handle of the context object + ur_context_handle_t hContext, + /// [in] the IPC memory handle + ur_exp_ipc_mem_handle_t hIPCMem) { + auto pfnPutMemHandleExp = getContext()->urDdiTable.IPCExp.pfnPutMemHandleExp; + + if (nullptr == pfnPutMemHandleExp) + return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; + + ur_ipc_put_mem_handle_exp_params_t params = {&hContext, &hIPCMem}; + uint64_t instance = getContext()->notify_begin( + UR_FUNCTION_IPC_PUT_MEM_HANDLE_EXP, "urIPCPutMemHandleExp", ¶ms); + + auto &logger = getContext()->logger; + UR_LOG_L(logger, INFO, " ---> urIPCPutMemHandleExp\n"); + + ur_result_t result = pfnPutMemHandleExp(hContext, hIPCMem); + + getContext()->notify_end(UR_FUNCTION_IPC_PUT_MEM_HANDLE_EXP, + "urIPCPutMemHandleExp", ¶ms, &result, instance); + + if (logger.getLevel() <= UR_LOGGER_LEVEL_INFO) { + std::ostringstream args_str; + ur::extras::printFunctionParams( + args_str, UR_FUNCTION_IPC_PUT_MEM_HANDLE_EXP, ¶ms); + UR_LOG_L(logger, INFO, " <--- urIPCPutMemHandleExp({}) -> {};\n", + args_str.str(), result); + } + + return result; +} + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Intercept function for urIPCOpenMemHandleExp +__urdlllocal ur_result_t UR_APICALL urIPCOpenMemHandleExp( + /// [in] handle of the context object + ur_context_handle_t hContext, + /// [in] pointer to the resulting IPC memory handle + ur_exp_ipc_mem_handle_t hIPCMem, + /// [out] pointer to a pointer to device USM memory + void **ppMem) { + auto pfnOpenMemHandleExp = + getContext()->urDdiTable.IPCExp.pfnOpenMemHandleExp; + + if (nullptr == pfnOpenMemHandleExp) + return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; + + ur_ipc_open_mem_handle_exp_params_t params = {&hContext, &hIPCMem, &ppMem}; + uint64_t instance = getContext()->notify_begin( + UR_FUNCTION_IPC_OPEN_MEM_HANDLE_EXP, "urIPCOpenMemHandleExp", ¶ms); + + auto &logger = getContext()->logger; + UR_LOG_L(logger, INFO, " ---> urIPCOpenMemHandleExp\n"); + + ur_result_t result = pfnOpenMemHandleExp(hContext, hIPCMem, ppMem); + + getContext()->notify_end(UR_FUNCTION_IPC_OPEN_MEM_HANDLE_EXP, + "urIPCOpenMemHandleExp", ¶ms, &result, instance); + + if (logger.getLevel() <= UR_LOGGER_LEVEL_INFO) { + std::ostringstream args_str; + ur::extras::printFunctionParams( + args_str, UR_FUNCTION_IPC_OPEN_MEM_HANDLE_EXP, ¶ms); + UR_LOG_L(logger, INFO, " <--- urIPCOpenMemHandleExp({}) -> {};\n", + args_str.str(), result); + } + + return result; +} + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Intercept function for urIPCCloseMemHandleExp +__urdlllocal ur_result_t UR_APICALL urIPCCloseMemHandleExp( + /// [in] handle of the context object + ur_context_handle_t hContext, + /// [in] pointer to device USM memory opened through urIPCOpenMemHandleExp + void *pMem) { + auto pfnCloseMemHandleExp = + getContext()->urDdiTable.IPCExp.pfnCloseMemHandleExp; + + if (nullptr == pfnCloseMemHandleExp) + return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; + + ur_ipc_close_mem_handle_exp_params_t params = {&hContext, &pMem}; + uint64_t instance = getContext()->notify_begin( + UR_FUNCTION_IPC_CLOSE_MEM_HANDLE_EXP, "urIPCCloseMemHandleExp", ¶ms); + + auto &logger = getContext()->logger; + UR_LOG_L(logger, INFO, " ---> urIPCCloseMemHandleExp\n"); + + ur_result_t result = pfnCloseMemHandleExp(hContext, pMem); + + getContext()->notify_end(UR_FUNCTION_IPC_CLOSE_MEM_HANDLE_EXP, + "urIPCCloseMemHandleExp", ¶ms, &result, + instance); + + if (logger.getLevel() <= UR_LOGGER_LEVEL_INFO) { + std::ostringstream args_str; + ur::extras::printFunctionParams( + args_str, UR_FUNCTION_IPC_CLOSE_MEM_HANDLE_EXP, ¶ms); + UR_LOG_L(logger, INFO, " <--- urIPCCloseMemHandleExp({}) -> {};\n", + args_str.str(), result); + } + + return result; +} + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Intercept function for urIPCGetMemHandleDataExp +__urdlllocal ur_result_t UR_APICALL urIPCGetMemHandleDataExp( + /// [in] handle of the context object + ur_context_handle_t hContext, + /// [in] the IPC memory handle + ur_exp_ipc_mem_handle_t hIPCMem, + /// [out][optional] a pointer to the IPC memory handle data + const void **ppIPCHandleData, + /// [out][optional] size of the resulting IPC memory handle data + size_t *pIPCMemHandleDataSizeRet) { + auto pfnGetMemHandleDataExp = + getContext()->urDdiTable.IPCExp.pfnGetMemHandleDataExp; + + if (nullptr == pfnGetMemHandleDataExp) + return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; + + ur_ipc_get_mem_handle_data_exp_params_t params = { + &hContext, &hIPCMem, &ppIPCHandleData, &pIPCMemHandleDataSizeRet}; + uint64_t instance = + getContext()->notify_begin(UR_FUNCTION_IPC_GET_MEM_HANDLE_DATA_EXP, + "urIPCGetMemHandleDataExp", ¶ms); + + auto &logger = getContext()->logger; + UR_LOG_L(logger, INFO, " ---> urIPCGetMemHandleDataExp\n"); + + ur_result_t result = pfnGetMemHandleDataExp( + hContext, hIPCMem, ppIPCHandleData, pIPCMemHandleDataSizeRet); + + getContext()->notify_end(UR_FUNCTION_IPC_GET_MEM_HANDLE_DATA_EXP, + "urIPCGetMemHandleDataExp", ¶ms, &result, + instance); + + if (logger.getLevel() <= UR_LOGGER_LEVEL_INFO) { + std::ostringstream args_str; + ur::extras::printFunctionParams( + args_str, UR_FUNCTION_IPC_GET_MEM_HANDLE_DATA_EXP, ¶ms); + UR_LOG_L(logger, INFO, " <--- urIPCGetMemHandleDataExp({}) -> {};\n", + args_str.str(), result); + } + + return result; +} + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Intercept function for urIPCCreateMemHandleFromDataExp +__urdlllocal ur_result_t UR_APICALL urIPCCreateMemHandleFromDataExp( + /// [in] handle of the context object + ur_context_handle_t hContext, + /// [in] handle of the device object the corresponding USM device memory + /// was allocated on + ur_device_handle_t hDevice, + /// [in] the IPC memory handle data + const void *ipcMemHandleData, + /// [in] size of the IPC memory handle data + size_t ipcMemHandleDataSize, + /// [out] the IPC memory handle + ur_exp_ipc_mem_handle_t *phIPCMem) { + auto pfnCreateMemHandleFromDataExp = + getContext()->urDdiTable.IPCExp.pfnCreateMemHandleFromDataExp; + + if (nullptr == pfnCreateMemHandleFromDataExp) + return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; + + ur_ipc_create_mem_handle_from_data_exp_params_t params = { + &hContext, &hDevice, &ipcMemHandleData, &ipcMemHandleDataSize, &phIPCMem}; + uint64_t instance = getContext()->notify_begin( + UR_FUNCTION_IPC_CREATE_MEM_HANDLE_FROM_DATA_EXP, + "urIPCCreateMemHandleFromDataExp", ¶ms); + + auto &logger = getContext()->logger; + UR_LOG_L(logger, INFO, " ---> urIPCCreateMemHandleFromDataExp\n"); + + ur_result_t result = pfnCreateMemHandleFromDataExp( + hContext, hDevice, ipcMemHandleData, ipcMemHandleDataSize, phIPCMem); + + getContext()->notify_end(UR_FUNCTION_IPC_CREATE_MEM_HANDLE_FROM_DATA_EXP, + "urIPCCreateMemHandleFromDataExp", ¶ms, &result, + instance); + + if (logger.getLevel() <= UR_LOGGER_LEVEL_INFO) { + std::ostringstream args_str; + ur::extras::printFunctionParams( + args_str, UR_FUNCTION_IPC_CREATE_MEM_HANDLE_FROM_DATA_EXP, ¶ms); + UR_LOG_L(logger, INFO, + " <--- urIPCCreateMemHandleFromDataExp({}) -> {};\n", + args_str.str(), result); + } + + return result; +} + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Intercept function for urIPCDestroyMemHandleExp +__urdlllocal ur_result_t UR_APICALL urIPCDestroyMemHandleExp( + /// [in] handle of the context object + ur_context_handle_t hContext, + /// [in] the IPC memory handle + ur_exp_ipc_mem_handle_t hIPCMem) { + auto pfnDestroyMemHandleExp = + getContext()->urDdiTable.IPCExp.pfnDestroyMemHandleExp; + + if (nullptr == pfnDestroyMemHandleExp) + return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; + + ur_ipc_destroy_mem_handle_exp_params_t params = {&hContext, &hIPCMem}; + uint64_t instance = + getContext()->notify_begin(UR_FUNCTION_IPC_DESTROY_MEM_HANDLE_EXP, + "urIPCDestroyMemHandleExp", ¶ms); + + auto &logger = getContext()->logger; + UR_LOG_L(logger, INFO, " ---> urIPCDestroyMemHandleExp\n"); + + ur_result_t result = pfnDestroyMemHandleExp(hContext, hIPCMem); + + getContext()->notify_end(UR_FUNCTION_IPC_DESTROY_MEM_HANDLE_EXP, + "urIPCDestroyMemHandleExp", ¶ms, &result, + instance); + + if (logger.getLevel() <= UR_LOGGER_LEVEL_INFO) { + std::ostringstream args_str; + ur::extras::printFunctionParams( + args_str, UR_FUNCTION_IPC_DESTROY_MEM_HANDLE_EXP, ¶ms); + UR_LOG_L(logger, INFO, " <--- urIPCDestroyMemHandleExp({}) -> {};\n", + args_str.str(), result); + } + + return result; +} + /////////////////////////////////////////////////////////////////////////////// /// @brief Intercept function for urMemoryExportAllocExportableMemoryExp __urdlllocal ur_result_t UR_APICALL urMemoryExportAllocExportableMemoryExp( @@ -10783,6 +11060,59 @@ __urdlllocal ur_result_t UR_APICALL urGetEventProcAddrTable( return result; } /////////////////////////////////////////////////////////////////////////////// +/// @brief Exported function for filling application's IPCExp table +/// with current process' addresses +/// +/// @returns +/// - ::UR_RESULT_SUCCESS +/// - ::UR_RESULT_ERROR_INVALID_NULL_POINTER +/// - ::UR_RESULT_ERROR_UNSUPPORTED_VERSION +__urdlllocal ur_result_t UR_APICALL urGetIPCExpProcAddrTable( + /// [in] API version requested + ur_api_version_t version, + /// [in,out] pointer to table of DDI function pointers + ur_ipc_exp_dditable_t *pDdiTable) { + auto &dditable = ur_tracing_layer::getContext()->urDdiTable.IPCExp; + + if (nullptr == pDdiTable) + return UR_RESULT_ERROR_INVALID_NULL_POINTER; + + if (UR_MAJOR_VERSION(ur_tracing_layer::getContext()->version) != + UR_MAJOR_VERSION(version) || + UR_MINOR_VERSION(ur_tracing_layer::getContext()->version) > + UR_MINOR_VERSION(version)) + return UR_RESULT_ERROR_UNSUPPORTED_VERSION; + + ur_result_t result = UR_RESULT_SUCCESS; + + dditable.pfnGetMemHandleExp = pDdiTable->pfnGetMemHandleExp; + pDdiTable->pfnGetMemHandleExp = ur_tracing_layer::urIPCGetMemHandleExp; + + dditable.pfnPutMemHandleExp = pDdiTable->pfnPutMemHandleExp; + pDdiTable->pfnPutMemHandleExp = ur_tracing_layer::urIPCPutMemHandleExp; + + dditable.pfnOpenMemHandleExp = pDdiTable->pfnOpenMemHandleExp; + pDdiTable->pfnOpenMemHandleExp = ur_tracing_layer::urIPCOpenMemHandleExp; + + dditable.pfnCloseMemHandleExp = pDdiTable->pfnCloseMemHandleExp; + pDdiTable->pfnCloseMemHandleExp = ur_tracing_layer::urIPCCloseMemHandleExp; + + dditable.pfnGetMemHandleDataExp = pDdiTable->pfnGetMemHandleDataExp; + pDdiTable->pfnGetMemHandleDataExp = + ur_tracing_layer::urIPCGetMemHandleDataExp; + + dditable.pfnCreateMemHandleFromDataExp = + pDdiTable->pfnCreateMemHandleFromDataExp; + pDdiTable->pfnCreateMemHandleFromDataExp = + ur_tracing_layer::urIPCCreateMemHandleFromDataExp; + + dditable.pfnDestroyMemHandleExp = pDdiTable->pfnDestroyMemHandleExp; + pDdiTable->pfnDestroyMemHandleExp = + ur_tracing_layer::urIPCDestroyMemHandleExp; + + return result; +} +/////////////////////////////////////////////////////////////////////////////// /// @brief Exported function for filling application's Kernel table /// with current process' addresses /// @@ -11590,6 +11920,11 @@ ur_result_t context_t::init(ur_dditable_t *dditable, &dditable->Event); } + if (UR_RESULT_SUCCESS == result) { + result = ur_tracing_layer::urGetIPCExpProcAddrTable(UR_API_VERSION_CURRENT, + &dditable->IPCExp); + } + if (UR_RESULT_SUCCESS == result) { result = ur_tracing_layer::urGetKernelProcAddrTable(UR_API_VERSION_CURRENT, &dditable->Kernel); diff --git a/unified-runtime/source/loader/layers/validation/ur_valddi.cpp b/unified-runtime/source/loader/layers/validation/ur_valddi.cpp index 32dec6f1b25df..88b0bb4114363 100644 --- a/unified-runtime/source/loader/layers/validation/ur_valddi.cpp +++ b/unified-runtime/source/loader/layers/validation/ur_valddi.cpp @@ -10337,6 +10337,238 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueTimestampRecordingExp( return result; } +/////////////////////////////////////////////////////////////////////////////// +/// @brief Intercept function for urIPCGetMemHandleExp +__urdlllocal ur_result_t UR_APICALL urIPCGetMemHandleExp( + /// [in] handle of the context object + ur_context_handle_t hContext, + /// [in] pointer to device USM memory + void *pMem, + /// [out][alloc] pointer to the resulting IPC memory handle + ur_exp_ipc_mem_handle_t *phIPCMem) { + auto pfnGetMemHandleExp = getContext()->urDdiTable.IPCExp.pfnGetMemHandleExp; + + if (nullptr == pfnGetMemHandleExp) { + return UR_RESULT_ERROR_UNINITIALIZED; + } + + if (getContext()->enableParameterValidation) { + if (NULL == phIPCMem) + return UR_RESULT_ERROR_INVALID_NULL_POINTER; + + if (NULL == hContext) + return UR_RESULT_ERROR_INVALID_NULL_HANDLE; + } + + if (getContext()->enableLifetimeValidation && + !getContext()->refCountContext->isReferenceValid(hContext)) { + URLOG_CTX_INVALID_REFERENCE(hContext); + } + + ur_result_t result = pfnGetMemHandleExp(hContext, pMem, phIPCMem); + + return result; +} + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Intercept function for urIPCPutMemHandleExp +__urdlllocal ur_result_t UR_APICALL urIPCPutMemHandleExp( + /// [in] handle of the context object + ur_context_handle_t hContext, + /// [in] the IPC memory handle + ur_exp_ipc_mem_handle_t hIPCMem) { + auto pfnPutMemHandleExp = getContext()->urDdiTable.IPCExp.pfnPutMemHandleExp; + + if (nullptr == pfnPutMemHandleExp) { + return UR_RESULT_ERROR_UNINITIALIZED; + } + + if (getContext()->enableParameterValidation) { + if (NULL == hContext) + return UR_RESULT_ERROR_INVALID_NULL_HANDLE; + } + + if (getContext()->enableLifetimeValidation && + !getContext()->refCountContext->isReferenceValid(hContext)) { + URLOG_CTX_INVALID_REFERENCE(hContext); + } + + ur_result_t result = pfnPutMemHandleExp(hContext, hIPCMem); + + return result; +} + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Intercept function for urIPCOpenMemHandleExp +__urdlllocal ur_result_t UR_APICALL urIPCOpenMemHandleExp( + /// [in] handle of the context object + ur_context_handle_t hContext, + /// [in] pointer to the resulting IPC memory handle + ur_exp_ipc_mem_handle_t hIPCMem, + /// [out] pointer to a pointer to device USM memory + void **ppMem) { + auto pfnOpenMemHandleExp = + getContext()->urDdiTable.IPCExp.pfnOpenMemHandleExp; + + if (nullptr == pfnOpenMemHandleExp) { + return UR_RESULT_ERROR_UNINITIALIZED; + } + + if (getContext()->enableParameterValidation) { + if (NULL == hContext) + return UR_RESULT_ERROR_INVALID_NULL_HANDLE; + } + + if (getContext()->enableLifetimeValidation && + !getContext()->refCountContext->isReferenceValid(hContext)) { + URLOG_CTX_INVALID_REFERENCE(hContext); + } + + ur_result_t result = pfnOpenMemHandleExp(hContext, hIPCMem, ppMem); + + return result; +} + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Intercept function for urIPCCloseMemHandleExp +__urdlllocal ur_result_t UR_APICALL urIPCCloseMemHandleExp( + /// [in] handle of the context object + ur_context_handle_t hContext, + /// [in] pointer to device USM memory opened through urIPCOpenMemHandleExp + void *pMem) { + auto pfnCloseMemHandleExp = + getContext()->urDdiTable.IPCExp.pfnCloseMemHandleExp; + + if (nullptr == pfnCloseMemHandleExp) { + return UR_RESULT_ERROR_UNINITIALIZED; + } + + if (getContext()->enableParameterValidation) { + if (NULL == hContext) + return UR_RESULT_ERROR_INVALID_NULL_HANDLE; + } + + if (getContext()->enableLifetimeValidation && + !getContext()->refCountContext->isReferenceValid(hContext)) { + URLOG_CTX_INVALID_REFERENCE(hContext); + } + + ur_result_t result = pfnCloseMemHandleExp(hContext, pMem); + + return result; +} + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Intercept function for urIPCGetMemHandleDataExp +__urdlllocal ur_result_t UR_APICALL urIPCGetMemHandleDataExp( + /// [in] handle of the context object + ur_context_handle_t hContext, + /// [in] the IPC memory handle + ur_exp_ipc_mem_handle_t hIPCMem, + /// [out][optional] a pointer to the IPC memory handle data + const void **ppIPCHandleData, + /// [out][optional] size of the resulting IPC memory handle data + size_t *pIPCMemHandleDataSizeRet) { + auto pfnGetMemHandleDataExp = + getContext()->urDdiTable.IPCExp.pfnGetMemHandleDataExp; + + if (nullptr == pfnGetMemHandleDataExp) { + return UR_RESULT_ERROR_UNINITIALIZED; + } + + if (getContext()->enableParameterValidation) { + if (NULL == hContext) + return UR_RESULT_ERROR_INVALID_NULL_HANDLE; + } + + if (getContext()->enableLifetimeValidation && + !getContext()->refCountContext->isReferenceValid(hContext)) { + URLOG_CTX_INVALID_REFERENCE(hContext); + } + + ur_result_t result = pfnGetMemHandleDataExp( + hContext, hIPCMem, ppIPCHandleData, pIPCMemHandleDataSizeRet); + + return result; +} + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Intercept function for urIPCCreateMemHandleFromDataExp +__urdlllocal ur_result_t UR_APICALL urIPCCreateMemHandleFromDataExp( + /// [in] handle of the context object + ur_context_handle_t hContext, + /// [in] handle of the device object the corresponding USM device memory + /// was allocated on + ur_device_handle_t hDevice, + /// [in] the IPC memory handle data + const void *ipcMemHandleData, + /// [in] size of the IPC memory handle data + size_t ipcMemHandleDataSize, + /// [out] the IPC memory handle + ur_exp_ipc_mem_handle_t *phIPCMem) { + auto pfnCreateMemHandleFromDataExp = + getContext()->urDdiTable.IPCExp.pfnCreateMemHandleFromDataExp; + + if (nullptr == pfnCreateMemHandleFromDataExp) { + return UR_RESULT_ERROR_UNINITIALIZED; + } + + if (getContext()->enableParameterValidation) { + if (NULL == phIPCMem) + return UR_RESULT_ERROR_INVALID_NULL_POINTER; + + if (NULL == hContext) + return UR_RESULT_ERROR_INVALID_NULL_HANDLE; + + if (NULL == hDevice) + return UR_RESULT_ERROR_INVALID_NULL_HANDLE; + } + + if (getContext()->enableLifetimeValidation && + !getContext()->refCountContext->isReferenceValid(hContext)) { + URLOG_CTX_INVALID_REFERENCE(hContext); + } + + if (getContext()->enableLifetimeValidation && + !getContext()->refCountContext->isReferenceValid(hDevice)) { + URLOG_CTX_INVALID_REFERENCE(hDevice); + } + + ur_result_t result = pfnCreateMemHandleFromDataExp( + hContext, hDevice, ipcMemHandleData, ipcMemHandleDataSize, phIPCMem); + + return result; +} + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Intercept function for urIPCDestroyMemHandleExp +__urdlllocal ur_result_t UR_APICALL urIPCDestroyMemHandleExp( + /// [in] handle of the context object + ur_context_handle_t hContext, + /// [in] the IPC memory handle + ur_exp_ipc_mem_handle_t hIPCMem) { + auto pfnDestroyMemHandleExp = + getContext()->urDdiTable.IPCExp.pfnDestroyMemHandleExp; + + if (nullptr == pfnDestroyMemHandleExp) { + return UR_RESULT_ERROR_UNINITIALIZED; + } + + if (getContext()->enableParameterValidation) { + if (NULL == hContext) + return UR_RESULT_ERROR_INVALID_NULL_HANDLE; + } + + if (getContext()->enableLifetimeValidation && + !getContext()->refCountContext->isReferenceValid(hContext)) { + URLOG_CTX_INVALID_REFERENCE(hContext); + } + + ur_result_t result = pfnDestroyMemHandleExp(hContext, hIPCMem); + + return result; +} + /////////////////////////////////////////////////////////////////////////////// /// @brief Intercept function for urMemoryExportAllocExportableMemoryExp __urdlllocal ur_result_t UR_APICALL urMemoryExportAllocExportableMemoryExp( @@ -11585,6 +11817,60 @@ UR_DLLEXPORT ur_result_t UR_APICALL urGetEventProcAddrTable( return result; } +/////////////////////////////////////////////////////////////////////////////// +/// @brief Exported function for filling application's IPCExp table +/// with current process' addresses +/// +/// @returns +/// - ::UR_RESULT_SUCCESS +/// - ::UR_RESULT_ERROR_INVALID_NULL_POINTER +/// - ::UR_RESULT_ERROR_UNSUPPORTED_VERSION +UR_DLLEXPORT ur_result_t UR_APICALL urGetIPCExpProcAddrTable( + /// [in] API version requested + ur_api_version_t version, + /// [in,out] pointer to table of DDI function pointers + ur_ipc_exp_dditable_t *pDdiTable) { + auto &dditable = ur_validation_layer::getContext()->urDdiTable.IPCExp; + + if (nullptr == pDdiTable) + return UR_RESULT_ERROR_INVALID_NULL_POINTER; + + if (UR_MAJOR_VERSION(ur_validation_layer::getContext()->version) != + UR_MAJOR_VERSION(version) || + UR_MINOR_VERSION(ur_validation_layer::getContext()->version) > + UR_MINOR_VERSION(version)) + return UR_RESULT_ERROR_UNSUPPORTED_VERSION; + + ur_result_t result = UR_RESULT_SUCCESS; + + dditable.pfnGetMemHandleExp = pDdiTable->pfnGetMemHandleExp; + pDdiTable->pfnGetMemHandleExp = ur_validation_layer::urIPCGetMemHandleExp; + + dditable.pfnPutMemHandleExp = pDdiTable->pfnPutMemHandleExp; + pDdiTable->pfnPutMemHandleExp = ur_validation_layer::urIPCPutMemHandleExp; + + dditable.pfnOpenMemHandleExp = pDdiTable->pfnOpenMemHandleExp; + pDdiTable->pfnOpenMemHandleExp = ur_validation_layer::urIPCOpenMemHandleExp; + + dditable.pfnCloseMemHandleExp = pDdiTable->pfnCloseMemHandleExp; + pDdiTable->pfnCloseMemHandleExp = ur_validation_layer::urIPCCloseMemHandleExp; + + dditable.pfnGetMemHandleDataExp = pDdiTable->pfnGetMemHandleDataExp; + pDdiTable->pfnGetMemHandleDataExp = + ur_validation_layer::urIPCGetMemHandleDataExp; + + dditable.pfnCreateMemHandleFromDataExp = + pDdiTable->pfnCreateMemHandleFromDataExp; + pDdiTable->pfnCreateMemHandleFromDataExp = + ur_validation_layer::urIPCCreateMemHandleFromDataExp; + + dditable.pfnDestroyMemHandleExp = pDdiTable->pfnDestroyMemHandleExp; + pDdiTable->pfnDestroyMemHandleExp = + ur_validation_layer::urIPCDestroyMemHandleExp; + + return result; +} + /////////////////////////////////////////////////////////////////////////////// /// @brief Exported function for filling application's Kernel table /// with current process' addresses @@ -12427,6 +12713,11 @@ ur_result_t context_t::init(ur_dditable_t *dditable, UR_API_VERSION_CURRENT, &dditable->Event); } + if (UR_RESULT_SUCCESS == result) { + result = ur_validation_layer::urGetIPCExpProcAddrTable( + UR_API_VERSION_CURRENT, &dditable->IPCExp); + } + if (UR_RESULT_SUCCESS == result) { result = ur_validation_layer::urGetKernelProcAddrTable( UR_API_VERSION_CURRENT, &dditable->Kernel); diff --git a/unified-runtime/source/loader/loader.def.in b/unified-runtime/source/loader/loader.def.in index 3ad47149315ee..81b665399948c 100644 --- a/unified-runtime/source/loader/loader.def.in +++ b/unified-runtime/source/loader/loader.def.in @@ -118,6 +118,7 @@ EXPORTS urGetEnqueueExpProcAddrTable urGetEnqueueProcAddrTable urGetEventProcAddrTable + urGetIPCExpProcAddrTable urGetKernelProcAddrTable urGetMemProcAddrTable urGetMemoryExportExpProcAddrTable @@ -131,6 +132,13 @@ EXPORTS urGetUSMProcAddrTable urGetUsmP2PExpProcAddrTable urGetVirtualMemProcAddrTable + urIPCCloseMemHandleExp + urIPCCreateMemHandleFromDataExp + urIPCDestroyMemHandleExp + urIPCGetMemHandleDataExp + urIPCGetMemHandleExp + urIPCOpenMemHandleExp + urIPCPutMemHandleExp urKernelCreate urKernelCreateWithNativeHandle urKernelGetGroupInfo @@ -361,6 +369,13 @@ EXPORTS urPrintImageDesc urPrintImageFormat urPrintImageInfo + urPrintIpcCloseMemHandleExpParams + urPrintIpcCreateMemHandleFromDataExpParams + urPrintIpcDestroyMemHandleExpParams + urPrintIpcGetMemHandleDataExpParams + urPrintIpcGetMemHandleExpParams + urPrintIpcOpenMemHandleExpParams + urPrintIpcPutMemHandleExpParams urPrintKernelArgLocalProperties urPrintKernelArgMemObjProperties urPrintKernelArgPointerProperties diff --git a/unified-runtime/source/loader/loader.map.in b/unified-runtime/source/loader/loader.map.in index fde803f9aa45a..c6e5cd5006526 100644 --- a/unified-runtime/source/loader/loader.map.in +++ b/unified-runtime/source/loader/loader.map.in @@ -118,6 +118,7 @@ urGetEnqueueExpProcAddrTable; urGetEnqueueProcAddrTable; urGetEventProcAddrTable; + urGetIPCExpProcAddrTable; urGetKernelProcAddrTable; urGetMemProcAddrTable; urGetMemoryExportExpProcAddrTable; @@ -131,6 +132,13 @@ urGetUSMProcAddrTable; urGetUsmP2PExpProcAddrTable; urGetVirtualMemProcAddrTable; + urIPCCloseMemHandleExp; + urIPCCreateMemHandleFromDataExp; + urIPCDestroyMemHandleExp; + urIPCGetMemHandleDataExp; + urIPCGetMemHandleExp; + urIPCOpenMemHandleExp; + urIPCPutMemHandleExp; urKernelCreate; urKernelCreateWithNativeHandle; urKernelGetGroupInfo; @@ -361,6 +369,13 @@ urPrintImageDesc; urPrintImageFormat; urPrintImageInfo; + urPrintIpcCloseMemHandleExpParams; + urPrintIpcCreateMemHandleFromDataExpParams; + urPrintIpcDestroyMemHandleExpParams; + urPrintIpcGetMemHandleDataExpParams; + urPrintIpcGetMemHandleExpParams; + urPrintIpcOpenMemHandleExpParams; + urPrintIpcPutMemHandleExpParams; urPrintKernelArgLocalProperties; urPrintKernelArgMemObjProperties; urPrintKernelArgPointerProperties; diff --git a/unified-runtime/source/loader/ur_ldrddi.cpp b/unified-runtime/source/loader/ur_ldrddi.cpp index 75ae04bc5a4a8..d2792f8b3de4e 100644 --- a/unified-runtime/source/loader/ur_ldrddi.cpp +++ b/unified-runtime/source/loader/ur_ldrddi.cpp @@ -5452,6 +5452,150 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueTimestampRecordingExp( phEventWaitList, phEvent); } +/////////////////////////////////////////////////////////////////////////////// +/// @brief Intercept function for urIPCGetMemHandleExp +__urdlllocal ur_result_t UR_APICALL urIPCGetMemHandleExp( + /// [in] handle of the context object + ur_context_handle_t hContext, + /// [in] pointer to device USM memory + void *pMem, + /// [out][alloc] pointer to the resulting IPC memory handle + ur_exp_ipc_mem_handle_t *phIPCMem) { + + auto *dditable = *reinterpret_cast(hContext); + + auto *pfnGetMemHandleExp = dditable->IPCExp.pfnGetMemHandleExp; + if (nullptr == pfnGetMemHandleExp) + return UR_RESULT_ERROR_UNINITIALIZED; + + // forward to device-platform + return pfnGetMemHandleExp(hContext, pMem, phIPCMem); +} + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Intercept function for urIPCPutMemHandleExp +__urdlllocal ur_result_t UR_APICALL urIPCPutMemHandleExp( + /// [in] handle of the context object + ur_context_handle_t hContext, + /// [in] the IPC memory handle + ur_exp_ipc_mem_handle_t hIPCMem) { + + auto *dditable = *reinterpret_cast(hContext); + + auto *pfnPutMemHandleExp = dditable->IPCExp.pfnPutMemHandleExp; + if (nullptr == pfnPutMemHandleExp) + return UR_RESULT_ERROR_UNINITIALIZED; + + // forward to device-platform + return pfnPutMemHandleExp(hContext, hIPCMem); +} + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Intercept function for urIPCOpenMemHandleExp +__urdlllocal ur_result_t UR_APICALL urIPCOpenMemHandleExp( + /// [in] handle of the context object + ur_context_handle_t hContext, + /// [in] pointer to the resulting IPC memory handle + ur_exp_ipc_mem_handle_t hIPCMem, + /// [out] pointer to a pointer to device USM memory + void **ppMem) { + + auto *dditable = *reinterpret_cast(hContext); + + auto *pfnOpenMemHandleExp = dditable->IPCExp.pfnOpenMemHandleExp; + if (nullptr == pfnOpenMemHandleExp) + return UR_RESULT_ERROR_UNINITIALIZED; + + // forward to device-platform + return pfnOpenMemHandleExp(hContext, hIPCMem, ppMem); +} + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Intercept function for urIPCCloseMemHandleExp +__urdlllocal ur_result_t UR_APICALL urIPCCloseMemHandleExp( + /// [in] handle of the context object + ur_context_handle_t hContext, + /// [in] pointer to device USM memory opened through urIPCOpenMemHandleExp + void *pMem) { + + auto *dditable = *reinterpret_cast(hContext); + + auto *pfnCloseMemHandleExp = dditable->IPCExp.pfnCloseMemHandleExp; + if (nullptr == pfnCloseMemHandleExp) + return UR_RESULT_ERROR_UNINITIALIZED; + + // forward to device-platform + return pfnCloseMemHandleExp(hContext, pMem); +} + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Intercept function for urIPCGetMemHandleDataExp +__urdlllocal ur_result_t UR_APICALL urIPCGetMemHandleDataExp( + /// [in] handle of the context object + ur_context_handle_t hContext, + /// [in] the IPC memory handle + ur_exp_ipc_mem_handle_t hIPCMem, + /// [out][optional] a pointer to the IPC memory handle data + const void **ppIPCHandleData, + /// [out][optional] size of the resulting IPC memory handle data + size_t *pIPCMemHandleDataSizeRet) { + + auto *dditable = *reinterpret_cast(hContext); + + auto *pfnGetMemHandleDataExp = dditable->IPCExp.pfnGetMemHandleDataExp; + if (nullptr == pfnGetMemHandleDataExp) + return UR_RESULT_ERROR_UNINITIALIZED; + + // forward to device-platform + return pfnGetMemHandleDataExp(hContext, hIPCMem, ppIPCHandleData, + pIPCMemHandleDataSizeRet); +} + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Intercept function for urIPCCreateMemHandleFromDataExp +__urdlllocal ur_result_t UR_APICALL urIPCCreateMemHandleFromDataExp( + /// [in] handle of the context object + ur_context_handle_t hContext, + /// [in] handle of the device object the corresponding USM device memory + /// was allocated on + ur_device_handle_t hDevice, + /// [in] the IPC memory handle data + const void *ipcMemHandleData, + /// [in] size of the IPC memory handle data + size_t ipcMemHandleDataSize, + /// [out] the IPC memory handle + ur_exp_ipc_mem_handle_t *phIPCMem) { + + auto *dditable = *reinterpret_cast(hContext); + + auto *pfnCreateMemHandleFromDataExp = + dditable->IPCExp.pfnCreateMemHandleFromDataExp; + if (nullptr == pfnCreateMemHandleFromDataExp) + return UR_RESULT_ERROR_UNINITIALIZED; + + // forward to device-platform + return pfnCreateMemHandleFromDataExp(hContext, hDevice, ipcMemHandleData, + ipcMemHandleDataSize, phIPCMem); +} + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Intercept function for urIPCDestroyMemHandleExp +__urdlllocal ur_result_t UR_APICALL urIPCDestroyMemHandleExp( + /// [in] handle of the context object + ur_context_handle_t hContext, + /// [in] the IPC memory handle + ur_exp_ipc_mem_handle_t hIPCMem) { + + auto *dditable = *reinterpret_cast(hContext); + + auto *pfnDestroyMemHandleExp = dditable->IPCExp.pfnDestroyMemHandleExp; + if (nullptr == pfnDestroyMemHandleExp) + return UR_RESULT_ERROR_UNINITIALIZED; + + // forward to device-platform + return pfnDestroyMemHandleExp(hContext, hIPCMem); +} + /////////////////////////////////////////////////////////////////////////////// /// @brief Intercept function for urMemoryExportAllocExportableMemoryExp __urdlllocal ur_result_t UR_APICALL urMemoryExportAllocExportableMemoryExp( @@ -6322,6 +6466,65 @@ UR_DLLEXPORT ur_result_t UR_APICALL urGetEventProcAddrTable( return result; } +/////////////////////////////////////////////////////////////////////////////// +/// @brief Exported function for filling application's IPCExp table +/// with current process' addresses +/// +/// @returns +/// - ::UR_RESULT_SUCCESS +/// - ::UR_RESULT_ERROR_UNINITIALIZED +/// - ::UR_RESULT_ERROR_INVALID_NULL_POINTER +/// - ::UR_RESULT_ERROR_UNSUPPORTED_VERSION +UR_DLLEXPORT ur_result_t UR_APICALL urGetIPCExpProcAddrTable( + /// [in] API version requested + ur_api_version_t version, + /// [in,out] pointer to table of DDI function pointers + ur_ipc_exp_dditable_t *pDdiTable) { + if (nullptr == pDdiTable) + return UR_RESULT_ERROR_INVALID_NULL_POINTER; + + if (ur_loader::getContext()->version < version) + return UR_RESULT_ERROR_UNSUPPORTED_VERSION; + + ur_result_t result = UR_RESULT_SUCCESS; + + // Load the device-platform DDI tables + for (auto &platform : ur_loader::getContext()->platforms) { + // statically linked adapter inside of the loader + if (platform.handle == nullptr) + continue; + + if (platform.initStatus != UR_RESULT_SUCCESS) + continue; + auto getTable = reinterpret_cast( + ur_loader::LibLoader::getFunctionPtr(platform.handle.get(), + "urGetIPCExpProcAddrTable")); + if (!getTable) + continue; + platform.initStatus = getTable(version, &platform.dditable.IPCExp); + } + + if (UR_RESULT_SUCCESS == result) { + if (ur_loader::getContext()->platforms.size() != 1 || + ur_loader::getContext()->forceIntercept) { + // return pointers to loader's DDIs + pDdiTable->pfnGetMemHandleExp = ur_loader::urIPCGetMemHandleExp; + pDdiTable->pfnPutMemHandleExp = ur_loader::urIPCPutMemHandleExp; + pDdiTable->pfnOpenMemHandleExp = ur_loader::urIPCOpenMemHandleExp; + pDdiTable->pfnCloseMemHandleExp = ur_loader::urIPCCloseMemHandleExp; + pDdiTable->pfnGetMemHandleDataExp = ur_loader::urIPCGetMemHandleDataExp; + pDdiTable->pfnCreateMemHandleFromDataExp = + ur_loader::urIPCCreateMemHandleFromDataExp; + pDdiTable->pfnDestroyMemHandleExp = ur_loader::urIPCDestroyMemHandleExp; + } else { + // return pointers directly to platform's DDIs + *pDdiTable = ur_loader::getContext()->platforms.front().dditable.IPCExp; + } + } + + return result; +} + /////////////////////////////////////////////////////////////////////////////// /// @brief Exported function for filling application's Kernel table /// with current process' addresses diff --git a/unified-runtime/source/loader/ur_libapi.cpp b/unified-runtime/source/loader/ur_libapi.cpp index 4ec2282647e80..0da75c3f817fc 100644 --- a/unified-runtime/source/loader/ur_libapi.cpp +++ b/unified-runtime/source/loader/ur_libapi.cpp @@ -9997,6 +9997,251 @@ ur_result_t UR_APICALL urEnqueueTimestampRecordingExp( return exceptionToResult(std::current_exception()); } +/////////////////////////////////////////////////////////////////////////////// +/// @brief Gets an inter-process memory handle for a pointer to device USM +/// memory +/// +/// @returns +/// - ::UR_RESULT_SUCCESS +/// - ::UR_RESULT_ERROR_UNINITIALIZED +/// - ::UR_RESULT_ERROR_DEVICE_LOST +/// - ::UR_RESULT_ERROR_ADAPTER_SPECIFIC +/// - ::UR_RESULT_ERROR_INVALID_NULL_HANDLE +/// + `NULL == hContext` +/// + NULL == hContext +/// - ::UR_RESULT_ERROR_INVALID_NULL_POINTER +/// + `NULL == phIPCMem` +/// + NULL == phIPCMem +/// - ::UR_RESULT_ERROR_INVALID_CONTEXT +/// - ::UR_RESULT_ERROR_OUT_OF_HOST_MEMORY +/// - ::UR_RESULT_ERROR_OUT_OF_RESOURCES +ur_result_t UR_APICALL urIPCGetMemHandleExp( + /// [in] handle of the context object + ur_context_handle_t hContext, + /// [in] pointer to device USM memory + void *pMem, + /// [out][alloc] pointer to the resulting IPC memory handle + ur_exp_ipc_mem_handle_t *phIPCMem) try { + auto pfnGetMemHandleExp = + ur_lib::getContext()->urDdiTable.IPCExp.pfnGetMemHandleExp; + if (nullptr == pfnGetMemHandleExp) + return UR_RESULT_ERROR_UNINITIALIZED; + + return pfnGetMemHandleExp(hContext, pMem, phIPCMem); +} catch (...) { + return exceptionToResult(std::current_exception()); +} + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Releases an inter-process memory handle +/// +/// @returns +/// - ::UR_RESULT_SUCCESS +/// - ::UR_RESULT_ERROR_UNINITIALIZED +/// - ::UR_RESULT_ERROR_DEVICE_LOST +/// - ::UR_RESULT_ERROR_ADAPTER_SPECIFIC +/// - ::UR_RESULT_ERROR_INVALID_NULL_HANDLE +/// + `NULL == hContext` +/// + NULL == hContext +/// + NULL == hIPCMem +/// - ::UR_RESULT_ERROR_INVALID_CONTEXT +/// - ::UR_RESULT_ERROR_OUT_OF_HOST_MEMORY +/// - ::UR_RESULT_ERROR_OUT_OF_RESOURCES +ur_result_t UR_APICALL urIPCPutMemHandleExp( + /// [in] handle of the context object + ur_context_handle_t hContext, + /// [in] the IPC memory handle + ur_exp_ipc_mem_handle_t hIPCMem) try { + auto pfnPutMemHandleExp = + ur_lib::getContext()->urDdiTable.IPCExp.pfnPutMemHandleExp; + if (nullptr == pfnPutMemHandleExp) + return UR_RESULT_ERROR_UNINITIALIZED; + + return pfnPutMemHandleExp(hContext, hIPCMem); +} catch (...) { + return exceptionToResult(std::current_exception()); +} + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Opens an inter-process memory handle to get the corresponding pointer +/// to device USM memory +/// +/// @returns +/// - ::UR_RESULT_SUCCESS +/// - ::UR_RESULT_ERROR_UNINITIALIZED +/// - ::UR_RESULT_ERROR_DEVICE_LOST +/// - ::UR_RESULT_ERROR_ADAPTER_SPECIFIC +/// - ::UR_RESULT_ERROR_INVALID_NULL_HANDLE +/// + `NULL == hContext` +/// + NULL == hContext +/// + NULL == hIPCMem +/// - ::UR_RESULT_ERROR_INVALID_CONTEXT +/// - ::UR_RESULT_ERROR_INVALID_NULL_POINTER +/// + NULL == ppMem +/// - ::UR_RESULT_ERROR_OUT_OF_HOST_MEMORY +/// - ::UR_RESULT_ERROR_OUT_OF_RESOURCES +ur_result_t UR_APICALL urIPCOpenMemHandleExp( + /// [in] handle of the context object + ur_context_handle_t hContext, + /// [in] pointer to the resulting IPC memory handle + ur_exp_ipc_mem_handle_t hIPCMem, + /// [out] pointer to a pointer to device USM memory + void **ppMem) try { + auto pfnOpenMemHandleExp = + ur_lib::getContext()->urDdiTable.IPCExp.pfnOpenMemHandleExp; + if (nullptr == pfnOpenMemHandleExp) + return UR_RESULT_ERROR_UNINITIALIZED; + + return pfnOpenMemHandleExp(hContext, hIPCMem, ppMem); +} catch (...) { + return exceptionToResult(std::current_exception()); +} + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Closes an inter-process memory handle +/// +/// @returns +/// - ::UR_RESULT_SUCCESS +/// - ::UR_RESULT_ERROR_UNINITIALIZED +/// - ::UR_RESULT_ERROR_DEVICE_LOST +/// - ::UR_RESULT_ERROR_ADAPTER_SPECIFIC +/// - ::UR_RESULT_ERROR_INVALID_NULL_HANDLE +/// + `NULL == hContext` +/// + NULL == hContext +/// - ::UR_RESULT_ERROR_INVALID_CONTEXT +/// - ::UR_RESULT_ERROR_INVALID_NULL_POINTER +/// + NULL == pMem +/// - ::UR_RESULT_ERROR_OUT_OF_HOST_MEMORY +/// - ::UR_RESULT_ERROR_OUT_OF_RESOURCES +ur_result_t UR_APICALL urIPCCloseMemHandleExp( + /// [in] handle of the context object + ur_context_handle_t hContext, + /// [in] pointer to device USM memory opened through urIPCOpenMemHandleExp + void *pMem) try { + auto pfnCloseMemHandleExp = + ur_lib::getContext()->urDdiTable.IPCExp.pfnCloseMemHandleExp; + if (nullptr == pfnCloseMemHandleExp) + return UR_RESULT_ERROR_UNINITIALIZED; + + return pfnCloseMemHandleExp(hContext, pMem); +} catch (...) { + return exceptionToResult(std::current_exception()); +} + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Gets the data of an inter-process memory handle +/// +/// @returns +/// - ::UR_RESULT_SUCCESS +/// - ::UR_RESULT_ERROR_UNINITIALIZED +/// - ::UR_RESULT_ERROR_DEVICE_LOST +/// - ::UR_RESULT_ERROR_ADAPTER_SPECIFIC +/// - ::UR_RESULT_ERROR_INVALID_NULL_HANDLE +/// + `NULL == hContext` +/// + NULL == hContext +/// + NULL == hIPCMem +/// - ::UR_RESULT_ERROR_INVALID_CONTEXT +/// - ::UR_RESULT_ERROR_OUT_OF_HOST_MEMORY +/// - ::UR_RESULT_ERROR_OUT_OF_RESOURCES +ur_result_t UR_APICALL urIPCGetMemHandleDataExp( + /// [in] handle of the context object + ur_context_handle_t hContext, + /// [in] the IPC memory handle + ur_exp_ipc_mem_handle_t hIPCMem, + /// [out][optional] a pointer to the IPC memory handle data + const void **ppIPCHandleData, + /// [out][optional] size of the resulting IPC memory handle data + size_t *pIPCMemHandleDataSizeRet) try { + auto pfnGetMemHandleDataExp = + ur_lib::getContext()->urDdiTable.IPCExp.pfnGetMemHandleDataExp; + if (nullptr == pfnGetMemHandleDataExp) + return UR_RESULT_ERROR_UNINITIALIZED; + + return pfnGetMemHandleDataExp(hContext, hIPCMem, ppIPCHandleData, + pIPCMemHandleDataSizeRet); +} catch (...) { + return exceptionToResult(std::current_exception()); +} + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Creates an inter-process memory handle from handle data +/// +/// @returns +/// - ::UR_RESULT_SUCCESS +/// - ::UR_RESULT_ERROR_UNINITIALIZED +/// - ::UR_RESULT_ERROR_DEVICE_LOST +/// - ::UR_RESULT_ERROR_ADAPTER_SPECIFIC +/// - ::UR_RESULT_ERROR_INVALID_NULL_HANDLE +/// + `NULL == hContext` +/// + `NULL == hDevice` +/// + NULL == hContext +/// + NULL == hDevice +/// - ::UR_RESULT_ERROR_INVALID_NULL_POINTER +/// + `NULL == phIPCMem` +/// + NULL == ipcMemHandleData +/// + NULL == phIPCMem +/// - ::UR_RESULT_ERROR_INVALID_CONTEXT +/// - ::UR_RESULT_ERROR_INVALID_VALUE +/// + ipcMemHandleDataSize is not the same as the size of IPC memory +/// handle data +/// - ::UR_RESULT_ERROR_OUT_OF_HOST_MEMORY +/// - ::UR_RESULT_ERROR_OUT_OF_RESOURCES +ur_result_t UR_APICALL urIPCCreateMemHandleFromDataExp( + /// [in] handle of the context object + ur_context_handle_t hContext, + /// [in] handle of the device object the corresponding USM device memory + /// was allocated on + ur_device_handle_t hDevice, + /// [in] the IPC memory handle data + const void *ipcMemHandleData, + /// [in] size of the IPC memory handle data + size_t ipcMemHandleDataSize, + /// [out] the IPC memory handle + ur_exp_ipc_mem_handle_t *phIPCMem) try { + auto pfnCreateMemHandleFromDataExp = + ur_lib::getContext()->urDdiTable.IPCExp.pfnCreateMemHandleFromDataExp; + if (nullptr == pfnCreateMemHandleFromDataExp) + return UR_RESULT_ERROR_UNINITIALIZED; + + return pfnCreateMemHandleFromDataExp(hContext, hDevice, ipcMemHandleData, + ipcMemHandleDataSize, phIPCMem); +} catch (...) { + return exceptionToResult(std::current_exception()); +} + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Destroys an inter-process memory handle created through +/// urIPCCreateMemHandleFromDataExp +/// +/// @returns +/// - ::UR_RESULT_SUCCESS +/// - ::UR_RESULT_ERROR_UNINITIALIZED +/// - ::UR_RESULT_ERROR_DEVICE_LOST +/// - ::UR_RESULT_ERROR_ADAPTER_SPECIFIC +/// - ::UR_RESULT_ERROR_INVALID_NULL_HANDLE +/// + `NULL == hContext` +/// + NULL == hContext +/// + NULL == hIPCMem +/// - ::UR_RESULT_ERROR_INVALID_CONTEXT +/// - ::UR_RESULT_ERROR_INVALID_VALUE +/// + hIPCMem was not created through CreateMemHandleFromDataExp +/// - ::UR_RESULT_ERROR_OUT_OF_HOST_MEMORY +/// - ::UR_RESULT_ERROR_OUT_OF_RESOURCES +ur_result_t UR_APICALL urIPCDestroyMemHandleExp( + /// [in] handle of the context object + ur_context_handle_t hContext, + /// [in] the IPC memory handle + ur_exp_ipc_mem_handle_t hIPCMem) try { + auto pfnDestroyMemHandleExp = + ur_lib::getContext()->urDdiTable.IPCExp.pfnDestroyMemHandleExp; + if (nullptr == pfnDestroyMemHandleExp) + return UR_RESULT_ERROR_UNINITIALIZED; + + return pfnDestroyMemHandleExp(hContext, hIPCMem); +} catch (...) { + return exceptionToResult(std::current_exception()); +} + /////////////////////////////////////////////////////////////////////////////// /// @brief Allocate an exportable memory region and return a pointer to that /// allocation. diff --git a/unified-runtime/source/loader/ur_libddi.cpp b/unified-runtime/source/loader/ur_libddi.cpp index b06ee531cdb46..648fc87872188 100644 --- a/unified-runtime/source/loader/ur_libddi.cpp +++ b/unified-runtime/source/loader/ur_libddi.cpp @@ -56,6 +56,11 @@ __urdlllocal ur_result_t context_t::ddiInit() { result = urGetEventProcAddrTable(UR_API_VERSION_CURRENT, &urDdiTable.Event); } + if (UR_RESULT_SUCCESS == result) { + result = + urGetIPCExpProcAddrTable(UR_API_VERSION_CURRENT, &urDdiTable.IPCExp); + } + if (UR_RESULT_SUCCESS == result) { result = urGetKernelProcAddrTable(UR_API_VERSION_CURRENT, &urDdiTable.Kernel); diff --git a/unified-runtime/source/loader/ur_print.cpp b/unified-runtime/source/loader/ur_print.cpp index f3d5c96e376ca..6b4af510ce561 100644 --- a/unified-runtime/source/loader/ur_print.cpp +++ b/unified-runtime/source/loader/ur_print.cpp @@ -2000,6 +2000,62 @@ ur_result_t urPrintEventSetCallbackParams( return str_copy(&ss, buffer, buff_size, out_size); } +ur_result_t urPrintIpcGetMemHandleExpParams( + const struct ur_ipc_get_mem_handle_exp_params_t *params, char *buffer, + const size_t buff_size, size_t *out_size) { + std::stringstream ss; + ss << params; + return str_copy(&ss, buffer, buff_size, out_size); +} + +ur_result_t urPrintIpcPutMemHandleExpParams( + const struct ur_ipc_put_mem_handle_exp_params_t *params, char *buffer, + const size_t buff_size, size_t *out_size) { + std::stringstream ss; + ss << params; + return str_copy(&ss, buffer, buff_size, out_size); +} + +ur_result_t urPrintIpcOpenMemHandleExpParams( + const struct ur_ipc_open_mem_handle_exp_params_t *params, char *buffer, + const size_t buff_size, size_t *out_size) { + std::stringstream ss; + ss << params; + return str_copy(&ss, buffer, buff_size, out_size); +} + +ur_result_t urPrintIpcCloseMemHandleExpParams( + const struct ur_ipc_close_mem_handle_exp_params_t *params, char *buffer, + const size_t buff_size, size_t *out_size) { + std::stringstream ss; + ss << params; + return str_copy(&ss, buffer, buff_size, out_size); +} + +ur_result_t urPrintIpcGetMemHandleDataExpParams( + const struct ur_ipc_get_mem_handle_data_exp_params_t *params, char *buffer, + const size_t buff_size, size_t *out_size) { + std::stringstream ss; + ss << params; + return str_copy(&ss, buffer, buff_size, out_size); +} + +ur_result_t urPrintIpcCreateMemHandleFromDataExpParams( + const struct ur_ipc_create_mem_handle_from_data_exp_params_t *params, + char *buffer, const size_t buff_size, size_t *out_size) { + std::stringstream ss; + ss << params; + return str_copy(&ss, buffer, buff_size, out_size); +} + +ur_result_t urPrintIpcDestroyMemHandleExpParams( + const struct ur_ipc_destroy_mem_handle_exp_params_t *params, char *buffer, + const size_t buff_size, size_t *out_size) { + std::stringstream ss; + ss << params; + return str_copy(&ss, buffer, buff_size, out_size); +} + ur_result_t urPrintKernelCreateParams(const struct ur_kernel_create_params_t *params, char *buffer, const size_t buff_size, diff --git a/unified-runtime/source/ur_api.cpp b/unified-runtime/source/ur_api.cpp index 8e3424b693e62..186a78f882c3e 100644 --- a/unified-runtime/source/ur_api.cpp +++ b/unified-runtime/source/ur_api.cpp @@ -8704,6 +8704,207 @@ ur_result_t UR_APICALL urEnqueueTimestampRecordingExp( return result; } +/////////////////////////////////////////////////////////////////////////////// +/// @brief Gets an inter-process memory handle for a pointer to device USM +/// memory +/// +/// @returns +/// - ::UR_RESULT_SUCCESS +/// - ::UR_RESULT_ERROR_UNINITIALIZED +/// - ::UR_RESULT_ERROR_DEVICE_LOST +/// - ::UR_RESULT_ERROR_ADAPTER_SPECIFIC +/// - ::UR_RESULT_ERROR_INVALID_NULL_HANDLE +/// + `NULL == hContext` +/// + NULL == hContext +/// - ::UR_RESULT_ERROR_INVALID_NULL_POINTER +/// + `NULL == phIPCMem` +/// + NULL == phIPCMem +/// - ::UR_RESULT_ERROR_INVALID_CONTEXT +/// - ::UR_RESULT_ERROR_OUT_OF_HOST_MEMORY +/// - ::UR_RESULT_ERROR_OUT_OF_RESOURCES +ur_result_t UR_APICALL urIPCGetMemHandleExp( + /// [in] handle of the context object + ur_context_handle_t hContext, + /// [in] pointer to device USM memory + void *pMem, + /// [out][alloc] pointer to the resulting IPC memory handle + ur_exp_ipc_mem_handle_t *phIPCMem) { + ur_result_t result = UR_RESULT_SUCCESS; + return result; +} + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Releases an inter-process memory handle +/// +/// @returns +/// - ::UR_RESULT_SUCCESS +/// - ::UR_RESULT_ERROR_UNINITIALIZED +/// - ::UR_RESULT_ERROR_DEVICE_LOST +/// - ::UR_RESULT_ERROR_ADAPTER_SPECIFIC +/// - ::UR_RESULT_ERROR_INVALID_NULL_HANDLE +/// + `NULL == hContext` +/// + NULL == hContext +/// + NULL == hIPCMem +/// - ::UR_RESULT_ERROR_INVALID_CONTEXT +/// - ::UR_RESULT_ERROR_OUT_OF_HOST_MEMORY +/// - ::UR_RESULT_ERROR_OUT_OF_RESOURCES +ur_result_t UR_APICALL urIPCPutMemHandleExp( + /// [in] handle of the context object + ur_context_handle_t hContext, + /// [in] the IPC memory handle + ur_exp_ipc_mem_handle_t hIPCMem) { + ur_result_t result = UR_RESULT_SUCCESS; + return result; +} + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Opens an inter-process memory handle to get the corresponding pointer +/// to device USM memory +/// +/// @returns +/// - ::UR_RESULT_SUCCESS +/// - ::UR_RESULT_ERROR_UNINITIALIZED +/// - ::UR_RESULT_ERROR_DEVICE_LOST +/// - ::UR_RESULT_ERROR_ADAPTER_SPECIFIC +/// - ::UR_RESULT_ERROR_INVALID_NULL_HANDLE +/// + `NULL == hContext` +/// + NULL == hContext +/// + NULL == hIPCMem +/// - ::UR_RESULT_ERROR_INVALID_CONTEXT +/// - ::UR_RESULT_ERROR_INVALID_NULL_POINTER +/// + NULL == ppMem +/// - ::UR_RESULT_ERROR_OUT_OF_HOST_MEMORY +/// - ::UR_RESULT_ERROR_OUT_OF_RESOURCES +ur_result_t UR_APICALL urIPCOpenMemHandleExp( + /// [in] handle of the context object + ur_context_handle_t hContext, + /// [in] pointer to the resulting IPC memory handle + ur_exp_ipc_mem_handle_t hIPCMem, + /// [out] pointer to a pointer to device USM memory + void **ppMem) { + ur_result_t result = UR_RESULT_SUCCESS; + return result; +} + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Closes an inter-process memory handle +/// +/// @returns +/// - ::UR_RESULT_SUCCESS +/// - ::UR_RESULT_ERROR_UNINITIALIZED +/// - ::UR_RESULT_ERROR_DEVICE_LOST +/// - ::UR_RESULT_ERROR_ADAPTER_SPECIFIC +/// - ::UR_RESULT_ERROR_INVALID_NULL_HANDLE +/// + `NULL == hContext` +/// + NULL == hContext +/// - ::UR_RESULT_ERROR_INVALID_CONTEXT +/// - ::UR_RESULT_ERROR_INVALID_NULL_POINTER +/// + NULL == pMem +/// - ::UR_RESULT_ERROR_OUT_OF_HOST_MEMORY +/// - ::UR_RESULT_ERROR_OUT_OF_RESOURCES +ur_result_t UR_APICALL urIPCCloseMemHandleExp( + /// [in] handle of the context object + ur_context_handle_t hContext, + /// [in] pointer to device USM memory opened through urIPCOpenMemHandleExp + void *pMem) { + ur_result_t result = UR_RESULT_SUCCESS; + return result; +} + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Gets the data of an inter-process memory handle +/// +/// @returns +/// - ::UR_RESULT_SUCCESS +/// - ::UR_RESULT_ERROR_UNINITIALIZED +/// - ::UR_RESULT_ERROR_DEVICE_LOST +/// - ::UR_RESULT_ERROR_ADAPTER_SPECIFIC +/// - ::UR_RESULT_ERROR_INVALID_NULL_HANDLE +/// + `NULL == hContext` +/// + NULL == hContext +/// + NULL == hIPCMem +/// - ::UR_RESULT_ERROR_INVALID_CONTEXT +/// - ::UR_RESULT_ERROR_OUT_OF_HOST_MEMORY +/// - ::UR_RESULT_ERROR_OUT_OF_RESOURCES +ur_result_t UR_APICALL urIPCGetMemHandleDataExp( + /// [in] handle of the context object + ur_context_handle_t hContext, + /// [in] the IPC memory handle + ur_exp_ipc_mem_handle_t hIPCMem, + /// [out][optional] a pointer to the IPC memory handle data + const void **ppIPCHandleData, + /// [out][optional] size of the resulting IPC memory handle data + size_t *pIPCMemHandleDataSizeRet) { + ur_result_t result = UR_RESULT_SUCCESS; + return result; +} + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Creates an inter-process memory handle from handle data +/// +/// @returns +/// - ::UR_RESULT_SUCCESS +/// - ::UR_RESULT_ERROR_UNINITIALIZED +/// - ::UR_RESULT_ERROR_DEVICE_LOST +/// - ::UR_RESULT_ERROR_ADAPTER_SPECIFIC +/// - ::UR_RESULT_ERROR_INVALID_NULL_HANDLE +/// + `NULL == hContext` +/// + `NULL == hDevice` +/// + NULL == hContext +/// + NULL == hDevice +/// - ::UR_RESULT_ERROR_INVALID_NULL_POINTER +/// + `NULL == phIPCMem` +/// + NULL == ipcMemHandleData +/// + NULL == phIPCMem +/// - ::UR_RESULT_ERROR_INVALID_CONTEXT +/// - ::UR_RESULT_ERROR_INVALID_VALUE +/// + ipcMemHandleDataSize is not the same as the size of IPC memory +/// handle data +/// - ::UR_RESULT_ERROR_OUT_OF_HOST_MEMORY +/// - ::UR_RESULT_ERROR_OUT_OF_RESOURCES +ur_result_t UR_APICALL urIPCCreateMemHandleFromDataExp( + /// [in] handle of the context object + ur_context_handle_t hContext, + /// [in] handle of the device object the corresponding USM device memory + /// was allocated on + ur_device_handle_t hDevice, + /// [in] the IPC memory handle data + const void *ipcMemHandleData, + /// [in] size of the IPC memory handle data + size_t ipcMemHandleDataSize, + /// [out] the IPC memory handle + ur_exp_ipc_mem_handle_t *phIPCMem) { + ur_result_t result = UR_RESULT_SUCCESS; + return result; +} + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Destroys an inter-process memory handle created through +/// urIPCCreateMemHandleFromDataExp +/// +/// @returns +/// - ::UR_RESULT_SUCCESS +/// - ::UR_RESULT_ERROR_UNINITIALIZED +/// - ::UR_RESULT_ERROR_DEVICE_LOST +/// - ::UR_RESULT_ERROR_ADAPTER_SPECIFIC +/// - ::UR_RESULT_ERROR_INVALID_NULL_HANDLE +/// + `NULL == hContext` +/// + NULL == hContext +/// + NULL == hIPCMem +/// - ::UR_RESULT_ERROR_INVALID_CONTEXT +/// - ::UR_RESULT_ERROR_INVALID_VALUE +/// + hIPCMem was not created through CreateMemHandleFromDataExp +/// - ::UR_RESULT_ERROR_OUT_OF_HOST_MEMORY +/// - ::UR_RESULT_ERROR_OUT_OF_RESOURCES +ur_result_t UR_APICALL urIPCDestroyMemHandleExp( + /// [in] handle of the context object + ur_context_handle_t hContext, + /// [in] the IPC memory handle + ur_exp_ipc_mem_handle_t hIPCMem) { + ur_result_t result = UR_RESULT_SUCCESS; + return result; +} + /////////////////////////////////////////////////////////////////////////////// /// @brief Allocate an exportable memory region and return a pointer to that /// allocation. diff --git a/unified-runtime/tools/urinfo/urinfo.hpp b/unified-runtime/tools/urinfo/urinfo.hpp index b08661787cccf..d27bf7a229ff9 100644 --- a/unified-runtime/tools/urinfo/urinfo.hpp +++ b/unified-runtime/tools/urinfo/urinfo.hpp @@ -445,6 +445,8 @@ inline void printDeviceInfos(ur_device_handle_t hDevice, printDeviceInfo( hDevice, UR_DEVICE_INFO_2D_BLOCK_ARRAY_CAPABILITIES_EXP); std::cout << prefix; + printDeviceInfo(hDevice, UR_DEVICE_INFO_IPC_MEMORY_SUPPORT_EXP); + std::cout << prefix; printDeviceInfo(hDevice, UR_DEVICE_INFO_ASYNC_USM_ALLOCATIONS_SUPPORT_EXP); std::cout << prefix; From e4aefbf014ba9d46909c05d8c86a20007b784b81 Mon Sep 17 00:00:00 2001 From: "Larsen, Steffen" Date: Mon, 15 Sep 2025 04:01:26 -0700 Subject: [PATCH 02/38] Set ptracer permission in test Signed-off-by: Larsen, Steffen --- sycl/test-e2e/Experimental/ipc_memory.cpp | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/sycl/test-e2e/Experimental/ipc_memory.cpp b/sycl/test-e2e/Experimental/ipc_memory.cpp index 31d2cdb03e37c..422c63e360c43 100644 --- a/sycl/test-e2e/Experimental/ipc_memory.cpp +++ b/sycl/test-e2e/Experimental/ipc_memory.cpp @@ -11,6 +11,12 @@ #include #include +#if defined(__linux__) +#include +#include +#include +#endif // defined(__linux__) + namespace syclexp = sycl::ext::oneapi::experimental; constexpr size_t N = 32; @@ -20,6 +26,17 @@ int spawner(int argc, char *argv[]) { assert(argc == 1); sycl::queue Q; +#if defined(__linux__) + // UMF currently requires ptrace permissions to be set for the spawner. As + // such we need to set it until this limitation has been addressed. + // https://github.com/oneapi-src/unified-memory-framework/tree/main?tab=readme-ov-file#level-zero-memory-provider + if (Q.get_backend() == sycl::backend::ext_oneapi_level_zero && + prctl(PR_SET_PTRACER, getppid()) == -1) { + std::cout << "Failed to set ptracer permissions!" << std::endl; + return 1; + } +#endif // defined(__linux__) + int *DataPtr = sycl::malloc_device(N, Q); Q.parallel_for(N, [=](sycl::item<1> I) { DataPtr[I] = static_cast(I.get_linear_id()); From 7c850498a5dd9cad4ea093142f22caacf7707bd9 Mon Sep 17 00:00:00 2001 From: "Larsen, Steffen" Date: Mon, 15 Sep 2025 06:39:53 -0700 Subject: [PATCH 03/38] Document known issues Signed-off-by: Larsen, Steffen --- ...neapi_inter_process_communication.asciidoc | 42 +++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/sycl/doc/extensions/experimental/sycl_ext_oneapi_inter_process_communication.asciidoc b/sycl/doc/extensions/experimental/sycl_ext_oneapi_inter_process_communication.asciidoc index 16af2048f234d..3d013c08a7827 100644 --- a/sycl/doc/extensions/experimental/sycl_ext_oneapi_inter_process_communication.asciidoc +++ b/sycl/doc/extensions/experimental/sycl_ext_oneapi_inter_process_communication.asciidoc @@ -187,3 +187,45 @@ been destroyed results in undefined behavior. |==== +== Issues + +=== Level Zero file descriptor duplication dependency + +The IPC memory APIs in Level Zero on Linux currently requires the ability to +duplicate file descriptors between processes. For security this is not allowed +by default on Linux-based systems, so in order for the IPC memory APIs to work +with Level Zero on Linux the user must either call `prctl(PR_SET_PTRACER, ...)` +in the IPC handle owner process or enable the functionality globally using + +```bash +sudo bash -c "echo 0 > /proc/sys/kernel/yama/ptrace_scope" +``` + +See also https://github.com/oneapi-src/unified-memory-framework/tree/main?tab=readme-ov-file#level-zero-memory-provider. + + +=== Level Zero memory inconsistency on recreated `ipc_memory` objects + +With the Level Zero backend, the data contained in the memory accessible through +the pointer retrieved through recreating an `ipc_memory` object in another +process may not correspond to the data in the memory in the owner process. + +For example: + 1. Process `A` allocates a block of USM device memory `X`. + 2. Process `A` writes to `X`. + 3. Process `A` creates an `ipc_memory` object from `X` and transfers the handle + data to process `B`. + 4. Process `B` recreates the `ipc_memory` object from the transferred handle + data and gets a pointer to `X` through it. + 5. Process `B` reads from `X`. *This may not result in the same data as what + process `A` wrote to `X`.* + 6. Process `B` writes to `X` and destroys it. + 7. Process `A` destroys its `ipc_memory` object and reads from `X`. This should + be the same as the data process `B` wrote to `X`. + + +=== Level Zero IPC memory Windows support + +The new IPC memory APIs are not currently supported on the Level Zero backend on +Windows systems. + From 6debadb70203520086b1586e56f0f86038a30ff3 Mon Sep 17 00:00:00 2001 From: "Larsen, Steffen" Date: Mon, 15 Sep 2025 06:41:28 -0700 Subject: [PATCH 04/38] Disable on Windows L0 Signed-off-by: Larsen, Steffen --- sycl/test-e2e/Experimental/ipc_memory.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/sycl/test-e2e/Experimental/ipc_memory.cpp b/sycl/test-e2e/Experimental/ipc_memory.cpp index 422c63e360c43..77e75a1afe014 100644 --- a/sycl/test-e2e/Experimental/ipc_memory.cpp +++ b/sycl/test-e2e/Experimental/ipc_memory.cpp @@ -1,5 +1,8 @@ // REQUIRES: aspect-usm_device_allocations && aspect-ext_oneapi_ipc_memory +// UNSUPPORTED: level_zero && windows +// UNSUPPORTED-TRACKER: TODO-0000 + // RUN: %{build} -o %t.out // RUN: %{run} %t.out From d3b6c5600c1ffa22c0520e7d45fffeb5a38a4061 Mon Sep 17 00:00:00 2001 From: "Larsen, Steffen" Date: Tue, 16 Sep 2025 00:47:54 -0700 Subject: [PATCH 05/38] Add tracker Signed-off-by: Larsen, Steffen --- sycl/test-e2e/Experimental/ipc_memory.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sycl/test-e2e/Experimental/ipc_memory.cpp b/sycl/test-e2e/Experimental/ipc_memory.cpp index 77e75a1afe014..fc48ad852f84c 100644 --- a/sycl/test-e2e/Experimental/ipc_memory.cpp +++ b/sycl/test-e2e/Experimental/ipc_memory.cpp @@ -1,7 +1,7 @@ // REQUIRES: aspect-usm_device_allocations && aspect-ext_oneapi_ipc_memory // UNSUPPORTED: level_zero && windows -// UNSUPPORTED-TRACKER: TODO-0000 +// UNSUPPORTED-TRACKER: UMFW-348 // RUN: %{build} -o %t.out // RUN: %{run} %t.out From 29cbc37d7fb06e0d00be8d485d54a1cc09339974 Mon Sep 17 00:00:00 2001 From: "Larsen, Steffen" Date: Wed, 17 Sep 2025 01:21:53 -0700 Subject: [PATCH 06/38] Open handle directly from data Signed-off-by: Larsen, Steffen --- unified-runtime/include/ur_api.h | 126 ++++-------------- unified-runtime/include/ur_api_funcs.def | 2 - unified-runtime/include/ur_ddi.h | 17 +-- unified-runtime/include/ur_print.h | 20 --- unified-runtime/include/ur_print.hpp | 84 ++---------- .../core/EXP-INTER-PROCESS-COMMUNICATION.rst | 2 - .../core/exp-inter-process-communication.yml | 77 +++-------- unified-runtime/scripts/core/registry.yml | 6 - .../source/adapters/cuda/memory.cpp | 60 +++------ .../source/adapters/cuda/memory.hpp | 2 - .../adapters/cuda/ur_interface_loader.cpp | 2 - .../source/adapters/hip/memory.cpp | 19 +-- .../adapters/hip/ur_interface_loader.cpp | 2 - .../source/adapters/level_zero/memory.cpp | 73 ++++------ .../source/adapters/level_zero/memory.hpp | 2 - .../level_zero/ur_interface_loader.cpp | 3 - .../level_zero/ur_interface_loader.hpp | 14 +- .../source/adapters/level_zero/v2/memory.cpp | 75 ++++------- .../source/adapters/level_zero/v2/memory.hpp | 2 - .../source/adapters/mock/ur_mockddi.cpp | 118 ++-------------- .../source/adapters/native_cpu/memory.cpp | 19 +-- .../native_cpu/ur_interface_loader.cpp | 2 - .../source/adapters/offload/memory.cpp | 19 +-- .../adapters/offload/ur_interface_loader.cpp | 2 - .../source/adapters/opencl/memory.cpp | 19 +-- .../adapters/opencl/ur_interface_loader.cpp | 2 - .../loader/layers/tracing/ur_trcddi.cpp | 112 ++-------------- .../loader/layers/validation/ur_valddi.cpp | 111 +++------------ unified-runtime/source/loader/loader.def.in | 4 - unified-runtime/source/loader/loader.map.in | 4 - unified-runtime/source/loader/ur_ldrddi.cpp | 62 ++------- unified-runtime/source/loader/ur_libapi.cpp | 109 +++------------ unified-runtime/source/loader/ur_print.cpp | 16 --- unified-runtime/source/ur_api.cpp | 89 +++---------- 34 files changed, 236 insertions(+), 1040 deletions(-) diff --git a/unified-runtime/include/ur_api.h b/unified-runtime/include/ur_api.h index f45aec5bc2edc..5602bc0b5d0e0 100644 --- a/unified-runtime/include/ur_api.h +++ b/unified-runtime/include/ur_api.h @@ -485,10 +485,6 @@ typedef enum ur_function_t { UR_FUNCTION_IPC_CLOSE_MEM_HANDLE_EXP = 292, /// Enumerator for ::urIPCGetMemHandleDataExp UR_FUNCTION_IPC_GET_MEM_HANDLE_DATA_EXP = 293, - /// Enumerator for ::urIPCCreateMemHandleFromDataExp - UR_FUNCTION_IPC_CREATE_MEM_HANDLE_FROM_DATA_EXP = 294, - /// Enumerator for ::urIPCDestroyMemHandleExp - UR_FUNCTION_IPC_DESTROY_MEM_HANDLE_EXP = 295, /// @cond UR_FUNCTION_FORCE_UINT32 = 0x7fffffff /// @endcond @@ -12387,10 +12383,8 @@ typedef struct ur_exp_ipc_mem_handle_t_ *ur_exp_ipc_mem_handle_t; /// - ::UR_RESULT_ERROR_ADAPTER_SPECIFIC /// - ::UR_RESULT_ERROR_INVALID_NULL_HANDLE /// + `NULL == hContext` -/// + NULL == hContext /// - ::UR_RESULT_ERROR_INVALID_NULL_POINTER /// + `NULL == phIPCMem` -/// + NULL == phIPCMem /// - ::UR_RESULT_ERROR_INVALID_CONTEXT /// - ::UR_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::UR_RESULT_ERROR_OUT_OF_RESOURCES @@ -12412,8 +12406,7 @@ UR_APIEXPORT ur_result_t UR_APICALL urIPCGetMemHandleExp( /// - ::UR_RESULT_ERROR_ADAPTER_SPECIFIC /// - ::UR_RESULT_ERROR_INVALID_NULL_HANDLE /// + `NULL == hContext` -/// + NULL == hContext -/// + NULL == hIPCMem +/// + `NULL == hIPCMem` /// - ::UR_RESULT_ERROR_INVALID_CONTEXT /// - ::UR_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::UR_RESULT_ERROR_OUT_OF_RESOURCES @@ -12424,8 +12417,8 @@ UR_APIEXPORT ur_result_t UR_APICALL urIPCPutMemHandleExp( ur_exp_ipc_mem_handle_t hIPCMem); /////////////////////////////////////////////////////////////////////////////// -/// @brief Opens an inter-process memory handle to get the corresponding pointer -/// to device USM memory +/// @brief Opens an inter-process memory handle from raw data to get the +/// corresponding pointer to device USM memory /// /// @returns /// - ::UR_RESULT_SUCCESS @@ -12434,18 +12427,26 @@ UR_APIEXPORT ur_result_t UR_APICALL urIPCPutMemHandleExp( /// - ::UR_RESULT_ERROR_ADAPTER_SPECIFIC /// - ::UR_RESULT_ERROR_INVALID_NULL_HANDLE /// + `NULL == hContext` -/// + NULL == hContext -/// + NULL == hIPCMem +/// + `NULL == hDevice` /// - ::UR_RESULT_ERROR_INVALID_CONTEXT /// - ::UR_RESULT_ERROR_INVALID_NULL_POINTER -/// + NULL == ppMem +/// + `NULL == ipcMemHandleData` +/// + `NULL == ppMem` +/// - ::UR_RESULT_ERROR_INVALID_VALUE +/// + ipcMemHandleDataSize is not the same as the size of IPC memory +/// handle data /// - ::UR_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::UR_RESULT_ERROR_OUT_OF_RESOURCES UR_APIEXPORT ur_result_t UR_APICALL urIPCOpenMemHandleExp( /// [in] handle of the context object ur_context_handle_t hContext, - /// [in] pointer to the resulting IPC memory handle - ur_exp_ipc_mem_handle_t hIPCMem, + /// [in] handle of the device object the corresponding USM device memory + /// was allocated on + ur_device_handle_t hDevice, + /// [in] the IPC memory handle data + void *ipcMemHandleData, + /// [in] size of the IPC memory handle data + size_t ipcMemHandleDataSize, /// [out] pointer to a pointer to device USM memory void **ppMem); @@ -12459,10 +12460,9 @@ UR_APIEXPORT ur_result_t UR_APICALL urIPCOpenMemHandleExp( /// - ::UR_RESULT_ERROR_ADAPTER_SPECIFIC /// - ::UR_RESULT_ERROR_INVALID_NULL_HANDLE /// + `NULL == hContext` -/// + NULL == hContext /// - ::UR_RESULT_ERROR_INVALID_CONTEXT /// - ::UR_RESULT_ERROR_INVALID_NULL_POINTER -/// + NULL == pMem +/// + `NULL == pMem` /// - ::UR_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::UR_RESULT_ERROR_OUT_OF_RESOURCES UR_APIEXPORT ur_result_t UR_APICALL urIPCCloseMemHandleExp( @@ -12481,8 +12481,7 @@ UR_APIEXPORT ur_result_t UR_APICALL urIPCCloseMemHandleExp( /// - ::UR_RESULT_ERROR_ADAPTER_SPECIFIC /// - ::UR_RESULT_ERROR_INVALID_NULL_HANDLE /// + `NULL == hContext` -/// + NULL == hContext -/// + NULL == hIPCMem +/// + `NULL == hIPCMem` /// - ::UR_RESULT_ERROR_INVALID_CONTEXT /// - ::UR_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::UR_RESULT_ERROR_OUT_OF_RESOURCES @@ -12492,70 +12491,10 @@ UR_APIEXPORT ur_result_t UR_APICALL urIPCGetMemHandleDataExp( /// [in] the IPC memory handle ur_exp_ipc_mem_handle_t hIPCMem, /// [out][optional] a pointer to the IPC memory handle data - const void **ppIPCHandleData, + void **ppIPCHandleData, /// [out][optional] size of the resulting IPC memory handle data size_t *pIPCMemHandleDataSizeRet); -/////////////////////////////////////////////////////////////////////////////// -/// @brief Creates an inter-process memory handle from handle data -/// -/// @returns -/// - ::UR_RESULT_SUCCESS -/// - ::UR_RESULT_ERROR_UNINITIALIZED -/// - ::UR_RESULT_ERROR_DEVICE_LOST -/// - ::UR_RESULT_ERROR_ADAPTER_SPECIFIC -/// - ::UR_RESULT_ERROR_INVALID_NULL_HANDLE -/// + `NULL == hContext` -/// + `NULL == hDevice` -/// + NULL == hContext -/// + NULL == hDevice -/// - ::UR_RESULT_ERROR_INVALID_NULL_POINTER -/// + `NULL == phIPCMem` -/// + NULL == ipcMemHandleData -/// + NULL == phIPCMem -/// - ::UR_RESULT_ERROR_INVALID_CONTEXT -/// - ::UR_RESULT_ERROR_INVALID_VALUE -/// + ipcMemHandleDataSize is not the same as the size of IPC memory -/// handle data -/// - ::UR_RESULT_ERROR_OUT_OF_HOST_MEMORY -/// - ::UR_RESULT_ERROR_OUT_OF_RESOURCES -UR_APIEXPORT ur_result_t UR_APICALL urIPCCreateMemHandleFromDataExp( - /// [in] handle of the context object - ur_context_handle_t hContext, - /// [in] handle of the device object the corresponding USM device memory - /// was allocated on - ur_device_handle_t hDevice, - /// [in] the IPC memory handle data - const void *ipcMemHandleData, - /// [in] size of the IPC memory handle data - size_t ipcMemHandleDataSize, - /// [out] the IPC memory handle - ur_exp_ipc_mem_handle_t *phIPCMem); - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Destroys an inter-process memory handle created through -/// urIPCCreateMemHandleFromDataExp -/// -/// @returns -/// - ::UR_RESULT_SUCCESS -/// - ::UR_RESULT_ERROR_UNINITIALIZED -/// - ::UR_RESULT_ERROR_DEVICE_LOST -/// - ::UR_RESULT_ERROR_ADAPTER_SPECIFIC -/// - ::UR_RESULT_ERROR_INVALID_NULL_HANDLE -/// + `NULL == hContext` -/// + NULL == hContext -/// + NULL == hIPCMem -/// - ::UR_RESULT_ERROR_INVALID_CONTEXT -/// - ::UR_RESULT_ERROR_INVALID_VALUE -/// + hIPCMem was not created through CreateMemHandleFromDataExp -/// - ::UR_RESULT_ERROR_OUT_OF_HOST_MEMORY -/// - ::UR_RESULT_ERROR_OUT_OF_RESOURCES -UR_APIEXPORT ur_result_t UR_APICALL urIPCDestroyMemHandleExp( - /// [in] handle of the context object - ur_context_handle_t hContext, - /// [in] the IPC memory handle - ur_exp_ipc_mem_handle_t hIPCMem); - #if !defined(__GNUC__) #pragma endregion #endif @@ -15656,7 +15595,9 @@ typedef struct ur_ipc_put_mem_handle_exp_params_t { /// allowing the callback the ability to modify the parameter's value typedef struct ur_ipc_open_mem_handle_exp_params_t { ur_context_handle_t *phContext; - ur_exp_ipc_mem_handle_t *phIPCMem; + ur_device_handle_t *phDevice; + void **pipcMemHandleData; + size_t *pipcMemHandleDataSize; void ***pppMem; } ur_ipc_open_mem_handle_exp_params_t; @@ -15676,31 +15617,10 @@ typedef struct ur_ipc_close_mem_handle_exp_params_t { typedef struct ur_ipc_get_mem_handle_data_exp_params_t { ur_context_handle_t *phContext; ur_exp_ipc_mem_handle_t *phIPCMem; - const void ***pppIPCHandleData; + void ***pppIPCHandleData; size_t **ppIPCMemHandleDataSizeRet; } ur_ipc_get_mem_handle_data_exp_params_t; -/////////////////////////////////////////////////////////////////////////////// -/// @brief Function parameters for urIPCCreateMemHandleFromDataExp -/// @details Each entry is a pointer to the parameter passed to the function; -/// allowing the callback the ability to modify the parameter's value -typedef struct ur_ipc_create_mem_handle_from_data_exp_params_t { - ur_context_handle_t *phContext; - ur_device_handle_t *phDevice; - const void **pipcMemHandleData; - size_t *pipcMemHandleDataSize; - ur_exp_ipc_mem_handle_t **pphIPCMem; -} ur_ipc_create_mem_handle_from_data_exp_params_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Function parameters for urIPCDestroyMemHandleExp -/// @details Each entry is a pointer to the parameter passed to the function; -/// allowing the callback the ability to modify the parameter's value -typedef struct ur_ipc_destroy_mem_handle_exp_params_t { - ur_context_handle_t *phContext; - ur_exp_ipc_mem_handle_t *phIPCMem; -} ur_ipc_destroy_mem_handle_exp_params_t; - /////////////////////////////////////////////////////////////////////////////// /// @brief Function parameters for urMemoryExportAllocExportableMemoryExp /// @details Each entry is a pointer to the parameter passed to the function; diff --git a/unified-runtime/include/ur_api_funcs.def b/unified-runtime/include/ur_api_funcs.def index f6e347cb16380..4b72a768d8ca3 100644 --- a/unified-runtime/include/ur_api_funcs.def +++ b/unified-runtime/include/ur_api_funcs.def @@ -211,8 +211,6 @@ _UR_API(urIPCPutMemHandleExp) _UR_API(urIPCOpenMemHandleExp) _UR_API(urIPCCloseMemHandleExp) _UR_API(urIPCGetMemHandleDataExp) -_UR_API(urIPCCreateMemHandleFromDataExp) -_UR_API(urIPCDestroyMemHandleExp) _UR_API(urMemoryExportAllocExportableMemoryExp) _UR_API(urMemoryExportFreeExportableMemoryExp) _UR_API(urMemoryExportExportMemoryHandleExp) diff --git a/unified-runtime/include/ur_ddi.h b/unified-runtime/include/ur_ddi.h index f26c71af2d67c..035be44791ab7 100644 --- a/unified-runtime/include/ur_ddi.h +++ b/unified-runtime/include/ur_ddi.h @@ -1800,7 +1800,7 @@ typedef ur_result_t(UR_APICALL *ur_pfnIPCPutMemHandleExp_t)( /////////////////////////////////////////////////////////////////////////////// /// @brief Function-pointer for urIPCOpenMemHandleExp typedef ur_result_t(UR_APICALL *ur_pfnIPCOpenMemHandleExp_t)( - ur_context_handle_t, ur_exp_ipc_mem_handle_t, void **); + ur_context_handle_t, ur_device_handle_t, void *, size_t, void **); /////////////////////////////////////////////////////////////////////////////// /// @brief Function-pointer for urIPCCloseMemHandleExp @@ -1810,18 +1810,7 @@ typedef ur_result_t(UR_APICALL *ur_pfnIPCCloseMemHandleExp_t)( /////////////////////////////////////////////////////////////////////////////// /// @brief Function-pointer for urIPCGetMemHandleDataExp typedef ur_result_t(UR_APICALL *ur_pfnIPCGetMemHandleDataExp_t)( - ur_context_handle_t, ur_exp_ipc_mem_handle_t, const void **, size_t *); - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Function-pointer for urIPCCreateMemHandleFromDataExp -typedef ur_result_t(UR_APICALL *ur_pfnIPCCreateMemHandleFromDataExp_t)( - ur_context_handle_t, ur_device_handle_t, const void *, size_t, - ur_exp_ipc_mem_handle_t *); - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Function-pointer for urIPCDestroyMemHandleExp -typedef ur_result_t(UR_APICALL *ur_pfnIPCDestroyMemHandleExp_t)( - ur_context_handle_t, ur_exp_ipc_mem_handle_t); + ur_context_handle_t, ur_exp_ipc_mem_handle_t, void **, size_t *); /////////////////////////////////////////////////////////////////////////////// /// @brief Table of IPCExp functions pointers @@ -1831,8 +1820,6 @@ typedef struct ur_ipc_exp_dditable_t { ur_pfnIPCOpenMemHandleExp_t pfnOpenMemHandleExp; ur_pfnIPCCloseMemHandleExp_t pfnCloseMemHandleExp; ur_pfnIPCGetMemHandleDataExp_t pfnGetMemHandleDataExp; - ur_pfnIPCCreateMemHandleFromDataExp_t pfnCreateMemHandleFromDataExp; - ur_pfnIPCDestroyMemHandleExp_t pfnDestroyMemHandleExp; } ur_ipc_exp_dditable_t; /////////////////////////////////////////////////////////////////////////////// diff --git a/unified-runtime/include/ur_print.h b/unified-runtime/include/ur_print.h index 99a80097b522d..dd38252f71399 100644 --- a/unified-runtime/include/ur_print.h +++ b/unified-runtime/include/ur_print.h @@ -3540,26 +3540,6 @@ UR_APIEXPORT ur_result_t UR_APICALL urPrintIpcGetMemHandleDataExpParams( const struct ur_ipc_get_mem_handle_data_exp_params_t *params, char *buffer, const size_t buff_size, size_t *out_size); -/////////////////////////////////////////////////////////////////////////////// -/// @brief Print ur_ipc_create_mem_handle_from_data_exp_params_t struct -/// @returns -/// - ::UR_RESULT_SUCCESS -/// - ::UR_RESULT_ERROR_INVALID_SIZE -/// - `buff_size < out_size` -UR_APIEXPORT ur_result_t UR_APICALL urPrintIpcCreateMemHandleFromDataExpParams( - const struct ur_ipc_create_mem_handle_from_data_exp_params_t *params, - char *buffer, const size_t buff_size, size_t *out_size); - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Print ur_ipc_destroy_mem_handle_exp_params_t struct -/// @returns -/// - ::UR_RESULT_SUCCESS -/// - ::UR_RESULT_ERROR_INVALID_SIZE -/// - `buff_size < out_size` -UR_APIEXPORT ur_result_t UR_APICALL urPrintIpcDestroyMemHandleExpParams( - const struct ur_ipc_destroy_mem_handle_exp_params_t *params, char *buffer, - const size_t buff_size, size_t *out_size); - /////////////////////////////////////////////////////////////////////////////// /// @brief Print ur_memory_export_alloc_exportable_memory_exp_params_t struct /// @returns diff --git a/unified-runtime/include/ur_print.hpp b/unified-runtime/include/ur_print.hpp index 48caa9701f038..73448963a1dc3 100644 --- a/unified-runtime/include/ur_print.hpp +++ b/unified-runtime/include/ur_print.hpp @@ -1290,12 +1290,6 @@ inline std::ostream &operator<<(std::ostream &os, enum ur_function_t value) { case UR_FUNCTION_IPC_GET_MEM_HANDLE_DATA_EXP: os << "UR_FUNCTION_IPC_GET_MEM_HANDLE_DATA_EXP"; break; - case UR_FUNCTION_IPC_CREATE_MEM_HANDLE_FROM_DATA_EXP: - os << "UR_FUNCTION_IPC_CREATE_MEM_HANDLE_FROM_DATA_EXP"; - break; - case UR_FUNCTION_IPC_DESTROY_MEM_HANDLE_EXP: - os << "UR_FUNCTION_IPC_DESTROY_MEM_HANDLE_EXP"; - break; default: os << "unknown enumerator"; break; @@ -20354,9 +20348,19 @@ inline std::ostream &operator<<( ur::details::printPtr(os, *(params->phContext)); os << ", "; - os << ".hIPCMem = "; + os << ".hDevice = "; - ur::details::printPtr(os, *(params->phIPCMem)); + ur::details::printPtr(os, *(params->phDevice)); + + os << ", "; + os << ".ipcMemHandleData = "; + + os << *(params->pipcMemHandleData); + + os << ", "; + os << ".ipcMemHandleDataSize = "; + + os << *(params->pipcMemHandleDataSize); os << ", "; os << ".ppMem = "; @@ -20418,63 +20422,6 @@ operator<<(std::ostream &os, return os; } -/////////////////////////////////////////////////////////////////////////////// -/// @brief Print operator for the -/// ur_ipc_create_mem_handle_from_data_exp_params_t type -/// @returns -/// std::ostream & -inline std::ostream & -operator<<(std::ostream &os, [[maybe_unused]] const struct - ur_ipc_create_mem_handle_from_data_exp_params_t *params) { - - os << ".hContext = "; - - ur::details::printPtr(os, *(params->phContext)); - - os << ", "; - os << ".hDevice = "; - - ur::details::printPtr(os, *(params->phDevice)); - - os << ", "; - os << ".ipcMemHandleData = "; - - os << *(params->pipcMemHandleData); - - os << ", "; - os << ".ipcMemHandleDataSize = "; - - os << *(params->pipcMemHandleDataSize); - - os << ", "; - os << ".phIPCMem = "; - - ur::details::printPtr(os, *(params->pphIPCMem)); - - return os; -} - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Print operator for the ur_ipc_destroy_mem_handle_exp_params_t type -/// @returns -/// std::ostream & -inline std::ostream & -operator<<(std::ostream &os, - [[maybe_unused]] const struct ur_ipc_destroy_mem_handle_exp_params_t - *params) { - - os << ".hContext = "; - - ur::details::printPtr(os, *(params->phContext)); - - os << ", "; - os << ".hIPCMem = "; - - ur::details::printPtr(os, *(params->phIPCMem)); - - return os; -} - /////////////////////////////////////////////////////////////////////////////// /// @brief Print operator for the /// ur_memory_export_alloc_exportable_memory_exp_params_t type @@ -21954,13 +21901,6 @@ inline ur_result_t UR_APICALL printFunctionParams(std::ostream &os, case UR_FUNCTION_IPC_GET_MEM_HANDLE_DATA_EXP: { os << (const struct ur_ipc_get_mem_handle_data_exp_params_t *)params; } break; - case UR_FUNCTION_IPC_CREATE_MEM_HANDLE_FROM_DATA_EXP: { - os << (const struct ur_ipc_create_mem_handle_from_data_exp_params_t *) - params; - } break; - case UR_FUNCTION_IPC_DESTROY_MEM_HANDLE_EXP: { - os << (const struct ur_ipc_destroy_mem_handle_exp_params_t *)params; - } break; case UR_FUNCTION_MEMORY_EXPORT_ALLOC_EXPORTABLE_MEMORY_EXP: { os << (const struct ur_memory_export_alloc_exportable_memory_exp_params_t *) params; diff --git a/unified-runtime/scripts/core/EXP-INTER-PROCESS-COMMUNICATION.rst b/unified-runtime/scripts/core/EXP-INTER-PROCESS-COMMUNICATION.rst index 1b0e0a5735eca..73d0616a1d7c3 100644 --- a/unified-runtime/scripts/core/EXP-INTER-PROCESS-COMMUNICATION.rst +++ b/unified-runtime/scripts/core/EXP-INTER-PROCESS-COMMUNICATION.rst @@ -47,8 +47,6 @@ Functions * ${x}IPCOpenMemHandleExp * ${x}IPCCloseMemHandleExp * ${x}IPCGetMemHandleDataExp - * ${x}IPCCreateMemHandleFromDataExp - * ${x}IPCDestroyMemHandleExp Changelog -------------------------------------------------------------------------------- diff --git a/unified-runtime/scripts/core/exp-inter-process-communication.yml b/unified-runtime/scripts/core/exp-inter-process-communication.yml index 5812430658a1c..6f7e513bd6739 100644 --- a/unified-runtime/scripts/core/exp-inter-process-communication.yml +++ b/unified-runtime/scripts/core/exp-inter-process-communication.yml @@ -73,7 +73,7 @@ returns: - $X_RESULT_ERROR_OUT_OF_RESOURCES --- #-------------------------------------------------------------------------- type: function -desc: "Opens an inter-process memory handle to get the corresponding pointer to device USM memory" +desc: "Opens an inter-process memory handle from raw data to get the corresponding pointer to device USM memory" class: $xIPC name: OpenMemHandleExp ordinal: "0" @@ -81,9 +81,15 @@ params: - type: $x_context_handle_t name: hContext desc: "[in] handle of the context object" - - type: $x_exp_ipc_mem_handle_t - name: hIPCMem - desc: "[in] pointer to the resulting IPC memory handle" + - type: $x_device_handle_t + name: hDevice + desc: "[in] handle of the device object the corresponding USM device memory was allocated on" + - type: void * + name: ipcMemHandleData + desc: "[in] the IPC memory handle data" + - type: size_t + name: ipcMemHandleDataSize + desc: "[in] size of the IPC memory handle data" - type: void ** name: ppMem desc: "[out] pointer to a pointer to device USM memory" @@ -91,9 +97,12 @@ returns: - $X_RESULT_ERROR_INVALID_CONTEXT - $X_RESULT_ERROR_INVALID_NULL_HANDLE: - "NULL == hContext" - - "NULL == hIPCMem" + - "NULL == hDevice" - $X_RESULT_ERROR_INVALID_NULL_POINTER: + - "NULL == ipcMemHandleData" - "NULL == ppMem" + - $X_RESULT_ERROR_INVALID_VALUE: + - "ipcMemHandleDataSize is not the same as the size of IPC memory handle data" - $X_RESULT_ERROR_OUT_OF_HOST_MEMORY - $X_RESULT_ERROR_OUT_OF_RESOURCES --- #-------------------------------------------------------------------------- @@ -130,7 +139,7 @@ params: - type: $x_exp_ipc_mem_handle_t name: hIPCMem desc: "[in] the IPC memory handle" - - type: const void** + - type: void** name: ppIPCHandleData desc: "[out][optional] a pointer to the IPC memory handle data" - type: size_t* @@ -143,59 +152,3 @@ returns: - "NULL == hIPCMem" - $X_RESULT_ERROR_OUT_OF_HOST_MEMORY - $X_RESULT_ERROR_OUT_OF_RESOURCES ---- #-------------------------------------------------------------------------- -type: function -desc: "Creates an inter-process memory handle from handle data" -class: $xIPC -name: CreateMemHandleFromDataExp -ordinal: "0" -params: - - type: $x_context_handle_t - name: hContext - desc: "[in] handle of the context object" - - type: $x_device_handle_t - name: hDevice - desc: "[in] handle of the device object the corresponding USM device memory was allocated on" - - type: const void * - name: ipcMemHandleData - desc: "[in] the IPC memory handle data" - - type: size_t - name: ipcMemHandleDataSize - desc: "[in] size of the IPC memory handle data" - - type: $x_exp_ipc_mem_handle_t* - name: phIPCMem - desc: "[out] the IPC memory handle" -returns: - - $X_RESULT_ERROR_INVALID_CONTEXT - - $X_RESULT_ERROR_INVALID_NULL_HANDLE: - - "NULL == hContext" - - "NULL == hDevice" - - $X_RESULT_ERROR_INVALID_NULL_POINTER: - - "NULL == ipcMemHandleData" - - "NULL == phIPCMem" - - $X_RESULT_ERROR_INVALID_VALUE: - - "ipcMemHandleDataSize is not the same as the size of IPC memory handle data" - - $X_RESULT_ERROR_OUT_OF_HOST_MEMORY - - $X_RESULT_ERROR_OUT_OF_RESOURCES ---- #-------------------------------------------------------------------------- -type: function -desc: "Destroys an inter-process memory handle created through urIPCCreateMemHandleFromDataExp" -class: $xIPC -name: DestroyMemHandleExp -ordinal: "0" -params: - - type: $x_context_handle_t - name: hContext - desc: "[in] handle of the context object" - - type: $x_exp_ipc_mem_handle_t - name: hIPCMem - desc: "[in] the IPC memory handle" -returns: - - $X_RESULT_ERROR_INVALID_CONTEXT - - $X_RESULT_ERROR_INVALID_NULL_HANDLE: - - "NULL == hContext" - - "NULL == hIPCMem" - - $X_RESULT_ERROR_INVALID_VALUE: - - "hIPCMem was not created through CreateMemHandleFromDataExp" - - $X_RESULT_ERROR_OUT_OF_HOST_MEMORY - - $X_RESULT_ERROR_OUT_OF_RESOURCES diff --git a/unified-runtime/scripts/core/registry.yml b/unified-runtime/scripts/core/registry.yml index bfa91ae5cdc06..020374a3484bb 100644 --- a/unified-runtime/scripts/core/registry.yml +++ b/unified-runtime/scripts/core/registry.yml @@ -685,12 +685,6 @@ etors: - name: IPC_GET_MEM_HANDLE_DATA_EXP desc: Enumerator for $xIPCGetMemHandleDataExp value: '293' -- name: IPC_CREATE_MEM_HANDLE_FROM_DATA_EXP - desc: Enumerator for $xIPCCreateMemHandleFromDataExp - value: '294' -- name: IPC_DESTROY_MEM_HANDLE_EXP - desc: Enumerator for $xIPCDestroyMemHandleExp - value: '295' --- type: enum desc: Defines structure types diff --git a/unified-runtime/source/adapters/cuda/memory.cpp b/unified-runtime/source/adapters/cuda/memory.cpp index 751abbd9320b0..0461b553a4fb0 100644 --- a/unified-runtime/source/adapters/cuda/memory.cpp +++ b/unified-runtime/source/adapters/cuda/memory.cpp @@ -594,10 +594,10 @@ CUsurfObject SurfaceMem::getSurface(const ur_device_handle_t Device) { UR_APIEXPORT ur_result_t UR_APICALL urIPCGetMemHandleExp( ur_context_handle_t, void *pMem, ur_exp_ipc_mem_handle_t *phIPCMem) { auto resHandle = std::make_unique(); - resHandle->CreatedFromData = false; - auto umfRet = umfPoolByPtr(pMem, &resHandle->UMFPool); - if (umfRet != UMF_RESULT_SUCCESS || !resHandle->UMFPool) + umf_memory_pool_handle_t umfPool; + auto umfRet = umfPoolByPtr(pMem, &umfPool); + if (umfRet != UMF_RESULT_SUCCESS || !umfPool) return UR_RESULT_ERROR_UNKNOWN; umfRet = umfGetIPCHandle(pMem, &resHandle->UMFHandle, &resHandle->HandleSize); @@ -619,13 +619,26 @@ urIPCPutMemHandleExp(ur_context_handle_t, ur_exp_ipc_mem_handle_t hIPCMem) { } UR_APIEXPORT ur_result_t UR_APICALL urIPCOpenMemHandleExp( - ur_context_handle_t, ur_exp_ipc_mem_handle_t hIPCMem, void **ppMem) { + ur_context_handle_t hContext, ur_device_handle_t hDevice, + void *pIPCMemHandleData, size_t ipcMemHandleDataSize, void **ppMem) { + umf_memory_pool_handle_t umfPool = hDevice->MemoryPoolDevice; + + size_t umfHandleSize = 0; + auto umfRet = umfPoolGetIPCHandleSize(umfPool, &umfHandleSize); + if (umfRet != UMF_RESULT_SUCCESS || umfHandleSize == 0) + return UR_RESULT_ERROR_UNKNOWN; + + if (umfHandleSize != ipcMemHandleDataSize) + return UR_RESULT_ERROR_INVALID_VALUE; + umf_ipc_handler_handle_t umfIPCHandler; - auto umfRet = umfPoolGetIPCHandler(hIPCMem->UMFPool, &umfIPCHandler); + umfRet = umfPoolGetIPCHandler(umfPool, &umfIPCHandler); if (umfRet != UMF_RESULT_SUCCESS || !umfIPCHandler) return UR_RESULT_ERROR_UNKNOWN; - umfRet = umfOpenIPCHandle(umfIPCHandler, hIPCMem->UMFHandle, ppMem); + umfRet = umfOpenIPCHandle( + umfIPCHandler, reinterpret_cast(pIPCMemHandleData), + ppMem); return umfRet == UMF_RESULT_SUCCESS ? UR_RESULT_SUCCESS : UR_RESULT_ERROR_UNKNOWN; } @@ -639,43 +652,10 @@ UR_APIEXPORT ur_result_t UR_APICALL urIPCCloseMemHandleExp(ur_context_handle_t, UR_APIEXPORT ur_result_t UR_APICALL urIPCGetMemHandleDataExp( ur_context_handle_t, ur_exp_ipc_mem_handle_t hIPCMem, - const void **ppIPCHandleData, size_t *pIPCMemHandleDataSizeRet) { + void **ppIPCHandleData, size_t *pIPCMemHandleDataSizeRet) { if (ppIPCHandleData) *ppIPCHandleData = hIPCMem->UMFHandle; if (pIPCMemHandleDataSizeRet) *pIPCMemHandleDataSizeRet = hIPCMem->HandleSize; return UR_RESULT_SUCCESS; } - -UR_APIEXPORT ur_result_t UR_APICALL urIPCCreateMemHandleFromDataExp( - ur_context_handle_t, ur_device_handle_t hDevice, - const void *pIPCMemHandleData, size_t ipcMemHandleDataSize, - ur_exp_ipc_mem_handle_t *phIPCMem) { - umf_memory_pool_handle_t umfPool = hDevice->MemoryPoolDevice; - - size_t umfHandleSize = 0; - auto umfRet = umfPoolGetIPCHandleSize(umfPool, &umfHandleSize); - if (umfRet != UMF_RESULT_SUCCESS || umfHandleSize == 0) - return UR_RESULT_ERROR_UNKNOWN; - - if (umfHandleSize != ipcMemHandleDataSize) - return UR_RESULT_ERROR_INVALID_VALUE; - - auto resHandle = std::make_unique(); - resHandle->UMFPool = umfPool; - resHandle->UMFHandle = - reinterpret_cast(std::malloc(umfHandleSize)); - std::memcpy(resHandle->UMFHandle, pIPCMemHandleData, umfHandleSize); - resHandle->HandleSize = umfHandleSize; - resHandle->CreatedFromData = true; - *phIPCMem = resHandle.release(); - return UR_RESULT_SUCCESS; -} - -UR_APIEXPORT ur_result_t UR_APICALL -urIPCDestroyMemHandleExp(ur_context_handle_t, ur_exp_ipc_mem_handle_t hIPCMem) { - if (!hIPCMem->CreatedFromData) - return UR_RESULT_ERROR_INVALID_VALUE; - std::free(hIPCMem); - return UR_RESULT_SUCCESS; -} diff --git a/unified-runtime/source/adapters/cuda/memory.hpp b/unified-runtime/source/adapters/cuda/memory.hpp index 222da95c7824f..9d3f19c4b9c58 100644 --- a/unified-runtime/source/adapters/cuda/memory.hpp +++ b/unified-runtime/source/adapters/cuda/memory.hpp @@ -442,8 +442,6 @@ struct ur_mem_handle_t_ : ur::cuda::handle_base { }; struct ur_exp_ipc_mem_handle_t_ { - umf_memory_pool_handle_t UMFPool; umf_ipc_handle_t UMFHandle = nullptr; size_t HandleSize = 0; - bool CreatedFromData = false; }; diff --git a/unified-runtime/source/adapters/cuda/ur_interface_loader.cpp b/unified-runtime/source/adapters/cuda/ur_interface_loader.cpp index 2d24a5b6c730f..2eb42d8bc0dea 100644 --- a/unified-runtime/source/adapters/cuda/ur_interface_loader.cpp +++ b/unified-runtime/source/adapters/cuda/ur_interface_loader.cpp @@ -470,8 +470,6 @@ UR_DLLEXPORT ur_result_t UR_APICALL urGetIPCExpProcAddrTable( pDdiTable->pfnOpenMemHandleExp = urIPCOpenMemHandleExp; pDdiTable->pfnCloseMemHandleExp = urIPCCloseMemHandleExp; pDdiTable->pfnGetMemHandleDataExp = urIPCGetMemHandleDataExp; - pDdiTable->pfnCreateMemHandleFromDataExp = urIPCCreateMemHandleFromDataExp; - pDdiTable->pfnDestroyMemHandleExp = urIPCDestroyMemHandleExp; return UR_RESULT_SUCCESS; } diff --git a/unified-runtime/source/adapters/hip/memory.cpp b/unified-runtime/source/adapters/hip/memory.cpp index a678ac7914416..f052fd2efc785 100644 --- a/unified-runtime/source/adapters/hip/memory.cpp +++ b/unified-runtime/source/adapters/hip/memory.cpp @@ -651,8 +651,10 @@ urIPCPutMemHandleExp(ur_context_handle_t, ur_exp_ipc_mem_handle_t) { return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; } -UR_APIEXPORT ur_result_t UR_APICALL -urIPCOpenMemHandleExp(ur_context_handle_t, ur_exp_ipc_mem_handle_t, void **) { +UR_APIEXPORT ur_result_t UR_APICALL urIPCOpenMemHandleExp(ur_context_handle_t, + ur_device_handle_t, + void *, size_t, + void **) { return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; } @@ -662,17 +664,6 @@ UR_APIEXPORT ur_result_t UR_APICALL urIPCCloseMemHandleExp(ur_context_handle_t, } UR_APIEXPORT ur_result_t UR_APICALL urIPCGetMemHandleDataExp( - ur_context_handle_t, ur_exp_ipc_mem_handle_t, const void **, size_t *) { - return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; -} - -UR_APIEXPORT ur_result_t UR_APICALL urIPCCreateMemHandleFromDataExp( - ur_context_handle_t, ur_device_handle_t, const void *, size_t, - ur_exp_ipc_mem_handle_t *) { - return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; -} - -UR_APIEXPORT ur_result_t UR_APICALL -urIPCDestroyMemHandleExp(ur_context_handle_t, ur_exp_ipc_mem_handle_t) { + ur_context_handle_t, ur_exp_ipc_mem_handle_t, void **, size_t *) { return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; } diff --git a/unified-runtime/source/adapters/hip/ur_interface_loader.cpp b/unified-runtime/source/adapters/hip/ur_interface_loader.cpp index 68757af457995..9c6cf548b4198 100644 --- a/unified-runtime/source/adapters/hip/ur_interface_loader.cpp +++ b/unified-runtime/source/adapters/hip/ur_interface_loader.cpp @@ -463,8 +463,6 @@ UR_DLLEXPORT ur_result_t UR_APICALL urGetIPCExpProcAddrTable( pDdiTable->pfnOpenMemHandleExp = urIPCOpenMemHandleExp; pDdiTable->pfnCloseMemHandleExp = urIPCCloseMemHandleExp; pDdiTable->pfnGetMemHandleDataExp = urIPCGetMemHandleDataExp; - pDdiTable->pfnCreateMemHandleFromDataExp = urIPCCreateMemHandleFromDataExp; - pDdiTable->pfnDestroyMemHandleExp = urIPCDestroyMemHandleExp; return UR_RESULT_SUCCESS; } diff --git a/unified-runtime/source/adapters/level_zero/memory.cpp b/unified-runtime/source/adapters/level_zero/memory.cpp index 88fadffde0af6..6c977dace0113 100644 --- a/unified-runtime/source/adapters/level_zero/memory.cpp +++ b/unified-runtime/source/adapters/level_zero/memory.cpp @@ -1955,10 +1955,10 @@ ur_result_t urEnqueueWriteHostPipe( ur_result_t urIPCGetMemHandleExp(ur_context_handle_t, void *pMem, ur_exp_ipc_mem_handle_t *phIPCMem) { auto resHandle = std::make_unique(); - resHandle->CreatedFromData = false; - auto umfRet = umfPoolByPtr(pMem, &resHandle->UMFPool); - if (umfRet != UMF_RESULT_SUCCESS || !resHandle->UMFPool) + umf_memory_pool_handle_t umfPool; + auto umfRet = umfPoolByPtr(pMem, &umfPool); + if (umfRet != UMF_RESULT_SUCCESS || !umfPool) return UR_RESULT_ERROR_UNKNOWN; umfRet = umfGetIPCHandle(pMem, &resHandle->UMFHandle, &resHandle->HandleSize); @@ -1979,15 +1979,32 @@ ur_result_t urIPCPutMemHandleExp(ur_context_handle_t, return UR_RESULT_SUCCESS; } -ur_result_t urIPCOpenMemHandleExp(ur_context_handle_t, - ur_exp_ipc_mem_handle_t hIPCMem, - void **ppMem) { +ur_result_t urIPCOpenMemHandleExp(ur_context_handle_t hContext, + ur_device_handle_t hDevice, + void *pIPCMemHandleData, + size_t ipcMemHandleDataSize, void **ppMem) { + auto *pool = hContext->DefaultPool.getPool(usm::pool_descriptor{ + &hContext->DefaultPool, hContext, hDevice, UR_USM_TYPE_DEVICE, false}); + if (!pool) + return UR_RESULT_ERROR_INVALID_CONTEXT; + umf_memory_pool_handle_t umfPool = pool->UmfPool.get(); + + size_t umfHandleSize = 0; + auto umfRet = umfPoolGetIPCHandleSize(umfPool, &umfHandleSize); + if (umfRet != UMF_RESULT_SUCCESS || umfHandleSize == 0) + return UR_RESULT_ERROR_UNKNOWN; + + if (umfHandleSize != ipcMemHandleDataSize) + return UR_RESULT_ERROR_INVALID_VALUE; + umf_ipc_handler_handle_t umfIPCHandler; - auto umfRet = umfPoolGetIPCHandler(hIPCMem->UMFPool, &umfIPCHandler); + umfRet = umfPoolGetIPCHandler(umfPool, &umfIPCHandler); if (umfRet != UMF_RESULT_SUCCESS || !umfIPCHandler) return UR_RESULT_ERROR_UNKNOWN; - umfRet = umfOpenIPCHandle(umfIPCHandler, hIPCMem->UMFHandle, ppMem); + umfRet = umfOpenIPCHandle( + umfIPCHandler, reinterpret_cast(pIPCMemHandleData), + ppMem); return umfRet == UMF_RESULT_SUCCESS ? UR_RESULT_SUCCESS : UR_RESULT_ERROR_UNKNOWN; } @@ -2000,7 +2017,7 @@ ur_result_t urIPCCloseMemHandleExp(ur_context_handle_t, void *pMem) { ur_result_t urIPCGetMemHandleDataExp(ur_context_handle_t, ur_exp_ipc_mem_handle_t hIPCMem, - const void **ppIPCHandleData, + void **ppIPCHandleData, size_t *pIPCMemHandleDataSizeRet) { if (ppIPCHandleData) *ppIPCHandleData = hIPCMem->UMFHandle; @@ -2009,44 +2026,6 @@ ur_result_t urIPCGetMemHandleDataExp(ur_context_handle_t, return UR_RESULT_SUCCESS; } -ur_result_t urIPCCreateMemHandleFromDataExp(ur_context_handle_t hContext, - ur_device_handle_t hDevice, - const void *pIPCMemHandleData, - size_t ipcMemHandleDataSize, - ur_exp_ipc_mem_handle_t *phIPCMem) { - auto *pool = hContext->DefaultPool.getPool(usm::pool_descriptor{ - &hContext->DefaultPool, hContext, hDevice, UR_USM_TYPE_DEVICE, false}); - if (!pool) - return UR_RESULT_ERROR_INVALID_CONTEXT; - umf_memory_pool_handle_t umfPool = pool->UmfPool.get(); - - size_t umfHandleSize = 0; - auto umfRet = umfPoolGetIPCHandleSize(umfPool, &umfHandleSize); - if (umfRet != UMF_RESULT_SUCCESS || umfHandleSize == 0) - return UR_RESULT_ERROR_UNKNOWN; - - if (umfHandleSize != ipcMemHandleDataSize) - return UR_RESULT_ERROR_INVALID_VALUE; - - auto resHandle = std::make_unique(); - resHandle->UMFPool = umfPool; - resHandle->UMFHandle = - reinterpret_cast(std::malloc(umfHandleSize)); - std::memcpy(resHandle->UMFHandle, pIPCMemHandleData, umfHandleSize); - resHandle->HandleSize = umfHandleSize; - resHandle->CreatedFromData = true; - *phIPCMem = resHandle.release(); - return UR_RESULT_SUCCESS; -} - -ur_result_t urIPCDestroyMemHandleExp(ur_context_handle_t, - ur_exp_ipc_mem_handle_t hIPCMem) { - if (!hIPCMem->CreatedFromData) - return UR_RESULT_ERROR_INVALID_VALUE; - std::free(hIPCMem); - return UR_RESULT_SUCCESS; -} - } // namespace ur::level_zero // If indirect access tracking is enabled then performs reference counting, diff --git a/unified-runtime/source/adapters/level_zero/memory.hpp b/unified-runtime/source/adapters/level_zero/memory.hpp index 052aa5d9504da..cc3917f0e6b43 100644 --- a/unified-runtime/source/adapters/level_zero/memory.hpp +++ b/unified-runtime/source/adapters/level_zero/memory.hpp @@ -245,10 +245,8 @@ struct ur_image final : ur_mem_handle_t_ { }; struct ur_exp_ipc_mem_handle_t_ { - umf_memory_pool_handle_t UMFPool; umf_ipc_handle_t UMFHandle = nullptr; size_t HandleSize = 0; - bool CreatedFromData = false; }; template diff --git a/unified-runtime/source/adapters/level_zero/ur_interface_loader.cpp b/unified-runtime/source/adapters/level_zero/ur_interface_loader.cpp index a98471f61f64c..fe2d9d49e6024 100644 --- a/unified-runtime/source/adapters/level_zero/ur_interface_loader.cpp +++ b/unified-runtime/source/adapters/level_zero/ur_interface_loader.cpp @@ -269,9 +269,6 @@ UR_APIEXPORT ur_result_t UR_APICALL urGetIPCExpProcAddrTable( pDdiTable->pfnOpenMemHandleExp = ur::level_zero::urIPCOpenMemHandleExp; pDdiTable->pfnCloseMemHandleExp = ur::level_zero::urIPCCloseMemHandleExp; pDdiTable->pfnGetMemHandleDataExp = ur::level_zero::urIPCGetMemHandleDataExp; - pDdiTable->pfnCreateMemHandleFromDataExp = - ur::level_zero::urIPCCreateMemHandleFromDataExp; - pDdiTable->pfnDestroyMemHandleExp = ur::level_zero::urIPCDestroyMemHandleExp; return result; } diff --git a/unified-runtime/source/adapters/level_zero/ur_interface_loader.hpp b/unified-runtime/source/adapters/level_zero/ur_interface_loader.hpp index 7ab153caa04bf..0c7f6a9694be0 100644 --- a/unified-runtime/source/adapters/level_zero/ur_interface_loader.hpp +++ b/unified-runtime/source/adapters/level_zero/ur_interface_loader.hpp @@ -773,20 +773,14 @@ ur_result_t urIPCGetMemHandleExp(ur_context_handle_t hContext, void *pMem, ur_result_t urIPCPutMemHandleExp(ur_context_handle_t hContext, ur_exp_ipc_mem_handle_t hIPCMem); ur_result_t urIPCOpenMemHandleExp(ur_context_handle_t hContext, - ur_exp_ipc_mem_handle_t hIPCMem, - void **ppMem); + ur_device_handle_t hDevice, + void *ipcMemHandleData, + size_t ipcMemHandleDataSize, void **ppMem); ur_result_t urIPCCloseMemHandleExp(ur_context_handle_t hContext, void *pMem); ur_result_t urIPCGetMemHandleDataExp(ur_context_handle_t hContext, ur_exp_ipc_mem_handle_t hIPCMem, - const void **ppIPCHandleData, + void **ppIPCHandleData, size_t *pIPCMemHandleDataSizeRet); -ur_result_t urIPCCreateMemHandleFromDataExp(ur_context_handle_t hContext, - ur_device_handle_t hDevice, - const void *ipcMemHandleData, - size_t ipcMemHandleDataSize, - ur_exp_ipc_mem_handle_t *phIPCMem); -ur_result_t urIPCDestroyMemHandleExp(ur_context_handle_t hContext, - ur_exp_ipc_mem_handle_t hIPCMem); ur_result_t urMemoryExportAllocExportableMemoryExp( ur_context_handle_t hContext, ur_device_handle_t hDevice, size_t alignment, size_t size, ur_exp_external_mem_type_t handleTypeToExport, void **ppMem); diff --git a/unified-runtime/source/adapters/level_zero/v2/memory.cpp b/unified-runtime/source/adapters/level_zero/v2/memory.cpp index 1375723f75be9..1794cfe0cffc3 100644 --- a/unified-runtime/source/adapters/level_zero/v2/memory.cpp +++ b/unified-runtime/source/adapters/level_zero/v2/memory.cpp @@ -778,10 +778,10 @@ ur_result_t urMemImageGetInfo(ur_mem_handle_t /*hMemory*/, ur_result_t urIPCGetMemHandleExp(ur_context_handle_t, void *pMem, ur_exp_ipc_mem_handle_t *phIPCMem) { auto resHandle = std::make_unique(); - resHandle->CreatedFromData = false; - auto umfRet = umfPoolByPtr(pMem, &resHandle->UMFPool); - if (umfRet != UMF_RESULT_SUCCESS || !resHandle->UMFPool) + umf_memory_pool_handle_t umfPool; + auto umfRet = umfPoolByPtr(pMem, &umfPool); + if (umfRet != UMF_RESULT_SUCCESS || !umfPool) return UR_RESULT_ERROR_UNKNOWN; umfRet = umfGetIPCHandle(pMem, &resHandle->UMFHandle, &resHandle->HandleSize); @@ -802,15 +802,33 @@ ur_result_t urIPCPutMemHandleExp(ur_context_handle_t, return UR_RESULT_SUCCESS; } -ur_result_t urIPCOpenMemHandleExp(ur_context_handle_t, - ur_exp_ipc_mem_handle_t hIPCMem, - void **ppMem) { +ur_result_t urIPCOpenMemHandleExp(ur_context_handle_t hContext, + ur_device_handle_t hDevice, + void *pIPCMemHandleData, + size_t ipcMemHandleDataSize, void **ppMem) { + auto *pool = hContext->getDefaultUSMPool()->getPool( + usm::pool_descriptor{hContext->getDefaultUSMPool(), hContext, hDevice, + UR_USM_TYPE_DEVICE, false}); + if (!pool) + return UR_RESULT_ERROR_INVALID_CONTEXT; + umf_memory_pool_handle_t umfPool = pool->umfPool.get(); + + size_t umfHandleSize = 0; + auto umfRet = umfPoolGetIPCHandleSize(umfPool, &umfHandleSize); + if (umfRet != UMF_RESULT_SUCCESS || umfHandleSize == 0) + return UR_RESULT_ERROR_UNKNOWN; + + if (umfHandleSize != ipcMemHandleDataSize) + return UR_RESULT_ERROR_INVALID_VALUE; + umf_ipc_handler_handle_t umfIPCHandler; - auto umfRet = umfPoolGetIPCHandler(hIPCMem->UMFPool, &umfIPCHandler); + umfRet = umfPoolGetIPCHandler(umfPool, &umfIPCHandler); if (umfRet != UMF_RESULT_SUCCESS || !umfIPCHandler) return UR_RESULT_ERROR_UNKNOWN; - umfRet = umfOpenIPCHandle(umfIPCHandler, hIPCMem->UMFHandle, ppMem); + umfRet = umfOpenIPCHandle( + umfIPCHandler, reinterpret_cast(pIPCMemHandleData), + ppMem); return umfRet == UMF_RESULT_SUCCESS ? UR_RESULT_SUCCESS : UR_RESULT_ERROR_UNKNOWN; } @@ -823,7 +841,7 @@ ur_result_t urIPCCloseMemHandleExp(ur_context_handle_t, void *pMem) { ur_result_t urIPCGetMemHandleDataExp(ur_context_handle_t, ur_exp_ipc_mem_handle_t hIPCMem, - const void **ppIPCHandleData, + void **ppIPCHandleData, size_t *pIPCMemHandleDataSizeRet) { if (ppIPCHandleData) *ppIPCHandleData = hIPCMem->UMFHandle; @@ -832,43 +850,4 @@ ur_result_t urIPCGetMemHandleDataExp(ur_context_handle_t, return UR_RESULT_SUCCESS; } -ur_result_t urIPCCreateMemHandleFromDataExp(ur_context_handle_t hContext, - ur_device_handle_t hDevice, - const void *pIPCMemHandleData, - size_t ipcMemHandleDataSize, - ur_exp_ipc_mem_handle_t *phIPCMem) { - auto *pool = hContext->getDefaultUSMPool()->getPool( - usm::pool_descriptor{hContext->getDefaultUSMPool(), hContext, hDevice, - UR_USM_TYPE_DEVICE, false}); - if (!pool) - return UR_RESULT_ERROR_INVALID_CONTEXT; - umf_memory_pool_handle_t umfPool = pool->umfPool.get(); - - size_t umfHandleSize = 0; - auto umfRet = umfPoolGetIPCHandleSize(umfPool, &umfHandleSize); - if (umfRet != UMF_RESULT_SUCCESS || umfHandleSize == 0) - return UR_RESULT_ERROR_UNKNOWN; - - if (umfHandleSize != ipcMemHandleDataSize) - return UR_RESULT_ERROR_INVALID_VALUE; - - auto resHandle = std::make_unique(); - resHandle->UMFPool = umfPool; - resHandle->UMFHandle = - reinterpret_cast(std::malloc(umfHandleSize)); - std::memcpy(resHandle->UMFHandle, pIPCMemHandleData, umfHandleSize); - resHandle->HandleSize = umfHandleSize; - resHandle->CreatedFromData = true; - *phIPCMem = resHandle.release(); - return UR_RESULT_SUCCESS; -} - -ur_result_t urIPCDestroyMemHandleExp(ur_context_handle_t, - ur_exp_ipc_mem_handle_t hIPCMem) { - if (!hIPCMem->CreatedFromData) - return UR_RESULT_ERROR_INVALID_VALUE; - std::free(hIPCMem); - return UR_RESULT_SUCCESS; -} - } // namespace ur::level_zero diff --git a/unified-runtime/source/adapters/level_zero/v2/memory.hpp b/unified-runtime/source/adapters/level_zero/v2/memory.hpp index 9abfcd569fed6..c61a171c511c4 100644 --- a/unified-runtime/source/adapters/level_zero/v2/memory.hpp +++ b/unified-runtime/source/adapters/level_zero/v2/memory.hpp @@ -295,8 +295,6 @@ struct ur_mem_handle_t_ : ur::handle_base { }; struct ur_exp_ipc_mem_handle_t_ { - umf_memory_pool_handle_t UMFPool; umf_ipc_handle_t UMFHandle = nullptr; size_t HandleSize = 0; - bool CreatedFromData = false; }; diff --git a/unified-runtime/source/adapters/mock/ur_mockddi.cpp b/unified-runtime/source/adapters/mock/ur_mockddi.cpp index 0cfc348b92866..80fd8024595e0 100644 --- a/unified-runtime/source/adapters/mock/ur_mockddi.cpp +++ b/unified-runtime/source/adapters/mock/ur_mockddi.cpp @@ -11399,13 +11399,19 @@ __urdlllocal ur_result_t UR_APICALL urIPCPutMemHandleExp( __urdlllocal ur_result_t UR_APICALL urIPCOpenMemHandleExp( /// [in] handle of the context object ur_context_handle_t hContext, - /// [in] pointer to the resulting IPC memory handle - ur_exp_ipc_mem_handle_t hIPCMem, + /// [in] handle of the device object the corresponding USM device memory + /// was allocated on + ur_device_handle_t hDevice, + /// [in] the IPC memory handle data + void *ipcMemHandleData, + /// [in] size of the IPC memory handle data + size_t ipcMemHandleDataSize, /// [out] pointer to a pointer to device USM memory void **ppMem) try { ur_result_t result = UR_RESULT_SUCCESS; - ur_ipc_open_mem_handle_exp_params_t params = {&hContext, &hIPCMem, &ppMem}; + ur_ipc_open_mem_handle_exp_params_t params = { + &hContext, &hDevice, &ipcMemHandleData, &ipcMemHandleDataSize, &ppMem}; auto beforeCallback = reinterpret_cast( mock::getCallbacks().get_before_callback("urIPCOpenMemHandleExp")); @@ -11492,7 +11498,7 @@ __urdlllocal ur_result_t UR_APICALL urIPCGetMemHandleDataExp( /// [in] the IPC memory handle ur_exp_ipc_mem_handle_t hIPCMem, /// [out][optional] a pointer to the IPC memory handle data - const void **ppIPCHandleData, + void **ppIPCHandleData, /// [out][optional] size of the resulting IPC memory handle data size_t *pIPCMemHandleDataSizeRet) try { ur_result_t result = UR_RESULT_SUCCESS; @@ -11533,105 +11539,6 @@ __urdlllocal ur_result_t UR_APICALL urIPCGetMemHandleDataExp( return exceptionToResult(std::current_exception()); } -/////////////////////////////////////////////////////////////////////////////// -/// @brief Intercept function for urIPCCreateMemHandleFromDataExp -__urdlllocal ur_result_t UR_APICALL urIPCCreateMemHandleFromDataExp( - /// [in] handle of the context object - ur_context_handle_t hContext, - /// [in] handle of the device object the corresponding USM device memory - /// was allocated on - ur_device_handle_t hDevice, - /// [in] the IPC memory handle data - const void *ipcMemHandleData, - /// [in] size of the IPC memory handle data - size_t ipcMemHandleDataSize, - /// [out] the IPC memory handle - ur_exp_ipc_mem_handle_t *phIPCMem) try { - ur_result_t result = UR_RESULT_SUCCESS; - - ur_ipc_create_mem_handle_from_data_exp_params_t params = { - &hContext, &hDevice, &ipcMemHandleData, &ipcMemHandleDataSize, &phIPCMem}; - - auto beforeCallback = reinterpret_cast( - mock::getCallbacks().get_before_callback( - "urIPCCreateMemHandleFromDataExp")); - if (beforeCallback) { - result = beforeCallback(¶ms); - if (result != UR_RESULT_SUCCESS) { - return result; - } - } - - auto replaceCallback = reinterpret_cast( - mock::getCallbacks().get_replace_callback( - "urIPCCreateMemHandleFromDataExp")); - if (replaceCallback) { - result = replaceCallback(¶ms); - } else { - - result = UR_RESULT_SUCCESS; - } - - if (result != UR_RESULT_SUCCESS) { - return result; - } - - auto afterCallback = reinterpret_cast( - mock::getCallbacks().get_after_callback( - "urIPCCreateMemHandleFromDataExp")); - if (afterCallback) { - return afterCallback(¶ms); - } - - return result; -} catch (...) { - return exceptionToResult(std::current_exception()); -} - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Intercept function for urIPCDestroyMemHandleExp -__urdlllocal ur_result_t UR_APICALL urIPCDestroyMemHandleExp( - /// [in] handle of the context object - ur_context_handle_t hContext, - /// [in] the IPC memory handle - ur_exp_ipc_mem_handle_t hIPCMem) try { - ur_result_t result = UR_RESULT_SUCCESS; - - ur_ipc_destroy_mem_handle_exp_params_t params = {&hContext, &hIPCMem}; - - auto beforeCallback = reinterpret_cast( - mock::getCallbacks().get_before_callback("urIPCDestroyMemHandleExp")); - if (beforeCallback) { - result = beforeCallback(¶ms); - if (result != UR_RESULT_SUCCESS) { - return result; - } - } - - auto replaceCallback = reinterpret_cast( - mock::getCallbacks().get_replace_callback("urIPCDestroyMemHandleExp")); - if (replaceCallback) { - result = replaceCallback(¶ms); - } else { - - result = UR_RESULT_SUCCESS; - } - - if (result != UR_RESULT_SUCCESS) { - return result; - } - - auto afterCallback = reinterpret_cast( - mock::getCallbacks().get_after_callback("urIPCDestroyMemHandleExp")); - if (afterCallback) { - return afterCallback(¶ms); - } - - return result; -} catch (...) { - return exceptionToResult(std::current_exception()); -} - /////////////////////////////////////////////////////////////////////////////// /// @brief Intercept function for urMemoryExportAllocExportableMemoryExp __urdlllocal ur_result_t UR_APICALL urMemoryExportAllocExportableMemoryExp( @@ -12840,11 +12747,6 @@ UR_DLLEXPORT ur_result_t UR_APICALL urGetIPCExpProcAddrTable( pDdiTable->pfnGetMemHandleDataExp = driver::urIPCGetMemHandleDataExp; - pDdiTable->pfnCreateMemHandleFromDataExp = - driver::urIPCCreateMemHandleFromDataExp; - - pDdiTable->pfnDestroyMemHandleExp = driver::urIPCDestroyMemHandleExp; - return result; } catch (...) { return exceptionToResult(std::current_exception()); diff --git a/unified-runtime/source/adapters/native_cpu/memory.cpp b/unified-runtime/source/adapters/native_cpu/memory.cpp index a026205eea551..f856b19843c78 100644 --- a/unified-runtime/source/adapters/native_cpu/memory.cpp +++ b/unified-runtime/source/adapters/native_cpu/memory.cpp @@ -149,8 +149,10 @@ urIPCPutMemHandleExp(ur_context_handle_t, ur_exp_ipc_mem_handle_t) { return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; } -UR_APIEXPORT ur_result_t UR_APICALL -urIPCOpenMemHandleExp(ur_context_handle_t, ur_exp_ipc_mem_handle_t, void **) { +UR_APIEXPORT ur_result_t UR_APICALL urIPCOpenMemHandleExp(ur_context_handle_t, + ur_device_handle_t, + void *, size_t, + void **) { return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; } @@ -160,17 +162,6 @@ UR_APIEXPORT ur_result_t UR_APICALL urIPCCloseMemHandleExp(ur_context_handle_t, } UR_APIEXPORT ur_result_t UR_APICALL urIPCGetMemHandleDataExp( - ur_context_handle_t, ur_exp_ipc_mem_handle_t, const void **, size_t *) { - return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; -} - -UR_APIEXPORT ur_result_t UR_APICALL urIPCCreateMemHandleFromDataExp( - ur_context_handle_t, ur_device_handle_t, const void *, size_t, - ur_exp_ipc_mem_handle_t *) { - return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; -} - -UR_APIEXPORT ur_result_t UR_APICALL -urIPCDestroyMemHandleExp(ur_context_handle_t, ur_exp_ipc_mem_handle_t) { + ur_context_handle_t, ur_exp_ipc_mem_handle_t, void **, size_t *) { return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; } diff --git a/unified-runtime/source/adapters/native_cpu/ur_interface_loader.cpp b/unified-runtime/source/adapters/native_cpu/ur_interface_loader.cpp index c85880f99e08d..f0c36bb6dadc2 100644 --- a/unified-runtime/source/adapters/native_cpu/ur_interface_loader.cpp +++ b/unified-runtime/source/adapters/native_cpu/ur_interface_loader.cpp @@ -447,8 +447,6 @@ UR_DLLEXPORT ur_result_t UR_APICALL urGetIPCExpProcAddrTable( pDdiTable->pfnOpenMemHandleExp = urIPCOpenMemHandleExp; pDdiTable->pfnCloseMemHandleExp = urIPCCloseMemHandleExp; pDdiTable->pfnGetMemHandleDataExp = urIPCGetMemHandleDataExp; - pDdiTable->pfnCreateMemHandleFromDataExp = urIPCCreateMemHandleFromDataExp; - pDdiTable->pfnDestroyMemHandleExp = urIPCDestroyMemHandleExp; return UR_RESULT_SUCCESS; } diff --git a/unified-runtime/source/adapters/offload/memory.cpp b/unified-runtime/source/adapters/offload/memory.cpp index 827300cba98b6..fdc9a1a1d4a65 100644 --- a/unified-runtime/source/adapters/offload/memory.cpp +++ b/unified-runtime/source/adapters/offload/memory.cpp @@ -153,8 +153,10 @@ urIPCPutMemHandleExp(ur_context_handle_t, ur_exp_ipc_mem_handle_t) { return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; } -UR_APIEXPORT ur_result_t UR_APICALL -urIPCOpenMemHandleExp(ur_context_handle_t, ur_exp_ipc_mem_handle_t, void **) { +UR_APIEXPORT ur_result_t UR_APICALL urIPCOpenMemHandleExp(ur_context_handle_t, + ur_device_handle_t, + void *, size_t, + void **) { return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; } @@ -164,17 +166,6 @@ UR_APIEXPORT ur_result_t UR_APICALL urIPCCloseMemHandleExp(ur_context_handle_t, } UR_APIEXPORT ur_result_t UR_APICALL urIPCGetMemHandleDataExp( - ur_context_handle_t, ur_exp_ipc_mem_handle_t, const void **, size_t *) { - return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; -} - -UR_APIEXPORT ur_result_t UR_APICALL urIPCCreateMemHandleFromDataExp( - ur_context_handle_t, ur_device_handle_t, const void *, size_t, - ur_exp_ipc_mem_handle_t *) { - return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; -} - -UR_APIEXPORT ur_result_t UR_APICALL -urIPCDestroyMemHandleExp(ur_context_handle_t, ur_exp_ipc_mem_handle_t) { + ur_context_handle_t, ur_exp_ipc_mem_handle_t, void **, size_t *) { return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; } diff --git a/unified-runtime/source/adapters/offload/ur_interface_loader.cpp b/unified-runtime/source/adapters/offload/ur_interface_loader.cpp index 1eac719c8bf8c..da8e16f4f6a6a 100644 --- a/unified-runtime/source/adapters/offload/ur_interface_loader.cpp +++ b/unified-runtime/source/adapters/offload/ur_interface_loader.cpp @@ -400,8 +400,6 @@ UR_DLLEXPORT ur_result_t UR_APICALL urGetIPCExpProcAddrTable( pDdiTable->pfnOpenMemHandleExp = urIPCOpenMemHandleExp; pDdiTable->pfnCloseMemHandleExp = urIPCCloseMemHandleExp; pDdiTable->pfnGetMemHandleDataExp = urIPCGetMemHandleDataExp; - pDdiTable->pfnCreateMemHandleFromDataExp = urIPCCreateMemHandleFromDataExp; - pDdiTable->pfnDestroyMemHandleExp = urIPCDestroyMemHandleExp; return UR_RESULT_SUCCESS; } diff --git a/unified-runtime/source/adapters/opencl/memory.cpp b/unified-runtime/source/adapters/opencl/memory.cpp index da056f83b1396..77d9c4a3316dd 100644 --- a/unified-runtime/source/adapters/opencl/memory.cpp +++ b/unified-runtime/source/adapters/opencl/memory.cpp @@ -590,8 +590,10 @@ urIPCPutMemHandleExp(ur_context_handle_t, ur_exp_ipc_mem_handle_t) { return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; } -UR_APIEXPORT ur_result_t UR_APICALL -urIPCOpenMemHandleExp(ur_context_handle_t, ur_exp_ipc_mem_handle_t, void **) { +UR_APIEXPORT ur_result_t UR_APICALL urIPCOpenMemHandleExp(ur_context_handle_t, + ur_device_handle_t, + void *, size_t, + void **) { return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; } @@ -601,17 +603,6 @@ UR_APIEXPORT ur_result_t UR_APICALL urIPCCloseMemHandleExp(ur_context_handle_t, } UR_APIEXPORT ur_result_t UR_APICALL urIPCGetMemHandleDataExp( - ur_context_handle_t, ur_exp_ipc_mem_handle_t, const void **, size_t *) { - return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; -} - -UR_APIEXPORT ur_result_t UR_APICALL urIPCCreateMemHandleFromDataExp( - ur_context_handle_t, ur_device_handle_t, const void *, size_t, - ur_exp_ipc_mem_handle_t *) { - return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; -} - -UR_APIEXPORT ur_result_t UR_APICALL -urIPCDestroyMemHandleExp(ur_context_handle_t, ur_exp_ipc_mem_handle_t) { + ur_context_handle_t, ur_exp_ipc_mem_handle_t, void **, size_t *) { return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; } diff --git a/unified-runtime/source/adapters/opencl/ur_interface_loader.cpp b/unified-runtime/source/adapters/opencl/ur_interface_loader.cpp index 405114b021c31..18585431b7fad 100644 --- a/unified-runtime/source/adapters/opencl/ur_interface_loader.cpp +++ b/unified-runtime/source/adapters/opencl/ur_interface_loader.cpp @@ -450,8 +450,6 @@ UR_DLLEXPORT ur_result_t UR_APICALL urGetIPCExpProcAddrTable( pDdiTable->pfnOpenMemHandleExp = urIPCOpenMemHandleExp; pDdiTable->pfnCloseMemHandleExp = urIPCCloseMemHandleExp; pDdiTable->pfnGetMemHandleDataExp = urIPCGetMemHandleDataExp; - pDdiTable->pfnCreateMemHandleFromDataExp = urIPCCreateMemHandleFromDataExp; - pDdiTable->pfnDestroyMemHandleExp = urIPCDestroyMemHandleExp; return UR_RESULT_SUCCESS; } diff --git a/unified-runtime/source/loader/layers/tracing/ur_trcddi.cpp b/unified-runtime/source/loader/layers/tracing/ur_trcddi.cpp index f51c0be4e95dc..6e6929ddfca4e 100644 --- a/unified-runtime/source/loader/layers/tracing/ur_trcddi.cpp +++ b/unified-runtime/source/loader/layers/tracing/ur_trcddi.cpp @@ -9651,8 +9651,13 @@ __urdlllocal ur_result_t UR_APICALL urIPCPutMemHandleExp( __urdlllocal ur_result_t UR_APICALL urIPCOpenMemHandleExp( /// [in] handle of the context object ur_context_handle_t hContext, - /// [in] pointer to the resulting IPC memory handle - ur_exp_ipc_mem_handle_t hIPCMem, + /// [in] handle of the device object the corresponding USM device memory + /// was allocated on + ur_device_handle_t hDevice, + /// [in] the IPC memory handle data + void *ipcMemHandleData, + /// [in] size of the IPC memory handle data + size_t ipcMemHandleDataSize, /// [out] pointer to a pointer to device USM memory void **ppMem) { auto pfnOpenMemHandleExp = @@ -9661,14 +9666,16 @@ __urdlllocal ur_result_t UR_APICALL urIPCOpenMemHandleExp( if (nullptr == pfnOpenMemHandleExp) return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; - ur_ipc_open_mem_handle_exp_params_t params = {&hContext, &hIPCMem, &ppMem}; + ur_ipc_open_mem_handle_exp_params_t params = { + &hContext, &hDevice, &ipcMemHandleData, &ipcMemHandleDataSize, &ppMem}; uint64_t instance = getContext()->notify_begin( UR_FUNCTION_IPC_OPEN_MEM_HANDLE_EXP, "urIPCOpenMemHandleExp", ¶ms); auto &logger = getContext()->logger; UR_LOG_L(logger, INFO, " ---> urIPCOpenMemHandleExp\n"); - ur_result_t result = pfnOpenMemHandleExp(hContext, hIPCMem, ppMem); + ur_result_t result = pfnOpenMemHandleExp(hContext, hDevice, ipcMemHandleData, + ipcMemHandleDataSize, ppMem); getContext()->notify_end(UR_FUNCTION_IPC_OPEN_MEM_HANDLE_EXP, "urIPCOpenMemHandleExp", ¶ms, &result, instance); @@ -9729,7 +9736,7 @@ __urdlllocal ur_result_t UR_APICALL urIPCGetMemHandleDataExp( /// [in] the IPC memory handle ur_exp_ipc_mem_handle_t hIPCMem, /// [out][optional] a pointer to the IPC memory handle data - const void **ppIPCHandleData, + void **ppIPCHandleData, /// [out][optional] size of the resulting IPC memory handle data size_t *pIPCMemHandleDataSizeRet) { auto pfnGetMemHandleDataExp = @@ -9765,92 +9772,6 @@ __urdlllocal ur_result_t UR_APICALL urIPCGetMemHandleDataExp( return result; } -/////////////////////////////////////////////////////////////////////////////// -/// @brief Intercept function for urIPCCreateMemHandleFromDataExp -__urdlllocal ur_result_t UR_APICALL urIPCCreateMemHandleFromDataExp( - /// [in] handle of the context object - ur_context_handle_t hContext, - /// [in] handle of the device object the corresponding USM device memory - /// was allocated on - ur_device_handle_t hDevice, - /// [in] the IPC memory handle data - const void *ipcMemHandleData, - /// [in] size of the IPC memory handle data - size_t ipcMemHandleDataSize, - /// [out] the IPC memory handle - ur_exp_ipc_mem_handle_t *phIPCMem) { - auto pfnCreateMemHandleFromDataExp = - getContext()->urDdiTable.IPCExp.pfnCreateMemHandleFromDataExp; - - if (nullptr == pfnCreateMemHandleFromDataExp) - return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; - - ur_ipc_create_mem_handle_from_data_exp_params_t params = { - &hContext, &hDevice, &ipcMemHandleData, &ipcMemHandleDataSize, &phIPCMem}; - uint64_t instance = getContext()->notify_begin( - UR_FUNCTION_IPC_CREATE_MEM_HANDLE_FROM_DATA_EXP, - "urIPCCreateMemHandleFromDataExp", ¶ms); - - auto &logger = getContext()->logger; - UR_LOG_L(logger, INFO, " ---> urIPCCreateMemHandleFromDataExp\n"); - - ur_result_t result = pfnCreateMemHandleFromDataExp( - hContext, hDevice, ipcMemHandleData, ipcMemHandleDataSize, phIPCMem); - - getContext()->notify_end(UR_FUNCTION_IPC_CREATE_MEM_HANDLE_FROM_DATA_EXP, - "urIPCCreateMemHandleFromDataExp", ¶ms, &result, - instance); - - if (logger.getLevel() <= UR_LOGGER_LEVEL_INFO) { - std::ostringstream args_str; - ur::extras::printFunctionParams( - args_str, UR_FUNCTION_IPC_CREATE_MEM_HANDLE_FROM_DATA_EXP, ¶ms); - UR_LOG_L(logger, INFO, - " <--- urIPCCreateMemHandleFromDataExp({}) -> {};\n", - args_str.str(), result); - } - - return result; -} - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Intercept function for urIPCDestroyMemHandleExp -__urdlllocal ur_result_t UR_APICALL urIPCDestroyMemHandleExp( - /// [in] handle of the context object - ur_context_handle_t hContext, - /// [in] the IPC memory handle - ur_exp_ipc_mem_handle_t hIPCMem) { - auto pfnDestroyMemHandleExp = - getContext()->urDdiTable.IPCExp.pfnDestroyMemHandleExp; - - if (nullptr == pfnDestroyMemHandleExp) - return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; - - ur_ipc_destroy_mem_handle_exp_params_t params = {&hContext, &hIPCMem}; - uint64_t instance = - getContext()->notify_begin(UR_FUNCTION_IPC_DESTROY_MEM_HANDLE_EXP, - "urIPCDestroyMemHandleExp", ¶ms); - - auto &logger = getContext()->logger; - UR_LOG_L(logger, INFO, " ---> urIPCDestroyMemHandleExp\n"); - - ur_result_t result = pfnDestroyMemHandleExp(hContext, hIPCMem); - - getContext()->notify_end(UR_FUNCTION_IPC_DESTROY_MEM_HANDLE_EXP, - "urIPCDestroyMemHandleExp", ¶ms, &result, - instance); - - if (logger.getLevel() <= UR_LOGGER_LEVEL_INFO) { - std::ostringstream args_str; - ur::extras::printFunctionParams( - args_str, UR_FUNCTION_IPC_DESTROY_MEM_HANDLE_EXP, ¶ms); - UR_LOG_L(logger, INFO, " <--- urIPCDestroyMemHandleExp({}) -> {};\n", - args_str.str(), result); - } - - return result; -} - /////////////////////////////////////////////////////////////////////////////// /// @brief Intercept function for urMemoryExportAllocExportableMemoryExp __urdlllocal ur_result_t UR_APICALL urMemoryExportAllocExportableMemoryExp( @@ -11101,15 +11022,6 @@ __urdlllocal ur_result_t UR_APICALL urGetIPCExpProcAddrTable( pDdiTable->pfnGetMemHandleDataExp = ur_tracing_layer::urIPCGetMemHandleDataExp; - dditable.pfnCreateMemHandleFromDataExp = - pDdiTable->pfnCreateMemHandleFromDataExp; - pDdiTable->pfnCreateMemHandleFromDataExp = - ur_tracing_layer::urIPCCreateMemHandleFromDataExp; - - dditable.pfnDestroyMemHandleExp = pDdiTable->pfnDestroyMemHandleExp; - pDdiTable->pfnDestroyMemHandleExp = - ur_tracing_layer::urIPCDestroyMemHandleExp; - return result; } /////////////////////////////////////////////////////////////////////////////// diff --git a/unified-runtime/source/loader/layers/validation/ur_valddi.cpp b/unified-runtime/source/loader/layers/validation/ur_valddi.cpp index 88b0bb4114363..1d5e7c9db19a8 100644 --- a/unified-runtime/source/loader/layers/validation/ur_valddi.cpp +++ b/unified-runtime/source/loader/layers/validation/ur_valddi.cpp @@ -10403,8 +10403,13 @@ __urdlllocal ur_result_t UR_APICALL urIPCPutMemHandleExp( __urdlllocal ur_result_t UR_APICALL urIPCOpenMemHandleExp( /// [in] handle of the context object ur_context_handle_t hContext, - /// [in] pointer to the resulting IPC memory handle - ur_exp_ipc_mem_handle_t hIPCMem, + /// [in] handle of the device object the corresponding USM device memory + /// was allocated on + ur_device_handle_t hDevice, + /// [in] the IPC memory handle data + void *ipcMemHandleData, + /// [in] size of the IPC memory handle data + size_t ipcMemHandleDataSize, /// [out] pointer to a pointer to device USM memory void **ppMem) { auto pfnOpenMemHandleExp = @@ -10417,6 +10422,12 @@ __urdlllocal ur_result_t UR_APICALL urIPCOpenMemHandleExp( if (getContext()->enableParameterValidation) { if (NULL == hContext) return UR_RESULT_ERROR_INVALID_NULL_HANDLE; + + if (NULL == hDevice) + return UR_RESULT_ERROR_INVALID_NULL_HANDLE; + + if (NULL == ipcMemHandleData) + return UR_RESULT_ERROR_INVALID_NULL_POINTER; } if (getContext()->enableLifetimeValidation && @@ -10424,7 +10435,13 @@ __urdlllocal ur_result_t UR_APICALL urIPCOpenMemHandleExp( URLOG_CTX_INVALID_REFERENCE(hContext); } - ur_result_t result = pfnOpenMemHandleExp(hContext, hIPCMem, ppMem); + if (getContext()->enableLifetimeValidation && + !getContext()->refCountContext->isReferenceValid(hDevice)) { + URLOG_CTX_INVALID_REFERENCE(hDevice); + } + + ur_result_t result = pfnOpenMemHandleExp(hContext, hDevice, ipcMemHandleData, + ipcMemHandleDataSize, ppMem); return result; } @@ -10466,7 +10483,7 @@ __urdlllocal ur_result_t UR_APICALL urIPCGetMemHandleDataExp( /// [in] the IPC memory handle ur_exp_ipc_mem_handle_t hIPCMem, /// [out][optional] a pointer to the IPC memory handle data - const void **ppIPCHandleData, + void **ppIPCHandleData, /// [out][optional] size of the resulting IPC memory handle data size_t *pIPCMemHandleDataSizeRet) { auto pfnGetMemHandleDataExp = @@ -10492,83 +10509,6 @@ __urdlllocal ur_result_t UR_APICALL urIPCGetMemHandleDataExp( return result; } -/////////////////////////////////////////////////////////////////////////////// -/// @brief Intercept function for urIPCCreateMemHandleFromDataExp -__urdlllocal ur_result_t UR_APICALL urIPCCreateMemHandleFromDataExp( - /// [in] handle of the context object - ur_context_handle_t hContext, - /// [in] handle of the device object the corresponding USM device memory - /// was allocated on - ur_device_handle_t hDevice, - /// [in] the IPC memory handle data - const void *ipcMemHandleData, - /// [in] size of the IPC memory handle data - size_t ipcMemHandleDataSize, - /// [out] the IPC memory handle - ur_exp_ipc_mem_handle_t *phIPCMem) { - auto pfnCreateMemHandleFromDataExp = - getContext()->urDdiTable.IPCExp.pfnCreateMemHandleFromDataExp; - - if (nullptr == pfnCreateMemHandleFromDataExp) { - return UR_RESULT_ERROR_UNINITIALIZED; - } - - if (getContext()->enableParameterValidation) { - if (NULL == phIPCMem) - return UR_RESULT_ERROR_INVALID_NULL_POINTER; - - if (NULL == hContext) - return UR_RESULT_ERROR_INVALID_NULL_HANDLE; - - if (NULL == hDevice) - return UR_RESULT_ERROR_INVALID_NULL_HANDLE; - } - - if (getContext()->enableLifetimeValidation && - !getContext()->refCountContext->isReferenceValid(hContext)) { - URLOG_CTX_INVALID_REFERENCE(hContext); - } - - if (getContext()->enableLifetimeValidation && - !getContext()->refCountContext->isReferenceValid(hDevice)) { - URLOG_CTX_INVALID_REFERENCE(hDevice); - } - - ur_result_t result = pfnCreateMemHandleFromDataExp( - hContext, hDevice, ipcMemHandleData, ipcMemHandleDataSize, phIPCMem); - - return result; -} - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Intercept function for urIPCDestroyMemHandleExp -__urdlllocal ur_result_t UR_APICALL urIPCDestroyMemHandleExp( - /// [in] handle of the context object - ur_context_handle_t hContext, - /// [in] the IPC memory handle - ur_exp_ipc_mem_handle_t hIPCMem) { - auto pfnDestroyMemHandleExp = - getContext()->urDdiTable.IPCExp.pfnDestroyMemHandleExp; - - if (nullptr == pfnDestroyMemHandleExp) { - return UR_RESULT_ERROR_UNINITIALIZED; - } - - if (getContext()->enableParameterValidation) { - if (NULL == hContext) - return UR_RESULT_ERROR_INVALID_NULL_HANDLE; - } - - if (getContext()->enableLifetimeValidation && - !getContext()->refCountContext->isReferenceValid(hContext)) { - URLOG_CTX_INVALID_REFERENCE(hContext); - } - - ur_result_t result = pfnDestroyMemHandleExp(hContext, hIPCMem); - - return result; -} - /////////////////////////////////////////////////////////////////////////////// /// @brief Intercept function for urMemoryExportAllocExportableMemoryExp __urdlllocal ur_result_t UR_APICALL urMemoryExportAllocExportableMemoryExp( @@ -11859,15 +11799,6 @@ UR_DLLEXPORT ur_result_t UR_APICALL urGetIPCExpProcAddrTable( pDdiTable->pfnGetMemHandleDataExp = ur_validation_layer::urIPCGetMemHandleDataExp; - dditable.pfnCreateMemHandleFromDataExp = - pDdiTable->pfnCreateMemHandleFromDataExp; - pDdiTable->pfnCreateMemHandleFromDataExp = - ur_validation_layer::urIPCCreateMemHandleFromDataExp; - - dditable.pfnDestroyMemHandleExp = pDdiTable->pfnDestroyMemHandleExp; - pDdiTable->pfnDestroyMemHandleExp = - ur_validation_layer::urIPCDestroyMemHandleExp; - return result; } diff --git a/unified-runtime/source/loader/loader.def.in b/unified-runtime/source/loader/loader.def.in index 81b665399948c..a09ecdf084ddd 100644 --- a/unified-runtime/source/loader/loader.def.in +++ b/unified-runtime/source/loader/loader.def.in @@ -133,8 +133,6 @@ EXPORTS urGetUsmP2PExpProcAddrTable urGetVirtualMemProcAddrTable urIPCCloseMemHandleExp - urIPCCreateMemHandleFromDataExp - urIPCDestroyMemHandleExp urIPCGetMemHandleDataExp urIPCGetMemHandleExp urIPCOpenMemHandleExp @@ -370,8 +368,6 @@ EXPORTS urPrintImageFormat urPrintImageInfo urPrintIpcCloseMemHandleExpParams - urPrintIpcCreateMemHandleFromDataExpParams - urPrintIpcDestroyMemHandleExpParams urPrintIpcGetMemHandleDataExpParams urPrintIpcGetMemHandleExpParams urPrintIpcOpenMemHandleExpParams diff --git a/unified-runtime/source/loader/loader.map.in b/unified-runtime/source/loader/loader.map.in index c6e5cd5006526..08c16c8e43c42 100644 --- a/unified-runtime/source/loader/loader.map.in +++ b/unified-runtime/source/loader/loader.map.in @@ -133,8 +133,6 @@ urGetUsmP2PExpProcAddrTable; urGetVirtualMemProcAddrTable; urIPCCloseMemHandleExp; - urIPCCreateMemHandleFromDataExp; - urIPCDestroyMemHandleExp; urIPCGetMemHandleDataExp; urIPCGetMemHandleExp; urIPCOpenMemHandleExp; @@ -370,8 +368,6 @@ urPrintImageFormat; urPrintImageInfo; urPrintIpcCloseMemHandleExpParams; - urPrintIpcCreateMemHandleFromDataExpParams; - urPrintIpcDestroyMemHandleExpParams; urPrintIpcGetMemHandleDataExpParams; urPrintIpcGetMemHandleExpParams; urPrintIpcOpenMemHandleExpParams; diff --git a/unified-runtime/source/loader/ur_ldrddi.cpp b/unified-runtime/source/loader/ur_ldrddi.cpp index d2792f8b3de4e..26b7b74e0f528 100644 --- a/unified-runtime/source/loader/ur_ldrddi.cpp +++ b/unified-runtime/source/loader/ur_ldrddi.cpp @@ -5495,8 +5495,13 @@ __urdlllocal ur_result_t UR_APICALL urIPCPutMemHandleExp( __urdlllocal ur_result_t UR_APICALL urIPCOpenMemHandleExp( /// [in] handle of the context object ur_context_handle_t hContext, - /// [in] pointer to the resulting IPC memory handle - ur_exp_ipc_mem_handle_t hIPCMem, + /// [in] handle of the device object the corresponding USM device memory + /// was allocated on + ur_device_handle_t hDevice, + /// [in] the IPC memory handle data + void *ipcMemHandleData, + /// [in] size of the IPC memory handle data + size_t ipcMemHandleDataSize, /// [out] pointer to a pointer to device USM memory void **ppMem) { @@ -5507,7 +5512,8 @@ __urdlllocal ur_result_t UR_APICALL urIPCOpenMemHandleExp( return UR_RESULT_ERROR_UNINITIALIZED; // forward to device-platform - return pfnOpenMemHandleExp(hContext, hIPCMem, ppMem); + return pfnOpenMemHandleExp(hContext, hDevice, ipcMemHandleData, + ipcMemHandleDataSize, ppMem); } /////////////////////////////////////////////////////////////////////////////// @@ -5536,7 +5542,7 @@ __urdlllocal ur_result_t UR_APICALL urIPCGetMemHandleDataExp( /// [in] the IPC memory handle ur_exp_ipc_mem_handle_t hIPCMem, /// [out][optional] a pointer to the IPC memory handle data - const void **ppIPCHandleData, + void **ppIPCHandleData, /// [out][optional] size of the resulting IPC memory handle data size_t *pIPCMemHandleDataSizeRet) { @@ -5551,51 +5557,6 @@ __urdlllocal ur_result_t UR_APICALL urIPCGetMemHandleDataExp( pIPCMemHandleDataSizeRet); } -/////////////////////////////////////////////////////////////////////////////// -/// @brief Intercept function for urIPCCreateMemHandleFromDataExp -__urdlllocal ur_result_t UR_APICALL urIPCCreateMemHandleFromDataExp( - /// [in] handle of the context object - ur_context_handle_t hContext, - /// [in] handle of the device object the corresponding USM device memory - /// was allocated on - ur_device_handle_t hDevice, - /// [in] the IPC memory handle data - const void *ipcMemHandleData, - /// [in] size of the IPC memory handle data - size_t ipcMemHandleDataSize, - /// [out] the IPC memory handle - ur_exp_ipc_mem_handle_t *phIPCMem) { - - auto *dditable = *reinterpret_cast(hContext); - - auto *pfnCreateMemHandleFromDataExp = - dditable->IPCExp.pfnCreateMemHandleFromDataExp; - if (nullptr == pfnCreateMemHandleFromDataExp) - return UR_RESULT_ERROR_UNINITIALIZED; - - // forward to device-platform - return pfnCreateMemHandleFromDataExp(hContext, hDevice, ipcMemHandleData, - ipcMemHandleDataSize, phIPCMem); -} - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Intercept function for urIPCDestroyMemHandleExp -__urdlllocal ur_result_t UR_APICALL urIPCDestroyMemHandleExp( - /// [in] handle of the context object - ur_context_handle_t hContext, - /// [in] the IPC memory handle - ur_exp_ipc_mem_handle_t hIPCMem) { - - auto *dditable = *reinterpret_cast(hContext); - - auto *pfnDestroyMemHandleExp = dditable->IPCExp.pfnDestroyMemHandleExp; - if (nullptr == pfnDestroyMemHandleExp) - return UR_RESULT_ERROR_UNINITIALIZED; - - // forward to device-platform - return pfnDestroyMemHandleExp(hContext, hIPCMem); -} - /////////////////////////////////////////////////////////////////////////////// /// @brief Intercept function for urMemoryExportAllocExportableMemoryExp __urdlllocal ur_result_t UR_APICALL urMemoryExportAllocExportableMemoryExp( @@ -6513,9 +6474,6 @@ UR_DLLEXPORT ur_result_t UR_APICALL urGetIPCExpProcAddrTable( pDdiTable->pfnOpenMemHandleExp = ur_loader::urIPCOpenMemHandleExp; pDdiTable->pfnCloseMemHandleExp = ur_loader::urIPCCloseMemHandleExp; pDdiTable->pfnGetMemHandleDataExp = ur_loader::urIPCGetMemHandleDataExp; - pDdiTable->pfnCreateMemHandleFromDataExp = - ur_loader::urIPCCreateMemHandleFromDataExp; - pDdiTable->pfnDestroyMemHandleExp = ur_loader::urIPCDestroyMemHandleExp; } else { // return pointers directly to platform's DDIs *pDdiTable = ur_loader::getContext()->platforms.front().dditable.IPCExp; diff --git a/unified-runtime/source/loader/ur_libapi.cpp b/unified-runtime/source/loader/ur_libapi.cpp index 0da75c3f817fc..6506de1cff988 100644 --- a/unified-runtime/source/loader/ur_libapi.cpp +++ b/unified-runtime/source/loader/ur_libapi.cpp @@ -10063,8 +10063,8 @@ ur_result_t UR_APICALL urIPCPutMemHandleExp( } /////////////////////////////////////////////////////////////////////////////// -/// @brief Opens an inter-process memory handle to get the corresponding pointer -/// to device USM memory +/// @brief Opens an inter-process memory handle from raw data to get the +/// corresponding pointer to device USM memory /// /// @returns /// - ::UR_RESULT_SUCCESS @@ -10073,18 +10073,26 @@ ur_result_t UR_APICALL urIPCPutMemHandleExp( /// - ::UR_RESULT_ERROR_ADAPTER_SPECIFIC /// - ::UR_RESULT_ERROR_INVALID_NULL_HANDLE /// + `NULL == hContext` -/// + NULL == hContext -/// + NULL == hIPCMem +/// + `NULL == hDevice` /// - ::UR_RESULT_ERROR_INVALID_CONTEXT /// - ::UR_RESULT_ERROR_INVALID_NULL_POINTER -/// + NULL == ppMem +/// + `NULL == ipcMemHandleData` +/// + `NULL == ppMem` +/// - ::UR_RESULT_ERROR_INVALID_VALUE +/// + ipcMemHandleDataSize is not the same as the size of IPC memory +/// handle data /// - ::UR_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::UR_RESULT_ERROR_OUT_OF_RESOURCES ur_result_t UR_APICALL urIPCOpenMemHandleExp( /// [in] handle of the context object ur_context_handle_t hContext, - /// [in] pointer to the resulting IPC memory handle - ur_exp_ipc_mem_handle_t hIPCMem, + /// [in] handle of the device object the corresponding USM device memory + /// was allocated on + ur_device_handle_t hDevice, + /// [in] the IPC memory handle data + void *ipcMemHandleData, + /// [in] size of the IPC memory handle data + size_t ipcMemHandleDataSize, /// [out] pointer to a pointer to device USM memory void **ppMem) try { auto pfnOpenMemHandleExp = @@ -10092,7 +10100,8 @@ ur_result_t UR_APICALL urIPCOpenMemHandleExp( if (nullptr == pfnOpenMemHandleExp) return UR_RESULT_ERROR_UNINITIALIZED; - return pfnOpenMemHandleExp(hContext, hIPCMem, ppMem); + return pfnOpenMemHandleExp(hContext, hDevice, ipcMemHandleData, + ipcMemHandleDataSize, ppMem); } catch (...) { return exceptionToResult(std::current_exception()); } @@ -10107,10 +10116,9 @@ ur_result_t UR_APICALL urIPCOpenMemHandleExp( /// - ::UR_RESULT_ERROR_ADAPTER_SPECIFIC /// - ::UR_RESULT_ERROR_INVALID_NULL_HANDLE /// + `NULL == hContext` -/// + NULL == hContext /// - ::UR_RESULT_ERROR_INVALID_CONTEXT /// - ::UR_RESULT_ERROR_INVALID_NULL_POINTER -/// + NULL == pMem +/// + `NULL == pMem` /// - ::UR_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::UR_RESULT_ERROR_OUT_OF_RESOURCES ur_result_t UR_APICALL urIPCCloseMemHandleExp( @@ -10149,7 +10157,7 @@ ur_result_t UR_APICALL urIPCGetMemHandleDataExp( /// [in] the IPC memory handle ur_exp_ipc_mem_handle_t hIPCMem, /// [out][optional] a pointer to the IPC memory handle data - const void **ppIPCHandleData, + void **ppIPCHandleData, /// [out][optional] size of the resulting IPC memory handle data size_t *pIPCMemHandleDataSizeRet) try { auto pfnGetMemHandleDataExp = @@ -10163,85 +10171,6 @@ ur_result_t UR_APICALL urIPCGetMemHandleDataExp( return exceptionToResult(std::current_exception()); } -/////////////////////////////////////////////////////////////////////////////// -/// @brief Creates an inter-process memory handle from handle data -/// -/// @returns -/// - ::UR_RESULT_SUCCESS -/// - ::UR_RESULT_ERROR_UNINITIALIZED -/// - ::UR_RESULT_ERROR_DEVICE_LOST -/// - ::UR_RESULT_ERROR_ADAPTER_SPECIFIC -/// - ::UR_RESULT_ERROR_INVALID_NULL_HANDLE -/// + `NULL == hContext` -/// + `NULL == hDevice` -/// + NULL == hContext -/// + NULL == hDevice -/// - ::UR_RESULT_ERROR_INVALID_NULL_POINTER -/// + `NULL == phIPCMem` -/// + NULL == ipcMemHandleData -/// + NULL == phIPCMem -/// - ::UR_RESULT_ERROR_INVALID_CONTEXT -/// - ::UR_RESULT_ERROR_INVALID_VALUE -/// + ipcMemHandleDataSize is not the same as the size of IPC memory -/// handle data -/// - ::UR_RESULT_ERROR_OUT_OF_HOST_MEMORY -/// - ::UR_RESULT_ERROR_OUT_OF_RESOURCES -ur_result_t UR_APICALL urIPCCreateMemHandleFromDataExp( - /// [in] handle of the context object - ur_context_handle_t hContext, - /// [in] handle of the device object the corresponding USM device memory - /// was allocated on - ur_device_handle_t hDevice, - /// [in] the IPC memory handle data - const void *ipcMemHandleData, - /// [in] size of the IPC memory handle data - size_t ipcMemHandleDataSize, - /// [out] the IPC memory handle - ur_exp_ipc_mem_handle_t *phIPCMem) try { - auto pfnCreateMemHandleFromDataExp = - ur_lib::getContext()->urDdiTable.IPCExp.pfnCreateMemHandleFromDataExp; - if (nullptr == pfnCreateMemHandleFromDataExp) - return UR_RESULT_ERROR_UNINITIALIZED; - - return pfnCreateMemHandleFromDataExp(hContext, hDevice, ipcMemHandleData, - ipcMemHandleDataSize, phIPCMem); -} catch (...) { - return exceptionToResult(std::current_exception()); -} - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Destroys an inter-process memory handle created through -/// urIPCCreateMemHandleFromDataExp -/// -/// @returns -/// - ::UR_RESULT_SUCCESS -/// - ::UR_RESULT_ERROR_UNINITIALIZED -/// - ::UR_RESULT_ERROR_DEVICE_LOST -/// - ::UR_RESULT_ERROR_ADAPTER_SPECIFIC -/// - ::UR_RESULT_ERROR_INVALID_NULL_HANDLE -/// + `NULL == hContext` -/// + NULL == hContext -/// + NULL == hIPCMem -/// - ::UR_RESULT_ERROR_INVALID_CONTEXT -/// - ::UR_RESULT_ERROR_INVALID_VALUE -/// + hIPCMem was not created through CreateMemHandleFromDataExp -/// - ::UR_RESULT_ERROR_OUT_OF_HOST_MEMORY -/// - ::UR_RESULT_ERROR_OUT_OF_RESOURCES -ur_result_t UR_APICALL urIPCDestroyMemHandleExp( - /// [in] handle of the context object - ur_context_handle_t hContext, - /// [in] the IPC memory handle - ur_exp_ipc_mem_handle_t hIPCMem) try { - auto pfnDestroyMemHandleExp = - ur_lib::getContext()->urDdiTable.IPCExp.pfnDestroyMemHandleExp; - if (nullptr == pfnDestroyMemHandleExp) - return UR_RESULT_ERROR_UNINITIALIZED; - - return pfnDestroyMemHandleExp(hContext, hIPCMem); -} catch (...) { - return exceptionToResult(std::current_exception()); -} - /////////////////////////////////////////////////////////////////////////////// /// @brief Allocate an exportable memory region and return a pointer to that /// allocation. diff --git a/unified-runtime/source/loader/ur_print.cpp b/unified-runtime/source/loader/ur_print.cpp index 6b4af510ce561..4c5552733bd38 100644 --- a/unified-runtime/source/loader/ur_print.cpp +++ b/unified-runtime/source/loader/ur_print.cpp @@ -2040,22 +2040,6 @@ ur_result_t urPrintIpcGetMemHandleDataExpParams( return str_copy(&ss, buffer, buff_size, out_size); } -ur_result_t urPrintIpcCreateMemHandleFromDataExpParams( - const struct ur_ipc_create_mem_handle_from_data_exp_params_t *params, - char *buffer, const size_t buff_size, size_t *out_size) { - std::stringstream ss; - ss << params; - return str_copy(&ss, buffer, buff_size, out_size); -} - -ur_result_t urPrintIpcDestroyMemHandleExpParams( - const struct ur_ipc_destroy_mem_handle_exp_params_t *params, char *buffer, - const size_t buff_size, size_t *out_size) { - std::stringstream ss; - ss << params; - return str_copy(&ss, buffer, buff_size, out_size); -} - ur_result_t urPrintKernelCreateParams(const struct ur_kernel_create_params_t *params, char *buffer, const size_t buff_size, diff --git a/unified-runtime/source/ur_api.cpp b/unified-runtime/source/ur_api.cpp index 186a78f882c3e..21805a78e9fbd 100644 --- a/unified-runtime/source/ur_api.cpp +++ b/unified-runtime/source/ur_api.cpp @@ -8758,8 +8758,8 @@ ur_result_t UR_APICALL urIPCPutMemHandleExp( } /////////////////////////////////////////////////////////////////////////////// -/// @brief Opens an inter-process memory handle to get the corresponding pointer -/// to device USM memory +/// @brief Opens an inter-process memory handle from raw data to get the +/// corresponding pointer to device USM memory /// /// @returns /// - ::UR_RESULT_SUCCESS @@ -8768,18 +8768,25 @@ ur_result_t UR_APICALL urIPCPutMemHandleExp( /// - ::UR_RESULT_ERROR_ADAPTER_SPECIFIC /// - ::UR_RESULT_ERROR_INVALID_NULL_HANDLE /// + `NULL == hContext` -/// + NULL == hContext -/// + NULL == hIPCMem /// - ::UR_RESULT_ERROR_INVALID_CONTEXT /// - ::UR_RESULT_ERROR_INVALID_NULL_POINTER -/// + NULL == ppMem +/// + `NULL == ipcMemHandleData` +/// + `NULL == ppMem` +/// - ::UR_RESULT_ERROR_INVALID_VALUE +/// + ipcMemHandleDataSize is not the same as the size of IPC memory +/// handle data /// - ::UR_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::UR_RESULT_ERROR_OUT_OF_RESOURCES ur_result_t UR_APICALL urIPCOpenMemHandleExp( /// [in] handle of the context object ur_context_handle_t hContext, - /// [in] pointer to the resulting IPC memory handle - ur_exp_ipc_mem_handle_t hIPCMem, + /// [in] handle of the device object the corresponding USM device memory + /// was allocated on + ur_device_handle_t hDevice, + /// [in] the IPC memory handle data + void *ipcMemHandleData, + /// [in] size of the IPC memory handle data + size_t ipcMemHandleDataSize, /// [out] pointer to a pointer to device USM memory void **ppMem) { ur_result_t result = UR_RESULT_SUCCESS; @@ -8832,79 +8839,13 @@ ur_result_t UR_APICALL urIPCGetMemHandleDataExp( /// [in] the IPC memory handle ur_exp_ipc_mem_handle_t hIPCMem, /// [out][optional] a pointer to the IPC memory handle data - const void **ppIPCHandleData, + void **ppIPCHandleData, /// [out][optional] size of the resulting IPC memory handle data size_t *pIPCMemHandleDataSizeRet) { ur_result_t result = UR_RESULT_SUCCESS; return result; } -/////////////////////////////////////////////////////////////////////////////// -/// @brief Creates an inter-process memory handle from handle data -/// -/// @returns -/// - ::UR_RESULT_SUCCESS -/// - ::UR_RESULT_ERROR_UNINITIALIZED -/// - ::UR_RESULT_ERROR_DEVICE_LOST -/// - ::UR_RESULT_ERROR_ADAPTER_SPECIFIC -/// - ::UR_RESULT_ERROR_INVALID_NULL_HANDLE -/// + `NULL == hContext` -/// + `NULL == hDevice` -/// + NULL == hContext -/// + NULL == hDevice -/// - ::UR_RESULT_ERROR_INVALID_NULL_POINTER -/// + `NULL == phIPCMem` -/// + NULL == ipcMemHandleData -/// + NULL == phIPCMem -/// - ::UR_RESULT_ERROR_INVALID_CONTEXT -/// - ::UR_RESULT_ERROR_INVALID_VALUE -/// + ipcMemHandleDataSize is not the same as the size of IPC memory -/// handle data -/// - ::UR_RESULT_ERROR_OUT_OF_HOST_MEMORY -/// - ::UR_RESULT_ERROR_OUT_OF_RESOURCES -ur_result_t UR_APICALL urIPCCreateMemHandleFromDataExp( - /// [in] handle of the context object - ur_context_handle_t hContext, - /// [in] handle of the device object the corresponding USM device memory - /// was allocated on - ur_device_handle_t hDevice, - /// [in] the IPC memory handle data - const void *ipcMemHandleData, - /// [in] size of the IPC memory handle data - size_t ipcMemHandleDataSize, - /// [out] the IPC memory handle - ur_exp_ipc_mem_handle_t *phIPCMem) { - ur_result_t result = UR_RESULT_SUCCESS; - return result; -} - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Destroys an inter-process memory handle created through -/// urIPCCreateMemHandleFromDataExp -/// -/// @returns -/// - ::UR_RESULT_SUCCESS -/// - ::UR_RESULT_ERROR_UNINITIALIZED -/// - ::UR_RESULT_ERROR_DEVICE_LOST -/// - ::UR_RESULT_ERROR_ADAPTER_SPECIFIC -/// - ::UR_RESULT_ERROR_INVALID_NULL_HANDLE -/// + `NULL == hContext` -/// + NULL == hContext -/// + NULL == hIPCMem -/// - ::UR_RESULT_ERROR_INVALID_CONTEXT -/// - ::UR_RESULT_ERROR_INVALID_VALUE -/// + hIPCMem was not created through CreateMemHandleFromDataExp -/// - ::UR_RESULT_ERROR_OUT_OF_HOST_MEMORY -/// - ::UR_RESULT_ERROR_OUT_OF_RESOURCES -ur_result_t UR_APICALL urIPCDestroyMemHandleExp( - /// [in] handle of the context object - ur_context_handle_t hContext, - /// [in] the IPC memory handle - ur_exp_ipc_mem_handle_t hIPCMem) { - ur_result_t result = UR_RESULT_SUCCESS; - return result; -} - /////////////////////////////////////////////////////////////////////////////// /// @brief Allocate an exportable memory region and return a pointer to that /// allocation. From baa805ff91edb2511827650b9cdeca8a9d3fe905 Mon Sep 17 00:00:00 2001 From: "Larsen, Steffen" Date: Wed, 17 Sep 2025 01:22:56 -0700 Subject: [PATCH 07/38] Adjust for UR changes Signed-off-by: Larsen, Steffen --- ...neapi_inter_process_communication.asciidoc | 9 +- .../ext/oneapi/experimental/ipc_memory.hpp | 10 ++- sycl/source/detail/ipc_memory_impl.hpp | 49 ++--------- sycl/source/ipc_memory.cpp | 32 +++++-- sycl/test-e2e/Experimental/ipc_memory.cpp | 15 ++-- sycl/unittests/Extensions/IPC.cpp | 84 ++++--------------- 6 files changed, 74 insertions(+), 125 deletions(-) diff --git a/sycl/doc/extensions/experimental/sycl_ext_oneapi_inter_process_communication.asciidoc b/sycl/doc/extensions/experimental/sycl_ext_oneapi_inter_process_communication.asciidoc index 3d013c08a7827..31896ce73a837 100644 --- a/sycl/doc/extensions/experimental/sycl_ext_oneapi_inter_process_communication.asciidoc +++ b/sycl/doc/extensions/experimental/sycl_ext_oneapi_inter_process_communication.asciidoc @@ -107,14 +107,17 @@ in the SYCL 2020 specification. ``` namespace sycl::ext::oneapi::experimental { +using ipc_memory_handle_data_t = span; class ipc_memory { public: ipc_memory(void *ptr, sycl::context &ctx); - ipc_memory(span ipc_memory_handle_data, - const sycl::context &ctx, const sycl::device &dev); - span get_handle_data() const; + static void *open(ipc_memory_handle_data_t ipc_memory_handle_data, + const sycl::context &ctx, const sycl::device &dev); + static void close(void *ptr, const sycl::context &ctx); + + ipc_memory_handle_data_t get_handle_data() const; void *get_ptr() const; }; diff --git a/sycl/include/sycl/ext/oneapi/experimental/ipc_memory.hpp b/sycl/include/sycl/ext/oneapi/experimental/ipc_memory.hpp index ccb3eb7471675..dbeb1aa9a6236 100644 --- a/sycl/include/sycl/ext/oneapi/experimental/ipc_memory.hpp +++ b/sycl/include/sycl/ext/oneapi/experimental/ipc_memory.hpp @@ -26,14 +26,18 @@ class ipc_memory_impl; } namespace ext::oneapi::experimental { +using ipc_memory_handle_data_t = span; + class __SYCL_EXPORT ipc_memory : public sycl::detail::OwnerLessBase { public: ipc_memory(void *Ptr, const sycl::context &Ctx); - ipc_memory(const span IPCMemoryHandleData, - const sycl::context &Ctx, const sycl::device &Dev); - sycl::span get_handle_data() const; + static void *open(ipc_memory_handle_data_t IPCMemoryHandleData, + const sycl::context &Ctx, const sycl::device &Dev); + static void close(void *Ptr, const sycl::context &Ctx); + + ipc_memory_handle_data_t get_handle_data() const; void *get_ptr() const; diff --git a/sycl/source/detail/ipc_memory_impl.hpp b/sycl/source/detail/ipc_memory_impl.hpp index 0d41ca2b699cd..b96cf2d3ce8b4 100644 --- a/sycl/source/detail/ipc_memory_impl.hpp +++ b/sycl/source/detail/ipc_memory_impl.hpp @@ -11,7 +11,7 @@ #include #include #include -#include +#include #include @@ -26,51 +26,20 @@ class ipc_memory_impl { public: ipc_memory_impl(void *Ptr, const sycl::context &Ctx, private_tag) - : MRelationship{HandleRelationship::Owner}, MContext{getSyclObjImpl(Ctx)}, - MPtr{Ptr} { + : MContext{getSyclObjImpl(Ctx)}, MPtr{Ptr} { adapter_impl &Adapter = MContext->getAdapter(); Adapter.call(MContext->getHandleRef(), Ptr, &MUrHandle); } - ipc_memory_impl(span IPCMemoryHandleData, - const sycl::context &Ctx, const sycl::device &Dev, - private_tag) - : MRelationship{HandleRelationship::Adopted}, - MContext{getSyclObjImpl(Ctx)} { - adapter_impl &Adapter = MContext->getAdapter(); - - // First recreate the IPC handle. - ur_result_t UrRes = - Adapter.call_nocheck( - MContext->getHandleRef(), getSyclObjImpl(Dev)->getHandleRef(), - IPCMemoryHandleData.data(), IPCMemoryHandleData.size(), &MUrHandle); - if (UrRes == UR_RESULT_ERROR_INVALID_VALUE) - throw sycl::exception(sycl::make_error_code(errc::invalid), - "IPCMemoryHandleData data size does not correspond " - "to the target platform's IPC memory handle size."); - Adapter.checkUrResult(UrRes); - - // Then open it and retrieve the pointer. - Adapter.call(MContext->getHandleRef(), - MUrHandle, &MPtr); - } - ipc_memory_impl(const ipc_memory_impl &) = delete; ipc_memory_impl(ipc_memory_impl &&) = default; ~ipc_memory_impl() { try { adapter_impl &Adapter = MContext->getAdapter(); - if (MRelationship == HandleRelationship::Owner) { - Adapter.call_nocheck( - MContext->getHandleRef(), MUrHandle); - } else { - Adapter.call_nocheck( - MContext->getHandleRef(), MPtr); - Adapter.call_nocheck( - MContext->getHandleRef(), MUrHandle); - } + Adapter.call_nocheck( + MContext->getHandleRef(), MUrHandle); } catch (std::exception &e) { __SYCL_REPORT_EXCEPTION_TO_STREAM("exception in ~ipc_memory_impl", e); } @@ -85,20 +54,20 @@ class ipc_memory_impl { private_tag{}); } - sycl::span get_handle_data() const { + sycl::ext::oneapi::experimental::ipc_memory_handle_data_t + get_handle_data() const { adapter_impl &Adapter = MContext->getAdapter(); - const void *HandleDataPtr = nullptr; + void *HandleDataPtr = nullptr; size_t HandleDataSize = 0; Adapter.call( MContext->getHandleRef(), MUrHandle, &HandleDataPtr, &HandleDataSize); - return sycl::span{ - reinterpret_cast(HandleDataPtr), HandleDataSize}; + return sycl::span{ + reinterpret_cast(HandleDataPtr), HandleDataSize}; } void *get_ptr() const { return MPtr; } private: - enum class HandleRelationship { Owner, Adopted } MRelationship; std::shared_ptr MContext; void *MPtr = nullptr; ur_exp_ipc_mem_handle_t MUrHandle = nullptr; diff --git a/sycl/source/ipc_memory.cpp b/sycl/source/ipc_memory.cpp index 3fc790656ee82..d6a8a81ba5fd5 100644 --- a/sycl/source/ipc_memory.cpp +++ b/sycl/source/ipc_memory.cpp @@ -6,6 +6,8 @@ // //===----------------------------------------------------------------------===// +#include +#include #include #include #include @@ -17,12 +19,32 @@ namespace ext::oneapi::experimental { ipc_memory::ipc_memory(void *Ptr, const sycl::context &Ctx) : impl(detail::ipc_memory_impl::create(Ptr, Ctx)) {} -ipc_memory::ipc_memory( - span IPCMemoryHandleData, - const sycl::context &Ctx, const sycl::device &Dev) - : impl(detail::ipc_memory_impl::create(IPCMemoryHandleData, Ctx, Dev)) {} +void *ipc_memory::open(ipc_memory_handle_data_t IPCMemoryHandleData, + const sycl::context &Ctx, const sycl::device &Dev) { + auto CtxImpl = sycl::detail::getSyclObjImpl(Ctx); + sycl::detail::adapter_impl &Adapter = CtxImpl->getAdapter(); -span ipc_memory::get_handle_data() const { + void *Ptr = nullptr; + ur_result_t UrRes = + Adapter.call_nocheck( + CtxImpl->getHandleRef(), getSyclObjImpl(Dev)->getHandleRef(), + IPCMemoryHandleData.data(), IPCMemoryHandleData.size(), &Ptr); + if (UrRes == UR_RESULT_ERROR_INVALID_VALUE) + throw sycl::exception(sycl::make_error_code(errc::invalid), + "IPCMemoryHandleData data size does not correspond " + "to the target platform's IPC memory handle size."); + Adapter.checkUrResult(UrRes); + return Ptr; +} + +void ipc_memory::close(void *Ptr, const sycl::context &Ctx) { + auto CtxImpl = sycl::detail::getSyclObjImpl(Ctx); + sycl::detail::adapter_impl &Adapter = CtxImpl->getAdapter(); + Adapter.call( + CtxImpl->getHandleRef(), Ptr); +} + +ipc_memory_handle_data_t ipc_memory::get_handle_data() const { return impl->get_handle_data(); } diff --git a/sycl/test-e2e/Experimental/ipc_memory.cpp b/sycl/test-e2e/Experimental/ipc_memory.cpp index fc48ad852f84c..d8ef95c50264a 100644 --- a/sycl/test-e2e/Experimental/ipc_memory.cpp +++ b/sycl/test-e2e/Experimental/ipc_memory.cpp @@ -51,8 +51,7 @@ int spawner(int argc, char *argv[]) { // Write handle data to file. { - sycl::span HandleData = - IPCMem.get_handle_data(); + syclexp::ipc_memory_handle_data_t HandleData = IPCMem.get_handle_data(); size_t HandleDataSize = HandleData.size(); std::fstream FS(CommsFile, std::ios_base::out | std::ios_base::binary); FS.write(reinterpret_cast(&HandleDataSize), sizeof(size_t)); @@ -89,11 +88,10 @@ int consumer() { std::unique_ptr HandleData{new char[HandleSize]}; FS.read(HandleData.get(), HandleSize); - // Re-create the IPC handle. - sycl::span Handle{HandleData.get(), - HandleSize}; - syclexp::ipc_memory IPCMem{Handle, Q.get_context(), Q.get_device()}; - int *DataPtr = reinterpret_cast(IPCMem.get_ptr()); + // Open IPC handle. + syclexp::ipc_memory_handle_data_t Handle{HandleData.get(), HandleSize}; + int *DataPtr = reinterpret_cast( + syclexp::ipc_memory::open(Handle, Q.get_context(), Q.get_device())); // Test the data already in the USM pointer. // TODO: This is currently disabled for L0 due to a bug in the original data @@ -115,6 +113,9 @@ int consumer() { DataPtr[I] = static_cast(N - I.get_linear_id()); }).wait(); + // Close the IPC pointer. + syclexp::ipc_memory::close(DataPtr, Q.get_context()); + return Failures; } diff --git a/sycl/unittests/Extensions/IPC.cpp b/sycl/unittests/Extensions/IPC.cpp index c650c3ed83163..6eff9c9429973 100644 --- a/sycl/unittests/Extensions/IPC.cpp +++ b/sycl/unittests/Extensions/IPC.cpp @@ -32,8 +32,6 @@ thread_local int urIPCGetMemHandleExp_counter = 0; thread_local int urIPCPutMemHandleExp_counter = 0; thread_local int urIPCOpenMemHandleExp_counter = 0; thread_local int urIPCCloseMemHandleExp_counter = 0; -thread_local int urIPCCreateMemHandleFromDataExp_counter = 0; -thread_local int urIPCDestroyMemHandleExp_counter = 0; thread_local int urIPCGetMemHandleDataExp_counter = 0; ur_result_t replace_urIPCGetMemHandleExp(void *pParams) { @@ -54,7 +52,8 @@ ur_result_t replace_urIPCPutMemHandleExp(void *pParams) { ur_result_t replace_urIPCOpenMemHandleExp(void *pParams) { ++urIPCOpenMemHandleExp_counter; auto params = *static_cast(pParams); - EXPECT_EQ(*params.phIPCMem, DummyMemHandle); + EXPECT_EQ(*params.pipcMemHandleData, DummyHandleData); + EXPECT_EQ(*params.pipcMemHandleDataSize, DummyHandleDataSize); **params.pppMem = DummyPtr; return UR_RESULT_SUCCESS; } @@ -66,23 +65,6 @@ ur_result_t replace_urIPCCloseMemHandleExp(void *pParams) { return UR_RESULT_SUCCESS; } -ur_result_t replace_urIPCCreateMemHandleFromDataExp(void *pParams) { - ++urIPCCreateMemHandleFromDataExp_counter; - auto params = - *static_cast(pParams); - EXPECT_EQ(*params.pipcMemHandleData, DummyHandleData); - EXPECT_EQ(*params.pipcMemHandleDataSize, DummyHandleDataSize); - **params.pphIPCMem = DummyMemHandle; - return UR_RESULT_SUCCESS; -} - -ur_result_t replace_urIPCDestroyMemHandleExp(void *pParams) { - ++urIPCDestroyMemHandleExp_counter; - auto params = *static_cast(pParams); - EXPECT_EQ(*params.phIPCMem, DummyMemHandle); - return UR_RESULT_SUCCESS; -} - ur_result_t replace_urIPCGetMemHandleDataExp(void *pParams) { ++urIPCGetMemHandleDataExp_counter; auto params = @@ -103,8 +85,6 @@ class IPCTests : public ::testing::Test { urIPCPutMemHandleExp_counter = 0; urIPCOpenMemHandleExp_counter = 0; urIPCCloseMemHandleExp_counter = 0; - urIPCCreateMemHandleFromDataExp_counter = 0; - urIPCDestroyMemHandleExp_counter = 0; urIPCGetMemHandleDataExp_counter = 0; mock::getCallbacks().set_replace_callback("urIPCGetMemHandleExp", @@ -115,11 +95,6 @@ class IPCTests : public ::testing::Test { replace_urIPCOpenMemHandleExp); mock::getCallbacks().set_replace_callback("urIPCCloseMemHandleExp", replace_urIPCCloseMemHandleExp); - mock::getCallbacks().set_replace_callback( - "urIPCCreateMemHandleFromDataExp", - replace_urIPCCreateMemHandleFromDataExp); - mock::getCallbacks().set_replace_callback("urIPCDestroyMemHandleExp", - replace_urIPCDestroyMemHandleExp); mock::getCallbacks().set_replace_callback("urIPCGetMemHandleDataExp", replace_urIPCGetMemHandleDataExp); } @@ -137,11 +112,9 @@ TEST_F(IPCTests, IPCGetPut) { EXPECT_EQ(urIPCPutMemHandleExp_counter, 0); EXPECT_EQ(urIPCOpenMemHandleExp_counter, 0); EXPECT_EQ(urIPCCloseMemHandleExp_counter, 0); - EXPECT_EQ(urIPCCreateMemHandleFromDataExp_counter, 0); - EXPECT_EQ(urIPCDestroyMemHandleExp_counter, 0); EXPECT_EQ(urIPCGetMemHandleDataExp_counter, 0); - sycl::span IPCMemHandleData = + syclexp::ipc_memory_handle_data_t IPCMemHandleData = IPCMem.get_handle_data(); EXPECT_EQ(IPCMemHandleData.data(), DummyHandleData); EXPECT_EQ(IPCMemHandleData.size(), DummyHandleDataSize); @@ -151,8 +124,6 @@ TEST_F(IPCTests, IPCGetPut) { EXPECT_EQ(urIPCPutMemHandleExp_counter, 0); EXPECT_EQ(urIPCOpenMemHandleExp_counter, 0); EXPECT_EQ(urIPCCloseMemHandleExp_counter, 0); - EXPECT_EQ(urIPCCreateMemHandleFromDataExp_counter, 0); - EXPECT_EQ(urIPCDestroyMemHandleExp_counter, 0); EXPECT_EQ(urIPCGetMemHandleDataExp_counter, 1); } @@ -162,52 +133,31 @@ TEST_F(IPCTests, IPCGetPut) { EXPECT_EQ(urIPCPutMemHandleExp_counter, 1); EXPECT_EQ(urIPCOpenMemHandleExp_counter, 0); EXPECT_EQ(urIPCCloseMemHandleExp_counter, 0); - EXPECT_EQ(urIPCCreateMemHandleFromDataExp_counter, 0); - EXPECT_EQ(urIPCDestroyMemHandleExp_counter, 0); EXPECT_EQ(urIPCGetMemHandleDataExp_counter, 1); } TEST_F(IPCTests, IPCOpenClose) { - { - sycl::span HandleData{ - DummyHandleData, DummyHandleDataSize}; - syclexp::ipc_memory IPCMem{HandleData, Ctxt, Ctxt.get_devices()[0]}; - EXPECT_EQ(IPCMem.get_ptr(), DummyPtr); - - // Creating the IPC memory from handle data should first re-create the - // handle and then call open on it. - EXPECT_EQ(urIPCGetMemHandleExp_counter, 0); - EXPECT_EQ(urIPCPutMemHandleExp_counter, 0); - EXPECT_EQ(urIPCOpenMemHandleExp_counter, 1); - EXPECT_EQ(urIPCCloseMemHandleExp_counter, 0); - EXPECT_EQ(urIPCCreateMemHandleFromDataExp_counter, 1); - EXPECT_EQ(urIPCDestroyMemHandleExp_counter, 0); - EXPECT_EQ(urIPCGetMemHandleDataExp_counter, 0); + syclexp::ipc_memory_handle_data_t HandleData{DummyHandleData, + DummyHandleDataSize}; + void *Ptr = + syclexp::ipc_memory::open(HandleData, Ctxt, Ctxt.get_devices()[0]); + EXPECT_EQ(Ptr, DummyPtr); - sycl::span IPCMemHandleData = - IPCMem.get_handle_data(); - EXPECT_EQ(IPCMemHandleData.data(), DummyHandleData); - EXPECT_EQ(IPCMemHandleData.size(), DummyHandleDataSize); + // Opening an IPC handle should call open. + EXPECT_EQ(urIPCGetMemHandleExp_counter, 0); + EXPECT_EQ(urIPCPutMemHandleExp_counter, 0); + EXPECT_EQ(urIPCOpenMemHandleExp_counter, 1); + EXPECT_EQ(urIPCCloseMemHandleExp_counter, 0); + EXPECT_EQ(urIPCGetMemHandleDataExp_counter, 0); - // Getting the underlying data should call the backend. - EXPECT_EQ(urIPCGetMemHandleExp_counter, 0); - EXPECT_EQ(urIPCPutMemHandleExp_counter, 0); - EXPECT_EQ(urIPCOpenMemHandleExp_counter, 1); - EXPECT_EQ(urIPCCloseMemHandleExp_counter, 0); - EXPECT_EQ(urIPCCreateMemHandleFromDataExp_counter, 1); - EXPECT_EQ(urIPCDestroyMemHandleExp_counter, 0); - EXPECT_EQ(urIPCGetMemHandleDataExp_counter, 1); - } + syclexp::ipc_memory::close(Ptr, Ctxt); - // When the IPC memory object dies, it should release the handle, calling - // "close" and then destroying it. + // When we close an IPC memory pointer, it should call close. EXPECT_EQ(urIPCGetMemHandleExp_counter, 0); EXPECT_EQ(urIPCPutMemHandleExp_counter, 0); EXPECT_EQ(urIPCOpenMemHandleExp_counter, 1); EXPECT_EQ(urIPCCloseMemHandleExp_counter, 1); - EXPECT_EQ(urIPCCreateMemHandleFromDataExp_counter, 1); - EXPECT_EQ(urIPCDestroyMemHandleExp_counter, 1); - EXPECT_EQ(urIPCGetMemHandleDataExp_counter, 1); + EXPECT_EQ(urIPCGetMemHandleDataExp_counter, 0); } } // namespace From 7170da91cf67fd3c6e293bebcf9585514f4b253f Mon Sep 17 00:00:00 2001 From: "Larsen, Steffen" Date: Wed, 17 Sep 2025 01:43:30 -0700 Subject: [PATCH 08/38] Address source-check issues Signed-off-by: Larsen, Steffen --- ...neapi_inter_process_communication.asciidoc | 27 +++++++++++++------ .../core/exp-inter-process-communication.yml | 24 ++++++++--------- .../source/adapters/cuda/memory.cpp | 3 +++ .../source/adapters/level_zero/memory.cpp | 3 +++ .../source/adapters/level_zero/v2/memory.cpp | 3 +++ .../loader/layers/validation/ur_valddi.cpp | 3 --- 6 files changed, 40 insertions(+), 23 deletions(-) diff --git a/sycl/doc/extensions/experimental/sycl_ext_oneapi_inter_process_communication.asciidoc b/sycl/doc/extensions/experimental/sycl_ext_oneapi_inter_process_communication.asciidoc index 31896ce73a837..20a450df999c9 100644 --- a/sycl/doc/extensions/experimental/sycl_ext_oneapi_inter_process_communication.asciidoc +++ b/sycl/doc/extensions/experimental/sycl_ext_oneapi_inter_process_communication.asciidoc @@ -145,28 +145,39 @@ and any resulting objects are undefined. a! [source] ---- -ipc_memory(span ipc_memory_handle_data, - const sycl::context &ctx, const sycl::device &dev) +static void *open(ipc_memory_handle_data_t ipc_memory_handle_data, + const sycl::context &ctx, const sycl::device &dev) ---- !==== -_Effects:_ Constructs an IPC memory object in `ctx` from the handle data -`ipc_memory_handle_data` of returned by the `get_handle_data()` member function -of another `ipc_memory` object. +_Effects:_ Returns a pointer to the same device USM memory as the device USM +memory associated with the `ipc_memory` object that the handle data originated +from. The `ipc_memory` object that the handle data originated from is allowed to be from another process on the host system. If the `ipc_memory` object that the handle data originated from has been destroyed, the behaviors of this constructor and any resulting objects are undefined. If the device USM memory the original `ipc_memory` object was created with was -not originally allocated on `dev`, the behaviors of this constructor and any -resulting objects are undefined. +not originally allocated on `dev`, the behaviors of this function is undefined. !==== a! [source] ---- -span get_handle_data() const +static void close(void *ptr, const sycl::context &ctx) +---- +!==== + +_Effects:_ Closes a device USM pointer previously returned by a call to +`ipc_memory::open()`. +Accessing `ptr` after a call to this function results in undefined behavior. + +!==== +a! +[source] +---- +ipc_memory_handle_data_t get_handle_data() const ---- !==== diff --git a/unified-runtime/scripts/core/exp-inter-process-communication.yml b/unified-runtime/scripts/core/exp-inter-process-communication.yml index 6f7e513bd6739..e5fb1691fe354 100644 --- a/unified-runtime/scripts/core/exp-inter-process-communication.yml +++ b/unified-runtime/scripts/core/exp-inter-process-communication.yml @@ -46,9 +46,9 @@ params: returns: - $X_RESULT_ERROR_INVALID_CONTEXT - $X_RESULT_ERROR_INVALID_NULL_HANDLE: - - "NULL == hContext" + - "`NULL == hContext`" - $X_RESULT_ERROR_INVALID_NULL_POINTER: - - "NULL == phIPCMem" + - "`NULL == phIPCMem`" - $X_RESULT_ERROR_OUT_OF_HOST_MEMORY - $X_RESULT_ERROR_OUT_OF_RESOURCES --- #-------------------------------------------------------------------------- @@ -67,8 +67,8 @@ params: returns: - $X_RESULT_ERROR_INVALID_CONTEXT - $X_RESULT_ERROR_INVALID_NULL_HANDLE: - - "NULL == hContext" - - "NULL == hIPCMem" + - "`NULL == hContext`" + - "`NULL == hIPCMem`" - $X_RESULT_ERROR_OUT_OF_HOST_MEMORY - $X_RESULT_ERROR_OUT_OF_RESOURCES --- #-------------------------------------------------------------------------- @@ -96,11 +96,11 @@ params: returns: - $X_RESULT_ERROR_INVALID_CONTEXT - $X_RESULT_ERROR_INVALID_NULL_HANDLE: - - "NULL == hContext" - - "NULL == hDevice" + - "`NULL == hContext`" + - "`NULL == hDevice`" - $X_RESULT_ERROR_INVALID_NULL_POINTER: - - "NULL == ipcMemHandleData" - - "NULL == ppMem" + - "`NULL == ipcMemHandleData`" + - "`NULL == ppMem`" - $X_RESULT_ERROR_INVALID_VALUE: - "ipcMemHandleDataSize is not the same as the size of IPC memory handle data" - $X_RESULT_ERROR_OUT_OF_HOST_MEMORY @@ -121,9 +121,9 @@ params: returns: - $X_RESULT_ERROR_INVALID_CONTEXT - $X_RESULT_ERROR_INVALID_NULL_HANDLE: - - "NULL == hContext" + - "`NULL == hContext`" - $X_RESULT_ERROR_INVALID_NULL_POINTER: - - "NULL == pMem" + - "`NULL == pMem`" - $X_RESULT_ERROR_OUT_OF_HOST_MEMORY - $X_RESULT_ERROR_OUT_OF_RESOURCES --- #-------------------------------------------------------------------------- @@ -148,7 +148,7 @@ params: returns: - $X_RESULT_ERROR_INVALID_CONTEXT - $X_RESULT_ERROR_INVALID_NULL_HANDLE: - - "NULL == hContext" - - "NULL == hIPCMem" + - "`NULL == hContext`" + - "`NULL == hIPCMem`" - $X_RESULT_ERROR_OUT_OF_HOST_MEMORY - $X_RESULT_ERROR_OUT_OF_RESOURCES diff --git a/unified-runtime/source/adapters/cuda/memory.cpp b/unified-runtime/source/adapters/cuda/memory.cpp index 0461b553a4fb0..2cc7384d82bdd 100644 --- a/unified-runtime/source/adapters/cuda/memory.cpp +++ b/unified-runtime/source/adapters/cuda/memory.cpp @@ -621,6 +621,9 @@ urIPCPutMemHandleExp(ur_context_handle_t, ur_exp_ipc_mem_handle_t hIPCMem) { UR_APIEXPORT ur_result_t UR_APICALL urIPCOpenMemHandleExp( ur_context_handle_t hContext, ur_device_handle_t hDevice, void *pIPCMemHandleData, size_t ipcMemHandleDataSize, void **ppMem) { + if (nullptr == pIPCMemHandleData) + return UR_RESULT_ERROR_INVALID_NULL_POINTER; + umf_memory_pool_handle_t umfPool = hDevice->MemoryPoolDevice; size_t umfHandleSize = 0; diff --git a/unified-runtime/source/adapters/level_zero/memory.cpp b/unified-runtime/source/adapters/level_zero/memory.cpp index 6c977dace0113..d3cb225fabd9c 100644 --- a/unified-runtime/source/adapters/level_zero/memory.cpp +++ b/unified-runtime/source/adapters/level_zero/memory.cpp @@ -1983,6 +1983,9 @@ ur_result_t urIPCOpenMemHandleExp(ur_context_handle_t hContext, ur_device_handle_t hDevice, void *pIPCMemHandleData, size_t ipcMemHandleDataSize, void **ppMem) { + if (nullptr == pIPCMemHandleData) + return UR_RESULT_ERROR_INVALID_NULL_POINTER; + auto *pool = hContext->DefaultPool.getPool(usm::pool_descriptor{ &hContext->DefaultPool, hContext, hDevice, UR_USM_TYPE_DEVICE, false}); if (!pool) diff --git a/unified-runtime/source/adapters/level_zero/v2/memory.cpp b/unified-runtime/source/adapters/level_zero/v2/memory.cpp index 1794cfe0cffc3..6fc15fcb91770 100644 --- a/unified-runtime/source/adapters/level_zero/v2/memory.cpp +++ b/unified-runtime/source/adapters/level_zero/v2/memory.cpp @@ -806,6 +806,9 @@ ur_result_t urIPCOpenMemHandleExp(ur_context_handle_t hContext, ur_device_handle_t hDevice, void *pIPCMemHandleData, size_t ipcMemHandleDataSize, void **ppMem) { + if (nullptr == pIPCMemHandleData) + return UR_RESULT_ERROR_INVALID_NULL_POINTER; + auto *pool = hContext->getDefaultUSMPool()->getPool( usm::pool_descriptor{hContext->getDefaultUSMPool(), hContext, hDevice, UR_USM_TYPE_DEVICE, false}); diff --git a/unified-runtime/source/loader/layers/validation/ur_valddi.cpp b/unified-runtime/source/loader/layers/validation/ur_valddi.cpp index 1d5e7c9db19a8..9ffba839389ae 100644 --- a/unified-runtime/source/loader/layers/validation/ur_valddi.cpp +++ b/unified-runtime/source/loader/layers/validation/ur_valddi.cpp @@ -10425,9 +10425,6 @@ __urdlllocal ur_result_t UR_APICALL urIPCOpenMemHandleExp( if (NULL == hDevice) return UR_RESULT_ERROR_INVALID_NULL_HANDLE; - - if (NULL == ipcMemHandleData) - return UR_RESULT_ERROR_INVALID_NULL_POINTER; } if (getContext()->enableLifetimeValidation && From ce89cfe6bd292e3d1fc70e1ca842b74413a2bfb4 Mon Sep 17 00:00:00 2001 From: "Larsen, Steffen" Date: Wed, 17 Sep 2025 02:13:06 -0700 Subject: [PATCH 09/38] Address more source checks Signed-off-by: Larsen, Steffen --- unified-runtime/source/adapters/cuda/memory.cpp | 3 --- .../source/adapters/level_zero/memory.cpp | 3 --- .../source/adapters/level_zero/v2/memory.cpp | 3 --- .../source/loader/layers/validation/ur_valddi.cpp | 15 +++++++++++++++ unified-runtime/source/loader/ur_libapi.cpp | 8 ++------ unified-runtime/source/ur_api.cpp | 12 ++++-------- 6 files changed, 21 insertions(+), 23 deletions(-) diff --git a/unified-runtime/source/adapters/cuda/memory.cpp b/unified-runtime/source/adapters/cuda/memory.cpp index 2cc7384d82bdd..0461b553a4fb0 100644 --- a/unified-runtime/source/adapters/cuda/memory.cpp +++ b/unified-runtime/source/adapters/cuda/memory.cpp @@ -621,9 +621,6 @@ urIPCPutMemHandleExp(ur_context_handle_t, ur_exp_ipc_mem_handle_t hIPCMem) { UR_APIEXPORT ur_result_t UR_APICALL urIPCOpenMemHandleExp( ur_context_handle_t hContext, ur_device_handle_t hDevice, void *pIPCMemHandleData, size_t ipcMemHandleDataSize, void **ppMem) { - if (nullptr == pIPCMemHandleData) - return UR_RESULT_ERROR_INVALID_NULL_POINTER; - umf_memory_pool_handle_t umfPool = hDevice->MemoryPoolDevice; size_t umfHandleSize = 0; diff --git a/unified-runtime/source/adapters/level_zero/memory.cpp b/unified-runtime/source/adapters/level_zero/memory.cpp index d3cb225fabd9c..6c977dace0113 100644 --- a/unified-runtime/source/adapters/level_zero/memory.cpp +++ b/unified-runtime/source/adapters/level_zero/memory.cpp @@ -1983,9 +1983,6 @@ ur_result_t urIPCOpenMemHandleExp(ur_context_handle_t hContext, ur_device_handle_t hDevice, void *pIPCMemHandleData, size_t ipcMemHandleDataSize, void **ppMem) { - if (nullptr == pIPCMemHandleData) - return UR_RESULT_ERROR_INVALID_NULL_POINTER; - auto *pool = hContext->DefaultPool.getPool(usm::pool_descriptor{ &hContext->DefaultPool, hContext, hDevice, UR_USM_TYPE_DEVICE, false}); if (!pool) diff --git a/unified-runtime/source/adapters/level_zero/v2/memory.cpp b/unified-runtime/source/adapters/level_zero/v2/memory.cpp index 6fc15fcb91770..1794cfe0cffc3 100644 --- a/unified-runtime/source/adapters/level_zero/v2/memory.cpp +++ b/unified-runtime/source/adapters/level_zero/v2/memory.cpp @@ -806,9 +806,6 @@ ur_result_t urIPCOpenMemHandleExp(ur_context_handle_t hContext, ur_device_handle_t hDevice, void *pIPCMemHandleData, size_t ipcMemHandleDataSize, void **ppMem) { - if (nullptr == pIPCMemHandleData) - return UR_RESULT_ERROR_INVALID_NULL_POINTER; - auto *pool = hContext->getDefaultUSMPool()->getPool( usm::pool_descriptor{hContext->getDefaultUSMPool(), hContext, hDevice, UR_USM_TYPE_DEVICE, false}); diff --git a/unified-runtime/source/loader/layers/validation/ur_valddi.cpp b/unified-runtime/source/loader/layers/validation/ur_valddi.cpp index 9ffba839389ae..e176955907a92 100644 --- a/unified-runtime/source/loader/layers/validation/ur_valddi.cpp +++ b/unified-runtime/source/loader/layers/validation/ur_valddi.cpp @@ -10386,6 +10386,9 @@ __urdlllocal ur_result_t UR_APICALL urIPCPutMemHandleExp( if (getContext()->enableParameterValidation) { if (NULL == hContext) return UR_RESULT_ERROR_INVALID_NULL_HANDLE; + + if (NULL == hIPCMem) + return UR_RESULT_ERROR_INVALID_NULL_HANDLE; } if (getContext()->enableLifetimeValidation && @@ -10420,6 +10423,12 @@ __urdlllocal ur_result_t UR_APICALL urIPCOpenMemHandleExp( } if (getContext()->enableParameterValidation) { + if (NULL == ipcMemHandleData) + return UR_RESULT_ERROR_INVALID_NULL_POINTER; + + if (NULL == ppMem) + return UR_RESULT_ERROR_INVALID_NULL_POINTER; + if (NULL == hContext) return UR_RESULT_ERROR_INVALID_NULL_HANDLE; @@ -10458,6 +10467,9 @@ __urdlllocal ur_result_t UR_APICALL urIPCCloseMemHandleExp( } if (getContext()->enableParameterValidation) { + if (NULL == pMem) + return UR_RESULT_ERROR_INVALID_NULL_POINTER; + if (NULL == hContext) return UR_RESULT_ERROR_INVALID_NULL_HANDLE; } @@ -10493,6 +10505,9 @@ __urdlllocal ur_result_t UR_APICALL urIPCGetMemHandleDataExp( if (getContext()->enableParameterValidation) { if (NULL == hContext) return UR_RESULT_ERROR_INVALID_NULL_HANDLE; + + if (NULL == hIPCMem) + return UR_RESULT_ERROR_INVALID_NULL_HANDLE; } if (getContext()->enableLifetimeValidation && diff --git a/unified-runtime/source/loader/ur_libapi.cpp b/unified-runtime/source/loader/ur_libapi.cpp index 6506de1cff988..0d49101533af8 100644 --- a/unified-runtime/source/loader/ur_libapi.cpp +++ b/unified-runtime/source/loader/ur_libapi.cpp @@ -10008,10 +10008,8 @@ ur_result_t UR_APICALL urEnqueueTimestampRecordingExp( /// - ::UR_RESULT_ERROR_ADAPTER_SPECIFIC /// - ::UR_RESULT_ERROR_INVALID_NULL_HANDLE /// + `NULL == hContext` -/// + NULL == hContext /// - ::UR_RESULT_ERROR_INVALID_NULL_POINTER /// + `NULL == phIPCMem` -/// + NULL == phIPCMem /// - ::UR_RESULT_ERROR_INVALID_CONTEXT /// - ::UR_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::UR_RESULT_ERROR_OUT_OF_RESOURCES @@ -10042,8 +10040,7 @@ ur_result_t UR_APICALL urIPCGetMemHandleExp( /// - ::UR_RESULT_ERROR_ADAPTER_SPECIFIC /// - ::UR_RESULT_ERROR_INVALID_NULL_HANDLE /// + `NULL == hContext` -/// + NULL == hContext -/// + NULL == hIPCMem +/// + `NULL == hIPCMem` /// - ::UR_RESULT_ERROR_INVALID_CONTEXT /// - ::UR_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::UR_RESULT_ERROR_OUT_OF_RESOURCES @@ -10146,8 +10143,7 @@ ur_result_t UR_APICALL urIPCCloseMemHandleExp( /// - ::UR_RESULT_ERROR_ADAPTER_SPECIFIC /// - ::UR_RESULT_ERROR_INVALID_NULL_HANDLE /// + `NULL == hContext` -/// + NULL == hContext -/// + NULL == hIPCMem +/// + `NULL == hIPCMem` /// - ::UR_RESULT_ERROR_INVALID_CONTEXT /// - ::UR_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::UR_RESULT_ERROR_OUT_OF_RESOURCES diff --git a/unified-runtime/source/ur_api.cpp b/unified-runtime/source/ur_api.cpp index 21805a78e9fbd..250e1af005851 100644 --- a/unified-runtime/source/ur_api.cpp +++ b/unified-runtime/source/ur_api.cpp @@ -8715,10 +8715,8 @@ ur_result_t UR_APICALL urEnqueueTimestampRecordingExp( /// - ::UR_RESULT_ERROR_ADAPTER_SPECIFIC /// - ::UR_RESULT_ERROR_INVALID_NULL_HANDLE /// + `NULL == hContext` -/// + NULL == hContext /// - ::UR_RESULT_ERROR_INVALID_NULL_POINTER /// + `NULL == phIPCMem` -/// + NULL == phIPCMem /// - ::UR_RESULT_ERROR_INVALID_CONTEXT /// - ::UR_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::UR_RESULT_ERROR_OUT_OF_RESOURCES @@ -8743,8 +8741,7 @@ ur_result_t UR_APICALL urIPCGetMemHandleExp( /// - ::UR_RESULT_ERROR_ADAPTER_SPECIFIC /// - ::UR_RESULT_ERROR_INVALID_NULL_HANDLE /// + `NULL == hContext` -/// + NULL == hContext -/// + NULL == hIPCMem +/// + `NULL == hIPCMem` /// - ::UR_RESULT_ERROR_INVALID_CONTEXT /// - ::UR_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::UR_RESULT_ERROR_OUT_OF_RESOURCES @@ -8768,6 +8765,7 @@ ur_result_t UR_APICALL urIPCPutMemHandleExp( /// - ::UR_RESULT_ERROR_ADAPTER_SPECIFIC /// - ::UR_RESULT_ERROR_INVALID_NULL_HANDLE /// + `NULL == hContext` +/// + `NULL == hDevice` /// - ::UR_RESULT_ERROR_INVALID_CONTEXT /// - ::UR_RESULT_ERROR_INVALID_NULL_POINTER /// + `NULL == ipcMemHandleData` @@ -8803,10 +8801,9 @@ ur_result_t UR_APICALL urIPCOpenMemHandleExp( /// - ::UR_RESULT_ERROR_ADAPTER_SPECIFIC /// - ::UR_RESULT_ERROR_INVALID_NULL_HANDLE /// + `NULL == hContext` -/// + NULL == hContext /// - ::UR_RESULT_ERROR_INVALID_CONTEXT /// - ::UR_RESULT_ERROR_INVALID_NULL_POINTER -/// + NULL == pMem +/// + `NULL == pMem` /// - ::UR_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::UR_RESULT_ERROR_OUT_OF_RESOURCES ur_result_t UR_APICALL urIPCCloseMemHandleExp( @@ -8828,8 +8825,7 @@ ur_result_t UR_APICALL urIPCCloseMemHandleExp( /// - ::UR_RESULT_ERROR_ADAPTER_SPECIFIC /// - ::UR_RESULT_ERROR_INVALID_NULL_HANDLE /// + `NULL == hContext` -/// + NULL == hContext -/// + NULL == hIPCMem +/// + `NULL == hIPCMem` /// - ::UR_RESULT_ERROR_INVALID_CONTEXT /// - ::UR_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::UR_RESULT_ERROR_OUT_OF_RESOURCES From 49ce33de3b3f359576fea7bd5e08e4a0fc70413b Mon Sep 17 00:00:00 2001 From: "Larsen, Steffen" Date: Wed, 17 Sep 2025 03:02:27 -0700 Subject: [PATCH 10/38] Add missing symbols Signed-off-by: Larsen, Steffen --- sycl/test/abi/sycl_symbols_linux.dump | 4 ++-- sycl/test/abi/sycl_symbols_windows.dump | 5 +++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/sycl/test/abi/sycl_symbols_linux.dump b/sycl/test/abi/sycl_symbols_linux.dump index f5b010fb15769..c64a07435c846 100644 --- a/sycl/test/abi/sycl_symbols_linux.dump +++ b/sycl/test/abi/sycl_symbols_linux.dump @@ -2991,9 +2991,9 @@ _ZN4sycl3_V13ext5intel12experimental9pipe_base18get_pipe_name_implEPKv _ZN4sycl3_V13ext6oneapi10level_zero6detail11make_deviceERKNS0_8platformEm _ZN4sycl3_V13ext6oneapi12experimental10async_freeERKNS0_5queueEPvRKNS0_6detail13code_locationE _ZN4sycl3_V13ext6oneapi12experimental10async_freeERNS0_7handlerEPv -_ZN4sycl3_V13ext6oneapi12experimental10ipc_memoryC1ENS0_4spanIKcLm18446744073709551615EEERKNS0_7contextERKNS0_6deviceE +_ZN4sycl3_V13ext6oneapi12experimental10ipc_memory4openENS0_4spanIcLm18446744073709551615EEERKNS0_7contextERKNS0_6deviceE +_ZN4sycl3_V13ext6oneapi12experimental10ipc_memory5closeEPvRKNS0_7contextE _ZN4sycl3_V13ext6oneapi12experimental10ipc_memoryC1EPvRKNS0_7contextE -_ZN4sycl3_V13ext6oneapi12experimental10ipc_memoryC2ENS0_4spanIKcLm18446744073709551615EEERKNS0_7contextERKNS0_6deviceE _ZN4sycl3_V13ext6oneapi12experimental10ipc_memoryC2EPvRKNS0_7contextE _ZN4sycl3_V13ext6oneapi12experimental10mem_adviseENS0_5queueEPvmiRKNS0_6detail13code_locationE _ZN4sycl3_V13ext6oneapi12experimental11memory_pool21increase_threshold_toEm diff --git a/sycl/test/abi/sycl_symbols_windows.dump b/sycl/test/abi/sycl_symbols_windows.dump index a3e5e90386e8d..5bd0cf2657eb2 100644 --- a/sycl/test/abi/sycl_symbols_windows.dump +++ b/sycl/test/abi/sycl_symbols_windows.dump @@ -450,7 +450,6 @@ ??0ipc_memory@experimental@oneapi@ext@_V1@sycl@@QEAA@AEBV012345@@Z ??0ipc_memory@experimental@oneapi@ext@_V1@sycl@@QEAA@PEAXAEBVcontext@45@@Z ??0ipc_memory@experimental@oneapi@ext@_V1@sycl@@AEAA@V?$shared_ptr@Vipc_memory_impl@detail@_V1@sycl@@@std@@@Z -??0ipc_memory@experimental@oneapi@ext@_V1@sycl@@QEAA@V?$span@$$CBD$0?0@45@AEBVcontext@45@AEBVdevice@45@@Z ??0ipc_memory@experimental@oneapi@ext@_V1@sycl@@QEAA@$$QEAV012345@@Z ??0kernel@_V1@sycl@@AEAA@V?$shared_ptr@Vkernel_impl@detail@_V1@sycl@@@std@@@Z ??0kernel@_V1@sycl@@QEAA@$$QEAV012@@Z @@ -3840,6 +3839,7 @@ ?category@exception@_V1@sycl@@QEBAAEBVerror_category@std@@XZ ?checkNodePropertiesAndThrow@modifiable_command_graph@detail@experimental@oneapi@ext@_V1@sycl@@KAXAEBVproperty_list@67@@Z ?clearArgs@handler@_V1@sycl@@AEAAXXZ +?close@ipc_memory@experimental@oneapi@ext@_V1@sycl@@SAXPEAXAEBVcontext@56@@Z ?code@exception@_V1@sycl@@QEBAAEBVerror_code@std@@XZ ?compile_from_source@detail@experimental@oneapi@ext@_V1@sycl@@YA?AV?$kernel_bundle@$00@56@AEAV?$kernel_bundle@$02@56@AEBV?$vector@Vdevice@_V1@sycl@@V?$allocator@Vdevice@_V1@sycl@@@std@@@std@@AEBV?$vector@Vstring_view@detail@_V1@sycl@@V?$allocator@Vstring_view@detail@_V1@sycl@@@std@@@std@@PEAVstring@156@2@Z ?compile_impl@detail@_V1@sycl@@YA?AV?$shared_ptr@Vkernel_bundle_impl@detail@_V1@sycl@@@std@@AEBV?$kernel_bundle@$0A@@23@AEBV?$vector@Vdevice@_V1@sycl@@V?$allocator@Vdevice@_V1@sycl@@@std@@@5@AEBVproperty_list@23@@Z @@ -4189,8 +4189,8 @@ ?get_empty_interop_kernel_bundle_impl@detail@_V1@sycl@@YA?AV?$shared_ptr@Vkernel_bundle_impl@detail@_V1@sycl@@@std@@AEBVcontext@23@AEBV?$vector@Vdevice@_V1@sycl@@V?$allocator@Vdevice@_V1@sycl@@@std@@@5@@Z ?get_filtering_mode@sampler@_V1@sycl@@QEBA?AW4filtering_mode@23@XZ ?get_flags@stream@_V1@sycl@@AEBAIXZ -?get_handle_data@ipc_memory@experimental@oneapi@ext@_V1@sycl@@QEBA?AV?$span@$$CBD$0?0@56@XZ ?get_handle@image_mem@experimental@oneapi@ext@_V1@sycl@@QEBA?AUimage_mem_handle@23456@XZ +?get_handle_data@ipc_memory@experimental@oneapi@ext@_V1@sycl@@QEBA?AV?$span@D$0?0@56@XZ ?get_image_channel_type@experimental@oneapi@ext@_V1@sycl@@YA?AW4image_channel_type@45@Uimage_mem_handle@12345@AEBVdevice@45@AEBVcontext@45@@Z ?get_image_channel_type@experimental@oneapi@ext@_V1@sycl@@YA?AW4image_channel_type@45@Uimage_mem_handle@12345@AEBVqueue@45@@Z ?get_image_memory_support@experimental@oneapi@ext@_V1@sycl@@YA?AV?$vector@W4image_memory_handle_type@experimental@oneapi@ext@_V1@sycl@@V?$allocator@W4image_memory_handle_type@experimental@oneapi@ext@_V1@sycl@@@std@@@std@@AEBUimage_descriptor@12345@AEBVdevice@45@AEBVcontext@45@@Z @@ -4364,6 +4364,7 @@ ?modf_impl@detail@_V1@sycl@@YANNPEAN@Z ?name@SYCLCategory@detail@_V1@sycl@@UEBAPEBDXZ ?native_specialization_constant@kernel_bundle_plain@detail@_V1@sycl@@QEBA_NXZ +?open@ipc_memory@experimental@oneapi@ext@_V1@sycl@@SAPEAXV?$span@D$0?0@56@AEBVcontext@56@AEBVdevice@56@@Z ?parallel_for@handler@_V1@sycl@@QEAAXV?$range@$00@23@Vkernel@23@@Z ?parallel_for@handler@_V1@sycl@@QEAAXV?$range@$01@23@Vkernel@23@@Z ?parallel_for@handler@_V1@sycl@@QEAAXV?$range@$02@23@Vkernel@23@@Z From c3f139bc84162ae86b1d766641e945e71b9c491f Mon Sep 17 00:00:00 2001 From: "Larsen, Steffen" Date: Wed, 17 Sep 2025 22:54:04 -0700 Subject: [PATCH 11/38] Remove known issue Signed-off-by: Larsen, Steffen --- ...neapi_inter_process_communication.asciidoc | 20 ------------------- sycl/test-e2e/Experimental/ipc_memory.cpp | 18 +++++++---------- 2 files changed, 7 insertions(+), 31 deletions(-) diff --git a/sycl/doc/extensions/experimental/sycl_ext_oneapi_inter_process_communication.asciidoc b/sycl/doc/extensions/experimental/sycl_ext_oneapi_inter_process_communication.asciidoc index 20a450df999c9..aa285570187d4 100644 --- a/sycl/doc/extensions/experimental/sycl_ext_oneapi_inter_process_communication.asciidoc +++ b/sycl/doc/extensions/experimental/sycl_ext_oneapi_inter_process_communication.asciidoc @@ -218,26 +218,6 @@ sudo bash -c "echo 0 > /proc/sys/kernel/yama/ptrace_scope" See also https://github.com/oneapi-src/unified-memory-framework/tree/main?tab=readme-ov-file#level-zero-memory-provider. -=== Level Zero memory inconsistency on recreated `ipc_memory` objects - -With the Level Zero backend, the data contained in the memory accessible through -the pointer retrieved through recreating an `ipc_memory` object in another -process may not correspond to the data in the memory in the owner process. - -For example: - 1. Process `A` allocates a block of USM device memory `X`. - 2. Process `A` writes to `X`. - 3. Process `A` creates an `ipc_memory` object from `X` and transfers the handle - data to process `B`. - 4. Process `B` recreates the `ipc_memory` object from the transferred handle - data and gets a pointer to `X` through it. - 5. Process `B` reads from `X`. *This may not result in the same data as what - process `A` wrote to `X`.* - 6. Process `B` writes to `X` and destroys it. - 7. Process `A` destroys its `ipc_memory` object and reads from `X`. This should - be the same as the data process `B` wrote to `X`. - - === Level Zero IPC memory Windows support The new IPC memory APIs are not currently supported on the Level Zero backend on diff --git a/sycl/test-e2e/Experimental/ipc_memory.cpp b/sycl/test-e2e/Experimental/ipc_memory.cpp index d8ef95c50264a..ba14e874baa9b 100644 --- a/sycl/test-e2e/Experimental/ipc_memory.cpp +++ b/sycl/test-e2e/Experimental/ipc_memory.cpp @@ -94,18 +94,14 @@ int consumer() { syclexp::ipc_memory::open(Handle, Q.get_context(), Q.get_device())); // Test the data already in the USM pointer. - // TODO: This is currently disabled for L0 due to a bug in the original data - // after opening an IPC handle. int Failures = 0; - if (Q.get_backend() != sycl::backend::ext_oneapi_level_zero) { - int Read[N] = {0}; - Q.copy(DataPtr, Read, N).wait(); - for (size_t I = 0; I < N; ++I) { - if (Read[I] != I) { - ++Failures; - std::cout << "Failed from consumer: Result at " << I - << " unexpected: " << Read[I] << " != " << I << std::endl; - } + int Read[N] = {0}; + Q.copy(DataPtr, Read, N).wait(); + for (size_t I = 0; I < N; ++I) { + if (Read[I] != I) { + ++Failures; + std::cout << "Failed from consumer: Result at " << I + << " unexpected: " << Read[I] << " != " << I << std::endl; } } From d1ba0defa4e755eda2e71ce4ad123de3f43a5ed5 Mon Sep 17 00:00:00 2001 From: "Larsen, Steffen" Date: Sun, 21 Sep 2025 23:35:24 -0700 Subject: [PATCH 12/38] Add put explicit internal release arg Signed-off-by: Larsen, Steffen --- unified-runtime/include/ur_api.h | 7 ++++++- unified-runtime/include/ur_ddi.h | 2 +- unified-runtime/include/ur_print.hpp | 5 +++++ .../scripts/core/exp-inter-process-communication.yml | 3 +++ unified-runtime/source/adapters/cuda/memory.cpp | 11 +++++++---- unified-runtime/source/adapters/hip/memory.cpp | 2 +- .../source/adapters/level_zero/memory.cpp | 11 +++++++---- .../adapters/level_zero/ur_interface_loader.hpp | 3 ++- .../source/adapters/level_zero/v2/memory.cpp | 11 +++++++---- unified-runtime/source/adapters/mock/ur_mockddi.cpp | 9 +++++++-- .../source/adapters/native_cpu/memory.cpp | 2 +- unified-runtime/source/adapters/offload/memory.cpp | 2 +- unified-runtime/source/adapters/opencl/memory.cpp | 2 +- .../source/loader/layers/tracing/ur_trcddi.cpp | 12 +++++++++--- .../source/loader/layers/validation/ur_valddi.cpp | 9 +++++++-- unified-runtime/source/loader/ur_ldrddi.cpp | 8 ++++++-- unified-runtime/source/loader/ur_libapi.cpp | 8 ++++++-- unified-runtime/source/ur_api.cpp | 6 +++++- 18 files changed, 82 insertions(+), 31 deletions(-) diff --git a/unified-runtime/include/ur_api.h b/unified-runtime/include/ur_api.h index 5602bc0b5d0e0..0c6b5552b2a8e 100644 --- a/unified-runtime/include/ur_api.h +++ b/unified-runtime/include/ur_api.h @@ -12414,7 +12414,11 @@ UR_APIEXPORT ur_result_t UR_APICALL urIPCPutMemHandleExp( /// [in] handle of the context object ur_context_handle_t hContext, /// [in] the IPC memory handle - ur_exp_ipc_mem_handle_t hIPCMem); + ur_exp_ipc_mem_handle_t hIPCMem, + /// [in] true if the backend resource should be released, false if the + /// backend resource will be released when freeing the corresponding + /// device USM memory + ur_bool_t putBackendResource); /////////////////////////////////////////////////////////////////////////////// /// @brief Opens an inter-process memory handle from raw data to get the @@ -15587,6 +15591,7 @@ typedef struct ur_ipc_get_mem_handle_exp_params_t { typedef struct ur_ipc_put_mem_handle_exp_params_t { ur_context_handle_t *phContext; ur_exp_ipc_mem_handle_t *phIPCMem; + ur_bool_t *pputBackendResource; } ur_ipc_put_mem_handle_exp_params_t; /////////////////////////////////////////////////////////////////////////////// diff --git a/unified-runtime/include/ur_ddi.h b/unified-runtime/include/ur_ddi.h index 035be44791ab7..ec400de8c758f 100644 --- a/unified-runtime/include/ur_ddi.h +++ b/unified-runtime/include/ur_ddi.h @@ -1795,7 +1795,7 @@ typedef ur_result_t(UR_APICALL *ur_pfnIPCGetMemHandleExp_t)( /////////////////////////////////////////////////////////////////////////////// /// @brief Function-pointer for urIPCPutMemHandleExp typedef ur_result_t(UR_APICALL *ur_pfnIPCPutMemHandleExp_t)( - ur_context_handle_t, ur_exp_ipc_mem_handle_t); + ur_context_handle_t, ur_exp_ipc_mem_handle_t, ur_bool_t); /////////////////////////////////////////////////////////////////////////////// /// @brief Function-pointer for urIPCOpenMemHandleExp diff --git a/unified-runtime/include/ur_print.hpp b/unified-runtime/include/ur_print.hpp index 73448963a1dc3..50b538e0adaaa 100644 --- a/unified-runtime/include/ur_print.hpp +++ b/unified-runtime/include/ur_print.hpp @@ -20332,6 +20332,11 @@ inline std::ostream &operator<<( ur::details::printPtr(os, *(params->phIPCMem)); + os << ", "; + os << ".putBackendResource = "; + + os << *(params->pputBackendResource); + return os; } diff --git a/unified-runtime/scripts/core/exp-inter-process-communication.yml b/unified-runtime/scripts/core/exp-inter-process-communication.yml index e5fb1691fe354..5ec212ca18414 100644 --- a/unified-runtime/scripts/core/exp-inter-process-communication.yml +++ b/unified-runtime/scripts/core/exp-inter-process-communication.yml @@ -64,6 +64,9 @@ params: - type: $x_exp_ipc_mem_handle_t name: hIPCMem desc: "[in] the IPC memory handle" + - type: $x_bool_t + name: putBackendResource + desc: "[in] true if the backend resource should be released, false if the backend resource will be released when freeing the corresponding device USM memory" returns: - $X_RESULT_ERROR_INVALID_CONTEXT - $X_RESULT_ERROR_INVALID_NULL_HANDLE: diff --git a/unified-runtime/source/adapters/cuda/memory.cpp b/unified-runtime/source/adapters/cuda/memory.cpp index 0461b553a4fb0..68442197144aa 100644 --- a/unified-runtime/source/adapters/cuda/memory.cpp +++ b/unified-runtime/source/adapters/cuda/memory.cpp @@ -610,10 +610,13 @@ UR_APIEXPORT ur_result_t UR_APICALL urIPCGetMemHandleExp( } UR_APIEXPORT ur_result_t UR_APICALL -urIPCPutMemHandleExp(ur_context_handle_t, ur_exp_ipc_mem_handle_t hIPCMem) { - auto umfRet = umfPutIPCHandle(hIPCMem->UMFHandle); - if (umfRet != UMF_RESULT_SUCCESS) - return UR_RESULT_ERROR_UNKNOWN; +urIPCPutMemHandleExp(ur_context_handle_t, ur_exp_ipc_mem_handle_t hIPCMem, + ur_bool_t putBackendResource) { + if (putBackendResource) { + auto umfRet = umfPutIPCHandle(hIPCMem->UMFHandle); + if (umfRet != UMF_RESULT_SUCCESS) + return UR_RESULT_ERROR_UNKNOWN; + } std::free(hIPCMem); return UR_RESULT_SUCCESS; } diff --git a/unified-runtime/source/adapters/hip/memory.cpp b/unified-runtime/source/adapters/hip/memory.cpp index f052fd2efc785..20ce56eed9297 100644 --- a/unified-runtime/source/adapters/hip/memory.cpp +++ b/unified-runtime/source/adapters/hip/memory.cpp @@ -647,7 +647,7 @@ urIPCGetMemHandleExp(ur_context_handle_t, void *, ur_exp_ipc_mem_handle_t *) { } UR_APIEXPORT ur_result_t UR_APICALL -urIPCPutMemHandleExp(ur_context_handle_t, ur_exp_ipc_mem_handle_t) { +urIPCPutMemHandleExp(ur_context_handle_t, ur_exp_ipc_mem_handle_t, ur_bool_t) { return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; } diff --git a/unified-runtime/source/adapters/level_zero/memory.cpp b/unified-runtime/source/adapters/level_zero/memory.cpp index 6c977dace0113..d5301b0d693a5 100644 --- a/unified-runtime/source/adapters/level_zero/memory.cpp +++ b/unified-runtime/source/adapters/level_zero/memory.cpp @@ -1971,10 +1971,13 @@ ur_result_t urIPCGetMemHandleExp(ur_context_handle_t, void *pMem, } ur_result_t urIPCPutMemHandleExp(ur_context_handle_t, - ur_exp_ipc_mem_handle_t hIPCMem) { - auto umfRet = umfPutIPCHandle(hIPCMem->UMFHandle); - if (umfRet != UMF_RESULT_SUCCESS) - return UR_RESULT_ERROR_UNKNOWN; + ur_exp_ipc_mem_handle_t hIPCMem, + ur_bool_t putBackendResource) { + if (putBackendResource) { + auto umfRet = umfPutIPCHandle(hIPCMem->UMFHandle); + if (umfRet != UMF_RESULT_SUCCESS) + return UR_RESULT_ERROR_UNKNOWN; + } std::free(hIPCMem); return UR_RESULT_SUCCESS; } diff --git a/unified-runtime/source/adapters/level_zero/ur_interface_loader.hpp b/unified-runtime/source/adapters/level_zero/ur_interface_loader.hpp index 0c7f6a9694be0..d6af4f2042b2f 100644 --- a/unified-runtime/source/adapters/level_zero/ur_interface_loader.hpp +++ b/unified-runtime/source/adapters/level_zero/ur_interface_loader.hpp @@ -771,7 +771,8 @@ ur_result_t urEnqueueTimestampRecordingExp( ur_result_t urIPCGetMemHandleExp(ur_context_handle_t hContext, void *pMem, ur_exp_ipc_mem_handle_t *phIPCMem); ur_result_t urIPCPutMemHandleExp(ur_context_handle_t hContext, - ur_exp_ipc_mem_handle_t hIPCMem); + ur_exp_ipc_mem_handle_t hIPCMem, + ur_bool_t putBackendResource); ur_result_t urIPCOpenMemHandleExp(ur_context_handle_t hContext, ur_device_handle_t hDevice, void *ipcMemHandleData, diff --git a/unified-runtime/source/adapters/level_zero/v2/memory.cpp b/unified-runtime/source/adapters/level_zero/v2/memory.cpp index 1794cfe0cffc3..910c06b197894 100644 --- a/unified-runtime/source/adapters/level_zero/v2/memory.cpp +++ b/unified-runtime/source/adapters/level_zero/v2/memory.cpp @@ -794,10 +794,13 @@ ur_result_t urIPCGetMemHandleExp(ur_context_handle_t, void *pMem, } ur_result_t urIPCPutMemHandleExp(ur_context_handle_t, - ur_exp_ipc_mem_handle_t hIPCMem) { - auto umfRet = umfPutIPCHandle(hIPCMem->UMFHandle); - if (umfRet != UMF_RESULT_SUCCESS) - return UR_RESULT_ERROR_UNKNOWN; + ur_exp_ipc_mem_handle_t hIPCMem, + ur_bool_t putBackendResource) { + if (putBackendResource) { + auto umfRet = umfPutIPCHandle(hIPCMem->UMFHandle); + if (umfRet != UMF_RESULT_SUCCESS) + return UR_RESULT_ERROR_UNKNOWN; + } std::free(hIPCMem); return UR_RESULT_SUCCESS; } diff --git a/unified-runtime/source/adapters/mock/ur_mockddi.cpp b/unified-runtime/source/adapters/mock/ur_mockddi.cpp index 80fd8024595e0..5314fdfdd6c93 100644 --- a/unified-runtime/source/adapters/mock/ur_mockddi.cpp +++ b/unified-runtime/source/adapters/mock/ur_mockddi.cpp @@ -11356,10 +11356,15 @@ __urdlllocal ur_result_t UR_APICALL urIPCPutMemHandleExp( /// [in] handle of the context object ur_context_handle_t hContext, /// [in] the IPC memory handle - ur_exp_ipc_mem_handle_t hIPCMem) try { + ur_exp_ipc_mem_handle_t hIPCMem, + /// [in] true if the backend resource should be released, false if the + /// backend resource will be released when freeing the corresponding + /// device USM memory + ur_bool_t putBackendResource) try { ur_result_t result = UR_RESULT_SUCCESS; - ur_ipc_put_mem_handle_exp_params_t params = {&hContext, &hIPCMem}; + ur_ipc_put_mem_handle_exp_params_t params = {&hContext, &hIPCMem, + &putBackendResource}; auto beforeCallback = reinterpret_cast( mock::getCallbacks().get_before_callback("urIPCPutMemHandleExp")); diff --git a/unified-runtime/source/adapters/native_cpu/memory.cpp b/unified-runtime/source/adapters/native_cpu/memory.cpp index f856b19843c78..957c97d1f820e 100644 --- a/unified-runtime/source/adapters/native_cpu/memory.cpp +++ b/unified-runtime/source/adapters/native_cpu/memory.cpp @@ -145,7 +145,7 @@ urIPCGetMemHandleExp(ur_context_handle_t, void *, ur_exp_ipc_mem_handle_t *) { } UR_APIEXPORT ur_result_t UR_APICALL -urIPCPutMemHandleExp(ur_context_handle_t, ur_exp_ipc_mem_handle_t) { +urIPCPutMemHandleExp(ur_context_handle_t, ur_exp_ipc_mem_handle_t, ur_bool_t) { return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; } diff --git a/unified-runtime/source/adapters/offload/memory.cpp b/unified-runtime/source/adapters/offload/memory.cpp index fdc9a1a1d4a65..55021c7d93043 100644 --- a/unified-runtime/source/adapters/offload/memory.cpp +++ b/unified-runtime/source/adapters/offload/memory.cpp @@ -149,7 +149,7 @@ urIPCGetMemHandleExp(ur_context_handle_t, void *, ur_exp_ipc_mem_handle_t *) { } UR_APIEXPORT ur_result_t UR_APICALL -urIPCPutMemHandleExp(ur_context_handle_t, ur_exp_ipc_mem_handle_t) { +urIPCPutMemHandleExp(ur_context_handle_t, ur_exp_ipc_mem_handle_t, ur_bool_t) { return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; } diff --git a/unified-runtime/source/adapters/opencl/memory.cpp b/unified-runtime/source/adapters/opencl/memory.cpp index 77d9c4a3316dd..0fe1192d588f0 100644 --- a/unified-runtime/source/adapters/opencl/memory.cpp +++ b/unified-runtime/source/adapters/opencl/memory.cpp @@ -586,7 +586,7 @@ urIPCGetMemHandleExp(ur_context_handle_t, void *, ur_exp_ipc_mem_handle_t *) { } UR_APIEXPORT ur_result_t UR_APICALL -urIPCPutMemHandleExp(ur_context_handle_t, ur_exp_ipc_mem_handle_t) { +urIPCPutMemHandleExp(ur_context_handle_t, ur_exp_ipc_mem_handle_t, ur_bool_t) { return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; } diff --git a/unified-runtime/source/loader/layers/tracing/ur_trcddi.cpp b/unified-runtime/source/loader/layers/tracing/ur_trcddi.cpp index 6e6929ddfca4e..51b4be076fdbd 100644 --- a/unified-runtime/source/loader/layers/tracing/ur_trcddi.cpp +++ b/unified-runtime/source/loader/layers/tracing/ur_trcddi.cpp @@ -9617,20 +9617,26 @@ __urdlllocal ur_result_t UR_APICALL urIPCPutMemHandleExp( /// [in] handle of the context object ur_context_handle_t hContext, /// [in] the IPC memory handle - ur_exp_ipc_mem_handle_t hIPCMem) { + ur_exp_ipc_mem_handle_t hIPCMem, + /// [in] true if the backend resource should be released, false if the + /// backend resource will be released when freeing the corresponding + /// device USM memory + ur_bool_t putBackendResource) { auto pfnPutMemHandleExp = getContext()->urDdiTable.IPCExp.pfnPutMemHandleExp; if (nullptr == pfnPutMemHandleExp) return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; - ur_ipc_put_mem_handle_exp_params_t params = {&hContext, &hIPCMem}; + ur_ipc_put_mem_handle_exp_params_t params = {&hContext, &hIPCMem, + &putBackendResource}; uint64_t instance = getContext()->notify_begin( UR_FUNCTION_IPC_PUT_MEM_HANDLE_EXP, "urIPCPutMemHandleExp", ¶ms); auto &logger = getContext()->logger; UR_LOG_L(logger, INFO, " ---> urIPCPutMemHandleExp\n"); - ur_result_t result = pfnPutMemHandleExp(hContext, hIPCMem); + ur_result_t result = + pfnPutMemHandleExp(hContext, hIPCMem, putBackendResource); getContext()->notify_end(UR_FUNCTION_IPC_PUT_MEM_HANDLE_EXP, "urIPCPutMemHandleExp", ¶ms, &result, instance); diff --git a/unified-runtime/source/loader/layers/validation/ur_valddi.cpp b/unified-runtime/source/loader/layers/validation/ur_valddi.cpp index e176955907a92..5f6af5a55f8a4 100644 --- a/unified-runtime/source/loader/layers/validation/ur_valddi.cpp +++ b/unified-runtime/source/loader/layers/validation/ur_valddi.cpp @@ -10376,7 +10376,11 @@ __urdlllocal ur_result_t UR_APICALL urIPCPutMemHandleExp( /// [in] handle of the context object ur_context_handle_t hContext, /// [in] the IPC memory handle - ur_exp_ipc_mem_handle_t hIPCMem) { + ur_exp_ipc_mem_handle_t hIPCMem, + /// [in] true if the backend resource should be released, false if the + /// backend resource will be released when freeing the corresponding + /// device USM memory + ur_bool_t putBackendResource) { auto pfnPutMemHandleExp = getContext()->urDdiTable.IPCExp.pfnPutMemHandleExp; if (nullptr == pfnPutMemHandleExp) { @@ -10396,7 +10400,8 @@ __urdlllocal ur_result_t UR_APICALL urIPCPutMemHandleExp( URLOG_CTX_INVALID_REFERENCE(hContext); } - ur_result_t result = pfnPutMemHandleExp(hContext, hIPCMem); + ur_result_t result = + pfnPutMemHandleExp(hContext, hIPCMem, putBackendResource); return result; } diff --git a/unified-runtime/source/loader/ur_ldrddi.cpp b/unified-runtime/source/loader/ur_ldrddi.cpp index 26b7b74e0f528..b6a7b812b3feb 100644 --- a/unified-runtime/source/loader/ur_ldrddi.cpp +++ b/unified-runtime/source/loader/ur_ldrddi.cpp @@ -5478,7 +5478,11 @@ __urdlllocal ur_result_t UR_APICALL urIPCPutMemHandleExp( /// [in] handle of the context object ur_context_handle_t hContext, /// [in] the IPC memory handle - ur_exp_ipc_mem_handle_t hIPCMem) { + ur_exp_ipc_mem_handle_t hIPCMem, + /// [in] true if the backend resource should be released, false if the + /// backend resource will be released when freeing the corresponding + /// device USM memory + ur_bool_t putBackendResource) { auto *dditable = *reinterpret_cast(hContext); @@ -5487,7 +5491,7 @@ __urdlllocal ur_result_t UR_APICALL urIPCPutMemHandleExp( return UR_RESULT_ERROR_UNINITIALIZED; // forward to device-platform - return pfnPutMemHandleExp(hContext, hIPCMem); + return pfnPutMemHandleExp(hContext, hIPCMem, putBackendResource); } /////////////////////////////////////////////////////////////////////////////// diff --git a/unified-runtime/source/loader/ur_libapi.cpp b/unified-runtime/source/loader/ur_libapi.cpp index 0d49101533af8..020283a575384 100644 --- a/unified-runtime/source/loader/ur_libapi.cpp +++ b/unified-runtime/source/loader/ur_libapi.cpp @@ -10048,13 +10048,17 @@ ur_result_t UR_APICALL urIPCPutMemHandleExp( /// [in] handle of the context object ur_context_handle_t hContext, /// [in] the IPC memory handle - ur_exp_ipc_mem_handle_t hIPCMem) try { + ur_exp_ipc_mem_handle_t hIPCMem, + /// [in] true if the backend resource should be released, false if the + /// backend resource will be released when freeing the corresponding + /// device USM memory + ur_bool_t putBackendResource) try { auto pfnPutMemHandleExp = ur_lib::getContext()->urDdiTable.IPCExp.pfnPutMemHandleExp; if (nullptr == pfnPutMemHandleExp) return UR_RESULT_ERROR_UNINITIALIZED; - return pfnPutMemHandleExp(hContext, hIPCMem); + return pfnPutMemHandleExp(hContext, hIPCMem, putBackendResource); } catch (...) { return exceptionToResult(std::current_exception()); } diff --git a/unified-runtime/source/ur_api.cpp b/unified-runtime/source/ur_api.cpp index 250e1af005851..212fd99b6d6b9 100644 --- a/unified-runtime/source/ur_api.cpp +++ b/unified-runtime/source/ur_api.cpp @@ -8749,7 +8749,11 @@ ur_result_t UR_APICALL urIPCPutMemHandleExp( /// [in] handle of the context object ur_context_handle_t hContext, /// [in] the IPC memory handle - ur_exp_ipc_mem_handle_t hIPCMem) { + ur_exp_ipc_mem_handle_t hIPCMem, + /// [in] true if the backend resource should be released, false if the + /// backend resource will be released when freeing the corresponding + /// device USM memory + ur_bool_t putBackendResource) { ur_result_t result = UR_RESULT_SUCCESS; return result; } From 4070634b288d3050236b844d423b92e0b99f080f Mon Sep 17 00:00:00 2001 From: "Larsen, Steffen" Date: Sun, 21 Sep 2025 23:35:35 -0700 Subject: [PATCH 13/38] Adjust sycl impl Signed-off-by: Larsen, Steffen --- ...neapi_inter_process_communication.asciidoc | 27 +++++++- .../ext/oneapi/experimental/ipc_memory.hpp | 2 + sycl/source/detail/ipc_memory_impl.hpp | 32 +++++++--- sycl/source/ipc_memory.cpp | 2 + sycl/test/abi/sycl_symbols_linux.dump | 1 + sycl/unittests/Extensions/IPC.cpp | 61 ++++++++++++++++++- 6 files changed, 112 insertions(+), 13 deletions(-) diff --git a/sycl/doc/extensions/experimental/sycl_ext_oneapi_inter_process_communication.asciidoc b/sycl/doc/extensions/experimental/sycl_ext_oneapi_inter_process_communication.asciidoc index aa285570187d4..46bcbd8833615 100644 --- a/sycl/doc/extensions/experimental/sycl_ext_oneapi_inter_process_communication.asciidoc +++ b/sycl/doc/extensions/experimental/sycl_ext_oneapi_inter_process_communication.asciidoc @@ -113,6 +113,8 @@ class ipc_memory { public: ipc_memory(void *ptr, sycl::context &ctx); + void put(); + static void *open(ipc_memory_handle_data_t ipc_memory_handle_data, const sycl::context &ctx, const sycl::device &dev); static void close(void *ptr, const sycl::context &ctx); @@ -141,6 +143,25 @@ device USM memory. If `ptr` is not pointing to device USM memory, the behaviors of this constructor and any resulting objects are undefined. +!==== +a! +[source] +---- +void put() +---- +!==== + +_Effects:_ Instructs the underlying IPC memory resources to be returned to +the backend. This is not required to be called before the `ipc_memory` object +dies. Freeing the device USM memory used when constructing this instance of +`ipc_memory` will return the underlying IPC memory resources. +Calling this function after `sycl::free()` has been called on the device USM +memory used when constructing this instance of `ipc_memory` will result in +undefined behavior. + +_Throws:_ A `sycl::exception` with `errc::invalid` if `ipc_memory::put()` has +previously been called on this instance of `ipc_memory`. + !==== a! [source] @@ -171,7 +192,6 @@ static void close(void *ptr, const sycl::context &ctx) _Effects:_ Closes a device USM pointer previously returned by a call to `ipc_memory::open()`. -Accessing `ptr` after a call to this function results in undefined behavior. !==== a! @@ -182,9 +202,12 @@ ipc_memory_handle_data_t get_handle_data() const !==== _Returns:_ The handle data of the `ipc_memory` object. -Accessing the handle data returned by this API after the `ipc_memory` object has +Utilizing the handle data returned by this API after the `ipc_memory` object has been destroyed results in undefined behavior. +_Throws:_ A `sycl::exception` with `errc::invalid` if `ipc_memory::put()` has +previously been called on this instance of `ipc_memory`. + !==== a! [source] diff --git a/sycl/include/sycl/ext/oneapi/experimental/ipc_memory.hpp b/sycl/include/sycl/ext/oneapi/experimental/ipc_memory.hpp index dbeb1aa9a6236..622d8b2fa0ac1 100644 --- a/sycl/include/sycl/ext/oneapi/experimental/ipc_memory.hpp +++ b/sycl/include/sycl/ext/oneapi/experimental/ipc_memory.hpp @@ -33,6 +33,8 @@ class __SYCL_EXPORT ipc_memory public: ipc_memory(void *Ptr, const sycl::context &Ctx); + void put(); + static void *open(ipc_memory_handle_data_t IPCMemoryHandleData, const sycl::context &Ctx, const sycl::device &Dev); static void close(void *Ptr, const sycl::context &Ctx); diff --git a/sycl/source/detail/ipc_memory_impl.hpp b/sycl/source/detail/ipc_memory_impl.hpp index b96cf2d3ce8b4..672093474c0b4 100644 --- a/sycl/source/detail/ipc_memory_impl.hpp +++ b/sycl/source/detail/ipc_memory_impl.hpp @@ -27,9 +27,8 @@ class ipc_memory_impl { public: ipc_memory_impl(void *Ptr, const sycl::context &Ctx, private_tag) : MContext{getSyclObjImpl(Ctx)}, MPtr{Ptr} { - adapter_impl &Adapter = MContext->getAdapter(); - Adapter.call(MContext->getHandleRef(), Ptr, - &MUrHandle); + MContext->getAdapter().call( + MContext->getHandleRef(), Ptr, &MUrHandle.emplace(nullptr)); } ipc_memory_impl(const ipc_memory_impl &) = delete; @@ -37,14 +36,23 @@ class ipc_memory_impl { ~ipc_memory_impl() { try { - adapter_impl &Adapter = MContext->getAdapter(); - Adapter.call_nocheck( - MContext->getHandleRef(), MUrHandle); + if (MUrHandle) + MContext->getAdapter().call_nocheck( + MContext->getHandleRef(), *MUrHandle, /*putBackendResource=*/false); } catch (std::exception &e) { __SYCL_REPORT_EXCEPTION_TO_STREAM("exception in ~ipc_memory_impl", e); } } + void put() { + if (!MUrHandle) + throw sycl::exception(make_error_code(errc::invalid), + "IPC memory object has already been put back."); + MContext->getAdapter().call_nocheck( + MContext->getHandleRef(), *MUrHandle, /*putBackendResource=*/true); + MUrHandle = std::nullopt; + } + ipc_memory_impl &operator=(const ipc_memory_impl &) = delete; ipc_memory_impl &operator=(ipc_memory_impl &&) = default; @@ -56,11 +64,15 @@ class ipc_memory_impl { sycl::ext::oneapi::experimental::ipc_memory_handle_data_t get_handle_data() const { - adapter_impl &Adapter = MContext->getAdapter(); + if (!MUrHandle) + throw sycl::exception(make_error_code(errc::invalid), + "IPC memory object has been put back and the " + "handle data cannot be accessed."); + void *HandleDataPtr = nullptr; size_t HandleDataSize = 0; - Adapter.call( - MContext->getHandleRef(), MUrHandle, &HandleDataPtr, &HandleDataSize); + MContext->getAdapter().call( + MContext->getHandleRef(), *MUrHandle, &HandleDataPtr, &HandleDataSize); return sycl::span{ reinterpret_cast(HandleDataPtr), HandleDataSize}; } @@ -70,7 +82,7 @@ class ipc_memory_impl { private: std::shared_ptr MContext; void *MPtr = nullptr; - ur_exp_ipc_mem_handle_t MUrHandle = nullptr; + std::optional MUrHandle = std::nullopt; }; } // namespace detail diff --git a/sycl/source/ipc_memory.cpp b/sycl/source/ipc_memory.cpp index d6a8a81ba5fd5..c90115f57b8c1 100644 --- a/sycl/source/ipc_memory.cpp +++ b/sycl/source/ipc_memory.cpp @@ -19,6 +19,8 @@ namespace ext::oneapi::experimental { ipc_memory::ipc_memory(void *Ptr, const sycl::context &Ctx) : impl(detail::ipc_memory_impl::create(Ptr, Ctx)) {} +void ipc_memory::put() { impl->put(); } + void *ipc_memory::open(ipc_memory_handle_data_t IPCMemoryHandleData, const sycl::context &Ctx, const sycl::device &Dev) { auto CtxImpl = sycl::detail::getSyclObjImpl(Ctx); diff --git a/sycl/test/abi/sycl_symbols_linux.dump b/sycl/test/abi/sycl_symbols_linux.dump index c64a07435c846..0d19482cee2f4 100644 --- a/sycl/test/abi/sycl_symbols_linux.dump +++ b/sycl/test/abi/sycl_symbols_linux.dump @@ -2991,6 +2991,7 @@ _ZN4sycl3_V13ext5intel12experimental9pipe_base18get_pipe_name_implEPKv _ZN4sycl3_V13ext6oneapi10level_zero6detail11make_deviceERKNS0_8platformEm _ZN4sycl3_V13ext6oneapi12experimental10async_freeERKNS0_5queueEPvRKNS0_6detail13code_locationE _ZN4sycl3_V13ext6oneapi12experimental10async_freeERNS0_7handlerEPv +_ZN4sycl3_V13ext6oneapi12experimental10ipc_memory3putEv _ZN4sycl3_V13ext6oneapi12experimental10ipc_memory4openENS0_4spanIcLm18446744073709551615EEERKNS0_7contextERKNS0_6deviceE _ZN4sycl3_V13ext6oneapi12experimental10ipc_memory5closeEPvRKNS0_7contextE _ZN4sycl3_V13ext6oneapi12experimental10ipc_memoryC1EPvRKNS0_7contextE diff --git a/sycl/unittests/Extensions/IPC.cpp b/sycl/unittests/Extensions/IPC.cpp index 6eff9c9429973..2b030af44d1c4 100644 --- a/sycl/unittests/Extensions/IPC.cpp +++ b/sycl/unittests/Extensions/IPC.cpp @@ -42,10 +42,12 @@ ur_result_t replace_urIPCGetMemHandleExp(void *pParams) { return UR_RESULT_SUCCESS; } +thread_local ur_bool_t urIPCPutMemHandleExp_explicit = false; ur_result_t replace_urIPCPutMemHandleExp(void *pParams) { ++urIPCPutMemHandleExp_counter; auto params = *static_cast(pParams); EXPECT_EQ(*params.phIPCMem, DummyMemHandle); + EXPECT_EQ(*params.pputBackendResource, urIPCPutMemHandleExp_explicit); return UR_RESULT_SUCCESS; } @@ -103,7 +105,9 @@ class IPCTests : public ::testing::Test { sycl::context Ctxt; }; -TEST_F(IPCTests, IPCGetPut) { +TEST_F(IPCTests, IPCGetPutImplicit) { + urIPCPutMemHandleExp_explicit = false; + { syclexp::ipc_memory IPCMem{DummyPtr, Ctxt}; @@ -136,6 +140,61 @@ TEST_F(IPCTests, IPCGetPut) { EXPECT_EQ(urIPCGetMemHandleDataExp_counter, 1); } +TEST_F(IPCTests, IPCGetPutExplicit) { + urIPCPutMemHandleExp_explicit = true; + + { + syclexp::ipc_memory IPCMem{DummyPtr, Ctxt}; + + // Creating the IPC memory from a pointer should only call "get". + EXPECT_EQ(urIPCGetMemHandleExp_counter, 1); + EXPECT_EQ(urIPCPutMemHandleExp_counter, 0); + EXPECT_EQ(urIPCOpenMemHandleExp_counter, 0); + EXPECT_EQ(urIPCCloseMemHandleExp_counter, 0); + EXPECT_EQ(urIPCGetMemHandleDataExp_counter, 0); + + IPCMem.put(); + + // Calling "put" explicitly should call the UR function. + EXPECT_EQ(urIPCGetMemHandleExp_counter, 1); + EXPECT_EQ(urIPCPutMemHandleExp_counter, 1); + EXPECT_EQ(urIPCOpenMemHandleExp_counter, 0); + EXPECT_EQ(urIPCCloseMemHandleExp_counter, 0); + EXPECT_EQ(urIPCGetMemHandleDataExp_counter, 0); + + // calling put() again should now throw. + try { + IPCMem.put(); + FAIL(); + } catch (sycl::exception &E) { + EXPECT_EQ(E.code(), sycl::make_error_code(sycl::errc::invalid)); + } + + // get_handle_data() should now throw. + try { + IPCMem.get_handle_data(); + FAIL(); + } catch (sycl::exception &E) { + EXPECT_EQ(E.code(), sycl::make_error_code(sycl::errc::invalid)); + } + + // After exception cases, no changes should have happened to the counters. + EXPECT_EQ(urIPCGetMemHandleExp_counter, 1); + EXPECT_EQ(urIPCPutMemHandleExp_counter, 1); + EXPECT_EQ(urIPCOpenMemHandleExp_counter, 0); + EXPECT_EQ(urIPCCloseMemHandleExp_counter, 0); + EXPECT_EQ(urIPCGetMemHandleDataExp_counter, 0); + } + + // When the IPC memory object dies, put has already been called so "put" + // should not be called again. + EXPECT_EQ(urIPCGetMemHandleExp_counter, 1); + EXPECT_EQ(urIPCPutMemHandleExp_counter, 1); + EXPECT_EQ(urIPCOpenMemHandleExp_counter, 0); + EXPECT_EQ(urIPCCloseMemHandleExp_counter, 0); + EXPECT_EQ(urIPCGetMemHandleDataExp_counter, 0); +} + TEST_F(IPCTests, IPCOpenClose) { syclexp::ipc_memory_handle_data_t HandleData{DummyHandleData, DummyHandleDataSize}; From db03d7b0dd9cac21d193e506a7fcff93f62c92e5 Mon Sep 17 00:00:00 2001 From: "Larsen, Steffen" Date: Mon, 22 Sep 2025 00:25:08 -0700 Subject: [PATCH 14/38] Remove unused param Signed-off-by: Larsen, Steffen --- unified-runtime/source/adapters/cuda/memory.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/unified-runtime/source/adapters/cuda/memory.cpp b/unified-runtime/source/adapters/cuda/memory.cpp index 68442197144aa..07436425d10d2 100644 --- a/unified-runtime/source/adapters/cuda/memory.cpp +++ b/unified-runtime/source/adapters/cuda/memory.cpp @@ -622,8 +622,8 @@ urIPCPutMemHandleExp(ur_context_handle_t, ur_exp_ipc_mem_handle_t hIPCMem, } UR_APIEXPORT ur_result_t UR_APICALL urIPCOpenMemHandleExp( - ur_context_handle_t hContext, ur_device_handle_t hDevice, - void *pIPCMemHandleData, size_t ipcMemHandleDataSize, void **ppMem) { + ur_context_handle_t, ur_device_handle_t hDevice, void *pIPCMemHandleData, + size_t ipcMemHandleDataSize, void **ppMem) { umf_memory_pool_handle_t umfPool = hDevice->MemoryPoolDevice; size_t umfHandleSize = 0; From 00756947d1d82cbc255f50223926d9f54b4ef0c8 Mon Sep 17 00:00:00 2001 From: "Larsen, Steffen" Date: Mon, 22 Sep 2025 00:25:57 -0700 Subject: [PATCH 15/38] Add missing Windows symbol Signed-off-by: Larsen, Steffen --- sycl/test/abi/sycl_symbols_windows.dump | 1 + 1 file changed, 1 insertion(+) diff --git a/sycl/test/abi/sycl_symbols_windows.dump b/sycl/test/abi/sycl_symbols_windows.dump index 277a21640101e..c379eff83cc9e 100644 --- a/sycl/test/abi/sycl_symbols_windows.dump +++ b/sycl/test/abi/sycl_symbols_windows.dump @@ -4385,6 +4385,7 @@ ?print_graph@modifiable_command_graph@detail@experimental@oneapi@ext@_V1@sycl@@IEBAXVstring_view@267@_N@Z ?print_graph@modifiable_command_graph@detail@experimental@oneapi@ext@_V1@sycl@@QEBAXV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@_N@Z ?processArg@handler@_V1@sycl@@AEAAXPEAXAEBW4kernel_param_kind_t@detail@23@H_KAEA_K_N4@Z +?put@ipc_memory@experimental@oneapi@ext@_V1@sycl@@QEAAXXZ ?query@tls_code_loc_t@detail@_V1@sycl@@QEAAAEBUcode_location@234@XZ ?reduComputeWGSize@detail@_V1@sycl@@YA_K_K0AEA_K@Z ?reduGetMaxNumConcurrentWorkGroups@detail@_V1@sycl@@YAIAEAVhandler@23@@Z From 7a332b98162e84fea6f6bdb3aa205006b913873e Mon Sep 17 00:00:00 2001 From: "Larsen, Steffen" Date: Wed, 24 Sep 2025 06:46:44 -0700 Subject: [PATCH 16/38] Add missing newline Signed-off-by: Larsen, Steffen --- sycl/source/detail/ipc_memory_impl.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sycl/source/detail/ipc_memory_impl.hpp b/sycl/source/detail/ipc_memory_impl.hpp index 672093474c0b4..69b13d8df4ff3 100644 --- a/sycl/source/detail/ipc_memory_impl.hpp +++ b/sycl/source/detail/ipc_memory_impl.hpp @@ -87,4 +87,4 @@ class ipc_memory_impl { } // namespace detail } // namespace _V1 -} // namespace sycl \ No newline at end of file +} // namespace sycl From acf286f74a5bddccb137c9d0813cbde07c7d4569 Mon Sep 17 00:00:00 2001 From: "Larsen, Steffen" Date: Mon, 6 Oct 2025 00:18:21 -0700 Subject: [PATCH 17/38] Change IPC API (SYCL) Signed-off-by: Larsen, Steffen --- ...neapi_inter_process_communication.asciidoc | 107 ++++--------- .../ext/oneapi/experimental/ipc_memory.hpp | 42 +---- sycl/source/detail/ipc_memory_impl.hpp | 90 ----------- sycl/source/ipc_memory.cpp | 43 +++-- sycl/test-e2e/Experimental/ipc_memory.cpp | 6 +- sycl/test/abi/sycl_symbols_linux.dump | 9 +- sycl/unittests/Extensions/IPC.cpp | 150 +++++------------- 7 files changed, 112 insertions(+), 335 deletions(-) delete mode 100644 sycl/source/detail/ipc_memory_impl.hpp diff --git a/sycl/doc/extensions/experimental/sycl_ext_oneapi_inter_process_communication.asciidoc b/sycl/doc/extensions/experimental/sycl_ext_oneapi_inter_process_communication.asciidoc index 46bcbd8833615..5d4ad94898194 100644 --- a/sycl/doc/extensions/experimental/sycl_ext_oneapi_inter_process_communication.asciidoc +++ b/sycl/doc/extensions/experimental/sycl_ext_oneapi_inter_process_communication.asciidoc @@ -66,9 +66,9 @@ when the kernel is submitted to the queue. This extension adds the ability for SYCL programs to share device USM memory allocations between processes. This is done by the allocating process creating -a new `ipc_memory` object and transferring the "handle data" to the other -processes. The other processes can use the handle data to recreate the -`ipc_memory` object and get a pointer to the corresponding device USM memory. +a new IPC memory handle through the new free frunctions and transferring the +returned handle data to the other processes. The other processes can use the +handle data to retrieve the corresponding device USM memory. == Specification @@ -83,10 +83,6 @@ the implementation supports this feature, or applications can test the macro's value to determine which of the extension's features the implementation supports. -_And follow the text with a table like this *unless the extension is -"experimental"*. Note that your table may have more than one row if it -has multiple versions._ - [%header,cols="1,5"] |=== |Value @@ -100,29 +96,22 @@ has multiple versions._ === Inter-process communicable memory -This extension adds the new `ipc_memory` class. This new class adheres to the -common reference semantics described in -https://registry.khronos.org/SYCL/specs/sycl-2020/html/sycl-2020.html#sec:reference-semantics[Section 4.5.2.] -in the SYCL 2020 specification. +This extension adds new free functions under the `ipc_memory` experimental +namespace. ``` -namespace sycl::ext::oneapi::experimental { -using ipc_memory_handle_data_t = span; +namespace sycl::ext::oneapi::experimental::ipc_memory { -class ipc_memory { -public: - ipc_memory(void *ptr, sycl::context &ctx); +using handle_data_t = std::vector; - void put(); +handle_data_t get(void *ptr, const sycl::context &ctx); - static void *open(ipc_memory_handle_data_t ipc_memory_handle_data, - const sycl::context &ctx, const sycl::device &dev); - static void close(void *ptr, const sycl::context &ctx); +void put(handle_data_t &handle_data, const sycl::context &ctx); - ipc_memory_handle_data_t get_handle_data() const; +static void *open(handle_data_t handle_data, const sycl::context &ctx, + const sycl::device &dev); - void *get_ptr() const; -}; +static void close(void *ptr, const sycl::context &ctx); } ``` @@ -134,53 +123,45 @@ a| a! [source] ---- -ipc_memory(void *ptr, const sycl::context &ctx) +get(void *ptr, const sycl::context &ctx) ---- !==== -_Effects:_ Constructs an IPC memory object in `ctx` from a pointer `ptr` to -device USM memory. -If `ptr` is not pointing to device USM memory, the behaviors of this constructor -and any resulting objects are undefined. +_Returns:_ A `handle_data_t` object containing the data of the IPC memory handle +in `ctx` from a pointer `ptr` to device USM memory. +Calling this function with a `ptr` that does not point to device USM memory, the +behaviors is undefined. !==== a! [source] ---- -void put() +void put(handle_data_t &handle_data, const sycl::context &ctx) ---- !==== _Effects:_ Instructs the underlying IPC memory resources to be returned to -the backend. This is not required to be called before the `ipc_memory` object -dies. Freeing the device USM memory used when constructing this instance of -`ipc_memory` will return the underlying IPC memory resources. +the backend. Freeing the device USM memory used when the handle data was created +through a call to `get()` will have the same effect as calling this function, +so a direct call to this function is not strictly required. Calling this function after `sycl::free()` has been called on the device USM -memory used when constructing this instance of `ipc_memory` will result in -undefined behavior. - -_Throws:_ A `sycl::exception` with `errc::invalid` if `ipc_memory::put()` has -previously been called on this instance of `ipc_memory`. +memory used when the handle data was created through a call to `get()` will +result in undefined behavior. !==== a! [source] ---- -static void *open(ipc_memory_handle_data_t ipc_memory_handle_data, - const sycl::context &ctx, const sycl::device &dev) +static void *open(handle_data_t &handle_data, const sycl::context &ctx, + const sycl::device &dev) ---- !==== _Effects:_ Returns a pointer to the same device USM memory as the device USM -memory associated with the `ipc_memory` object that the handle data originated -from. -The `ipc_memory` object that the handle data originated from is allowed to be -from another process on the host system. -If the `ipc_memory` object that the handle data originated from has been -destroyed, the behaviors of this constructor and any resulting objects are -undefined. -If the device USM memory the original `ipc_memory` object was created with was -not originally allocated on `dev`, the behaviors of this function is undefined. +memory associated with `handle_data`. +The handle data is allowed to be from another process on the host system. +If the handle data has been destroyed, calling this function results in +undefined behavior. !==== a! @@ -191,35 +172,7 @@ static void close(void *ptr, const sycl::context &ctx) !==== _Effects:_ Closes a device USM pointer previously returned by a call to -`ipc_memory::open()`. - -!==== -a! -[source] ----- -ipc_memory_handle_data_t get_handle_data() const ----- -!==== - -_Returns:_ The handle data of the `ipc_memory` object. -Utilizing the handle data returned by this API after the `ipc_memory` object has -been destroyed results in undefined behavior. - -_Throws:_ A `sycl::exception` with `errc::invalid` if `ipc_memory::put()` has -previously been called on this instance of `ipc_memory`. - -!==== -a! -[source] ----- -void *get_ptr() const ----- -!==== - -_Returns:_ A pointer to device USM memory corresponding to the pointer used to -construct the original `ipc_memory` object. -Accessing the pointer returned by this API after the `ipc_memory` object has -been destroyed results in undefined behavior. +`open()`. |==== diff --git a/sycl/include/sycl/ext/oneapi/experimental/ipc_memory.hpp b/sycl/include/sycl/ext/oneapi/experimental/ipc_memory.hpp index 622d8b2fa0ac1..0e37597047116 100644 --- a/sycl/include/sycl/ext/oneapi/experimental/ipc_memory.hpp +++ b/sycl/include/sycl/ext/oneapi/experimental/ipc_memory.hpp @@ -21,45 +21,19 @@ inline namespace _V1 { class context; class device; -namespace detail { -class ipc_memory_impl; -} +namespace ext::oneapi::experimental::ipc_memory { -namespace ext::oneapi::experimental { -using ipc_memory_handle_data_t = span; +using handle_data_t = std::vector; -class __SYCL_EXPORT ipc_memory - : public sycl::detail::OwnerLessBase { -public: - ipc_memory(void *Ptr, const sycl::context &Ctx); +__SYCL_EXPORT handle_data_t get(void *Ptr, const sycl::context &Ctx); - void put(); +__SYCL_EXPORT void put(handle_data_t &HandleData, const sycl::context &Ctx); - static void *open(ipc_memory_handle_data_t IPCMemoryHandleData, - const sycl::context &Ctx, const sycl::device &Dev); - static void close(void *Ptr, const sycl::context &Ctx); +__SYCL_EXPORT void *open(handle_data_t &HandleData, const sycl::context &Ctx, + const sycl::device &Dev); - ipc_memory_handle_data_t get_handle_data() const; +__SYCL_EXPORT void close(void *Ptr, const sycl::context &Ctx); - void *get_ptr() const; - -private: - ipc_memory(std::shared_ptr IPCMemImpl) - : impl{IPCMemImpl} {} - - std::shared_ptr impl; - - template - friend const decltype(Obj::impl) & - sycl::detail::getSyclObjImpl(const Obj &SyclObject); - - template - friend T sycl::detail::createSyclObjFromImpl( - std::add_rvalue_reference_t ImplObj); - template - friend T sycl::detail::createSyclObjFromImpl( - std::add_lvalue_reference_t ImplObj); -}; -} // namespace ext::oneapi::experimental +} // namespace ext::oneapi::experimental::ipc_memory } // namespace _V1 } // namespace sycl diff --git a/sycl/source/detail/ipc_memory_impl.hpp b/sycl/source/detail/ipc_memory_impl.hpp deleted file mode 100644 index 69b13d8df4ff3..0000000000000 --- a/sycl/source/detail/ipc_memory_impl.hpp +++ /dev/null @@ -1,90 +0,0 @@ -//==-------- ipc_memory_impl.hpp --- SYCL ipc_memory implementation --------==// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#pragma once - -#include -#include -#include -#include - -#include - -namespace sycl { -inline namespace _V1 { -namespace detail { - -class ipc_memory_impl { - struct private_tag { - explicit private_tag() = default; - }; - -public: - ipc_memory_impl(void *Ptr, const sycl::context &Ctx, private_tag) - : MContext{getSyclObjImpl(Ctx)}, MPtr{Ptr} { - MContext->getAdapter().call( - MContext->getHandleRef(), Ptr, &MUrHandle.emplace(nullptr)); - } - - ipc_memory_impl(const ipc_memory_impl &) = delete; - ipc_memory_impl(ipc_memory_impl &&) = default; - - ~ipc_memory_impl() { - try { - if (MUrHandle) - MContext->getAdapter().call_nocheck( - MContext->getHandleRef(), *MUrHandle, /*putBackendResource=*/false); - } catch (std::exception &e) { - __SYCL_REPORT_EXCEPTION_TO_STREAM("exception in ~ipc_memory_impl", e); - } - } - - void put() { - if (!MUrHandle) - throw sycl::exception(make_error_code(errc::invalid), - "IPC memory object has already been put back."); - MContext->getAdapter().call_nocheck( - MContext->getHandleRef(), *MUrHandle, /*putBackendResource=*/true); - MUrHandle = std::nullopt; - } - - ipc_memory_impl &operator=(const ipc_memory_impl &) = delete; - ipc_memory_impl &operator=(ipc_memory_impl &&) = default; - - template - static std::shared_ptr create(Ts &&...args) { - return std::make_shared(std::forward(args)..., - private_tag{}); - } - - sycl::ext::oneapi::experimental::ipc_memory_handle_data_t - get_handle_data() const { - if (!MUrHandle) - throw sycl::exception(make_error_code(errc::invalid), - "IPC memory object has been put back and the " - "handle data cannot be accessed."); - - void *HandleDataPtr = nullptr; - size_t HandleDataSize = 0; - MContext->getAdapter().call( - MContext->getHandleRef(), *MUrHandle, &HandleDataPtr, &HandleDataSize); - return sycl::span{ - reinterpret_cast(HandleDataPtr), HandleDataSize}; - } - - void *get_ptr() const { return MPtr; } - -private: - std::shared_ptr MContext; - void *MPtr = nullptr; - std::optional MUrHandle = std::nullopt; -}; - -} // namespace detail -} // namespace _V1 -} // namespace sycl diff --git a/sycl/source/ipc_memory.cpp b/sycl/source/ipc_memory.cpp index c90115f57b8c1..0268307a3ddd9 100644 --- a/sycl/source/ipc_memory.cpp +++ b/sycl/source/ipc_memory.cpp @@ -8,21 +8,36 @@ #include #include -#include #include #include namespace sycl { inline namespace _V1 { -namespace ext::oneapi::experimental { +namespace ext::oneapi::experimental::ipc_memory { -ipc_memory::ipc_memory(void *Ptr, const sycl::context &Ctx) - : impl(detail::ipc_memory_impl::create(Ptr, Ctx)) {} +__SYCL_EXPORT handle_data_t get(void *Ptr, const sycl::context &Ctx) { + auto CtxImpl = sycl::detail::getSyclObjImpl(Ctx); + sycl::detail::adapter_impl &Adapter = CtxImpl->getAdapter(); + + size_t HandleSize = 0; + Adapter.call( + CtxImpl->getHandleRef(), Ptr, nullptr, &HandleSize); -void ipc_memory::put() { impl->put(); } + handle_data_t Res(HandleSize); + Adapter.call( + CtxImpl->getHandleRef(), Ptr, Res.data(), nullptr); + return Res; +} -void *ipc_memory::open(ipc_memory_handle_data_t IPCMemoryHandleData, - const sycl::context &Ctx, const sycl::device &Dev) { +__SYCL_EXPORT void put(handle_data_t &HandleData, const sycl::context &Ctx) { + auto CtxImpl = sycl::detail::getSyclObjImpl(Ctx); + sycl::detail::adapter_impl &Adapter = CtxImpl->getAdapter(); + Adapter.call( + CtxImpl->getHandleRef(), HandleData.data()); +} + +__SYCL_EXPORT void *open(handle_data_t &HandleData, const sycl::context &Ctx, + const sycl::device &Dev) { auto CtxImpl = sycl::detail::getSyclObjImpl(Ctx); sycl::detail::adapter_impl &Adapter = CtxImpl->getAdapter(); @@ -30,28 +45,22 @@ void *ipc_memory::open(ipc_memory_handle_data_t IPCMemoryHandleData, ur_result_t UrRes = Adapter.call_nocheck( CtxImpl->getHandleRef(), getSyclObjImpl(Dev)->getHandleRef(), - IPCMemoryHandleData.data(), IPCMemoryHandleData.size(), &Ptr); + HandleData.data(), HandleData.size(), &Ptr); if (UrRes == UR_RESULT_ERROR_INVALID_VALUE) throw sycl::exception(sycl::make_error_code(errc::invalid), - "IPCMemoryHandleData data size does not correspond " + "HandleData data size does not correspond " "to the target platform's IPC memory handle size."); Adapter.checkUrResult(UrRes); return Ptr; } -void ipc_memory::close(void *Ptr, const sycl::context &Ctx) { +__SYCL_EXPORT void close(void *Ptr, const sycl::context &Ctx) { auto CtxImpl = sycl::detail::getSyclObjImpl(Ctx); sycl::detail::adapter_impl &Adapter = CtxImpl->getAdapter(); Adapter.call( CtxImpl->getHandleRef(), Ptr); } -ipc_memory_handle_data_t ipc_memory::get_handle_data() const { - return impl->get_handle_data(); -} - -void *ipc_memory::get_ptr() const { return impl->get_ptr(); } - -} // namespace ext::oneapi::experimental +} // namespace ext::oneapi::experimental::ipc_memory } // namespace _V1 } // namespace sycl diff --git a/sycl/test-e2e/Experimental/ipc_memory.cpp b/sycl/test-e2e/Experimental/ipc_memory.cpp index ba14e874baa9b..eed4c8f99628e 100644 --- a/sycl/test-e2e/Experimental/ipc_memory.cpp +++ b/sycl/test-e2e/Experimental/ipc_memory.cpp @@ -46,12 +46,10 @@ int spawner(int argc, char *argv[]) { }).wait(); { - syclexp::ipc_memory IPCMem{DataPtr, Q.get_context()}; - assert(IPCMem.get_ptr() == DataPtr); - // Write handle data to file. { - syclexp::ipc_memory_handle_data_t HandleData = IPCMem.get_handle_data(); + syclexp::ipc_memory::handle_data_t HandleData = + syclexp::ipc_memory.get(DataPtr, Q.get_context()); size_t HandleDataSize = HandleData.size(); std::fstream FS(CommsFile, std::ios_base::out | std::ios_base::binary); FS.write(reinterpret_cast(&HandleDataSize), sizeof(size_t)); diff --git a/sycl/test/abi/sycl_symbols_linux.dump b/sycl/test/abi/sycl_symbols_linux.dump index 62567e79579e0..01ca3fc0d9401 100644 --- a/sycl/test/abi/sycl_symbols_linux.dump +++ b/sycl/test/abi/sycl_symbols_linux.dump @@ -2991,11 +2991,10 @@ _ZN4sycl3_V13ext5intel12experimental9pipe_base18get_pipe_name_implEPKv _ZN4sycl3_V13ext6oneapi10level_zero6detail11make_deviceERKNS0_8platformEm _ZN4sycl3_V13ext6oneapi12experimental10async_freeERKNS0_5queueEPvRKNS0_6detail13code_locationE _ZN4sycl3_V13ext6oneapi12experimental10async_freeERNS0_7handlerEPv -_ZN4sycl3_V13ext6oneapi12experimental10ipc_memory3putEv -_ZN4sycl3_V13ext6oneapi12experimental10ipc_memory4openENS0_4spanIcLm18446744073709551615EEERKNS0_7contextERKNS0_6deviceE +_ZN4sycl3_V13ext6oneapi12experimental10ipc_memory3getEPvRKNS0_7contextE +_ZN4sycl3_V13ext6oneapi12experimental10ipc_memory3putERSt6vectorIcSaIcEERKNS0_7contextE +_ZN4sycl3_V13ext6oneapi12experimental10ipc_memory4openERSt6vectorIcSaIcEERKNS0_7contextERKNS0_6deviceE _ZN4sycl3_V13ext6oneapi12experimental10ipc_memory5closeEPvRKNS0_7contextE -_ZN4sycl3_V13ext6oneapi12experimental10ipc_memoryC1EPvRKNS0_7contextE -_ZN4sycl3_V13ext6oneapi12experimental10ipc_memoryC2EPvRKNS0_7contextE _ZN4sycl3_V13ext6oneapi12experimental10mem_adviseENS0_5queueEPvmiRKNS0_6detail13code_locationE _ZN4sycl3_V13ext6oneapi12experimental11memory_pool21increase_threshold_toEm _ZN4sycl3_V13ext6oneapi12experimental11memory_poolC1ERKNS0_7contextERKNS0_6deviceENS0_3usm5allocENS4_15pool_propertiesE @@ -3700,8 +3699,6 @@ _ZNK4sycl3_V114interop_handle22ext_codeplay_has_graphEv _ZNK4sycl3_V115device_selector13select_deviceEv _ZNK4sycl3_V116default_selectorclERKNS0_6deviceE _ZNK4sycl3_V120accelerator_selectorclERKNS0_6deviceE -_ZNK4sycl3_V13ext6oneapi12experimental10ipc_memory7get_ptrEv -_ZNK4sycl3_V13ext6oneapi12experimental10ipc_memory15get_handle_dataEv _ZNK4sycl3_V13ext6oneapi12experimental11memory_pool10get_deviceEv _ZNK4sycl3_V13ext6oneapi12experimental11memory_pool11get_contextEv _ZNK4sycl3_V13ext6oneapi12experimental11memory_pool13get_thresholdEv diff --git a/sycl/unittests/Extensions/IPC.cpp b/sycl/unittests/Extensions/IPC.cpp index 2b030af44d1c4..faa5fad9fd0c8 100644 --- a/sycl/unittests/Extensions/IPC.cpp +++ b/sycl/unittests/Extensions/IPC.cpp @@ -18,12 +18,8 @@ namespace syclexp = sycl::ext::oneapi::experimental; namespace { -int DummyInt1 = 42; -void *DummyPtr = &DummyInt1; - -int DummyInt2 = 24; -ur_exp_ipc_mem_handle_t DummyMemHandle = - reinterpret_cast(&DummyInt2); +int DummyInt = 42; +void *DummyPtr = &DummyInt; constexpr size_t DummyHandleDataSize = 10; char DummyHandleData[DummyHandleDataSize] = {9, 8, 7, 6, 5, 4, 3, 2, 1}; @@ -32,29 +28,34 @@ thread_local int urIPCGetMemHandleExp_counter = 0; thread_local int urIPCPutMemHandleExp_counter = 0; thread_local int urIPCOpenMemHandleExp_counter = 0; thread_local int urIPCCloseMemHandleExp_counter = 0; -thread_local int urIPCGetMemHandleDataExp_counter = 0; ur_result_t replace_urIPCGetMemHandleExp(void *pParams) { ++urIPCGetMemHandleExp_counter; auto params = *static_cast(pParams); EXPECT_EQ(*params.ppMem, DummyPtr); - **params.pphIPCMem = DummyMemHandle; + if (*params.ppIPCMemHandleDataSizeRet) + **params.ppIPCMemHandleDataSizeRet = DummyHandleDataSize; + if (*params.ppIPCMemHandleData) + std::memcpy(*params.ppIPCMemHandleData, DummyHandleData, + DummyHandleDataSize); return UR_RESULT_SUCCESS; } -thread_local ur_bool_t urIPCPutMemHandleExp_explicit = false; ur_result_t replace_urIPCPutMemHandleExp(void *pParams) { ++urIPCPutMemHandleExp_counter; auto params = *static_cast(pParams); - EXPECT_EQ(*params.phIPCMem, DummyMemHandle); - EXPECT_EQ(*params.pputBackendResource, urIPCPutMemHandleExp_explicit); + EXPECT_EQ( + memcmp(*params.ppIPCMemHandleData, DummyHandleData, DummyHandleDataSize), + 0); return UR_RESULT_SUCCESS; } ur_result_t replace_urIPCOpenMemHandleExp(void *pParams) { ++urIPCOpenMemHandleExp_counter; auto params = *static_cast(pParams); - EXPECT_EQ(*params.pipcMemHandleData, DummyHandleData); + EXPECT_EQ( + memcmp(*params.ppIPCMemHandleData, DummyHandleData, DummyHandleDataSize), + 0); EXPECT_EQ(*params.pipcMemHandleDataSize, DummyHandleDataSize); **params.pppMem = DummyPtr; return UR_RESULT_SUCCESS; @@ -67,16 +68,6 @@ ur_result_t replace_urIPCCloseMemHandleExp(void *pParams) { return UR_RESULT_SUCCESS; } -ur_result_t replace_urIPCGetMemHandleDataExp(void *pParams) { - ++urIPCGetMemHandleDataExp_counter; - auto params = - *static_cast(pParams); - EXPECT_EQ(*params.phIPCMem, DummyMemHandle); - **params.pppIPCHandleData = DummyHandleData; - **params.ppIPCMemHandleDataSizeRet = DummyHandleDataSize; - return UR_RESULT_SUCCESS; -} - class IPCTests : public ::testing::Test { public: IPCTests() : Mock{}, Ctxt(sycl::platform()) {} @@ -87,7 +78,6 @@ class IPCTests : public ::testing::Test { urIPCPutMemHandleExp_counter = 0; urIPCOpenMemHandleExp_counter = 0; urIPCCloseMemHandleExp_counter = 0; - urIPCGetMemHandleDataExp_counter = 0; mock::getCallbacks().set_replace_callback("urIPCGetMemHandleExp", replace_urIPCGetMemHandleExp); @@ -97,8 +87,6 @@ class IPCTests : public ::testing::Test { replace_urIPCOpenMemHandleExp); mock::getCallbacks().set_replace_callback("urIPCCloseMemHandleExp", replace_urIPCCloseMemHandleExp); - mock::getCallbacks().set_replace_callback("urIPCGetMemHandleDataExp", - replace_urIPCGetMemHandleDataExp); } sycl::unittest::UrMock<> Mock; @@ -106,98 +94,48 @@ class IPCTests : public ::testing::Test { }; TEST_F(IPCTests, IPCGetPutImplicit) { - urIPCPutMemHandleExp_explicit = false; - - { - syclexp::ipc_memory IPCMem{DummyPtr, Ctxt}; - - // Creating the IPC memory from a pointer should only call "get". - EXPECT_EQ(urIPCGetMemHandleExp_counter, 1); - EXPECT_EQ(urIPCPutMemHandleExp_counter, 0); - EXPECT_EQ(urIPCOpenMemHandleExp_counter, 0); - EXPECT_EQ(urIPCCloseMemHandleExp_counter, 0); - EXPECT_EQ(urIPCGetMemHandleDataExp_counter, 0); - - syclexp::ipc_memory_handle_data_t IPCMemHandleData = - IPCMem.get_handle_data(); - EXPECT_EQ(IPCMemHandleData.data(), DummyHandleData); - EXPECT_EQ(IPCMemHandleData.size(), DummyHandleDataSize); - - // Getting the underlying data should call the backend. - EXPECT_EQ(urIPCGetMemHandleExp_counter, 1); - EXPECT_EQ(urIPCPutMemHandleExp_counter, 0); - EXPECT_EQ(urIPCOpenMemHandleExp_counter, 0); - EXPECT_EQ(urIPCCloseMemHandleExp_counter, 0); - EXPECT_EQ(urIPCGetMemHandleDataExp_counter, 1); - } - - // When the IPC memory object dies, it should return the handle, calling - // "put". - EXPECT_EQ(urIPCGetMemHandleExp_counter, 1); - EXPECT_EQ(urIPCPutMemHandleExp_counter, 1); + syclexp::ipc_memory::handle_data_t IPCMemHandleData = + syclexp::ipc_memory::get(DummyPtr, Ctxt); + EXPECT_EQ(IPCMemHandleData.size(), DummyHandleDataSize); + EXPECT_EQ( + memcmp(IPCMemHandleData.data(), DummyHandleData, IPCMemHandleData.size()), + 0); + + // Creating the IPC memory from a pointer should only call "get". It should be + // called twice: Once to get the size of the data and again to get the data. + EXPECT_EQ(urIPCGetMemHandleExp_counter, 2); + EXPECT_EQ(urIPCPutMemHandleExp_counter, 0); EXPECT_EQ(urIPCOpenMemHandleExp_counter, 0); EXPECT_EQ(urIPCCloseMemHandleExp_counter, 0); - EXPECT_EQ(urIPCGetMemHandleDataExp_counter, 1); } TEST_F(IPCTests, IPCGetPutExplicit) { - urIPCPutMemHandleExp_explicit = true; - - { - syclexp::ipc_memory IPCMem{DummyPtr, Ctxt}; - - // Creating the IPC memory from a pointer should only call "get". - EXPECT_EQ(urIPCGetMemHandleExp_counter, 1); - EXPECT_EQ(urIPCPutMemHandleExp_counter, 0); - EXPECT_EQ(urIPCOpenMemHandleExp_counter, 0); - EXPECT_EQ(urIPCCloseMemHandleExp_counter, 0); - EXPECT_EQ(urIPCGetMemHandleDataExp_counter, 0); - - IPCMem.put(); - - // Calling "put" explicitly should call the UR function. - EXPECT_EQ(urIPCGetMemHandleExp_counter, 1); - EXPECT_EQ(urIPCPutMemHandleExp_counter, 1); - EXPECT_EQ(urIPCOpenMemHandleExp_counter, 0); - EXPECT_EQ(urIPCCloseMemHandleExp_counter, 0); - EXPECT_EQ(urIPCGetMemHandleDataExp_counter, 0); - - // calling put() again should now throw. - try { - IPCMem.put(); - FAIL(); - } catch (sycl::exception &E) { - EXPECT_EQ(E.code(), sycl::make_error_code(sycl::errc::invalid)); - } - - // get_handle_data() should now throw. - try { - IPCMem.get_handle_data(); - FAIL(); - } catch (sycl::exception &E) { - EXPECT_EQ(E.code(), sycl::make_error_code(sycl::errc::invalid)); - } - - // After exception cases, no changes should have happened to the counters. - EXPECT_EQ(urIPCGetMemHandleExp_counter, 1); - EXPECT_EQ(urIPCPutMemHandleExp_counter, 1); - EXPECT_EQ(urIPCOpenMemHandleExp_counter, 0); - EXPECT_EQ(urIPCCloseMemHandleExp_counter, 0); - EXPECT_EQ(urIPCGetMemHandleDataExp_counter, 0); - } + syclexp::ipc_memory::handle_data_t IPCMemHandleData = + syclexp::ipc_memory::get(DummyPtr, Ctxt); + EXPECT_EQ(IPCMemHandleData.size(), DummyHandleDataSize); + EXPECT_EQ( + memcmp(IPCMemHandleData.data(), DummyHandleData, IPCMemHandleData.size()), + 0); + + // Creating the IPC memory from a pointer should only call "get". It should be + // called twice: Once to get the size of the data and again to get the data. + EXPECT_EQ(urIPCGetMemHandleExp_counter, 2); + EXPECT_EQ(urIPCPutMemHandleExp_counter, 0); + EXPECT_EQ(urIPCOpenMemHandleExp_counter, 0); + EXPECT_EQ(urIPCCloseMemHandleExp_counter, 0); + + syclexp::ipc_memory::put(IPCMemHandleData, Ctxt); - // When the IPC memory object dies, put has already been called so "put" - // should not be called again. - EXPECT_EQ(urIPCGetMemHandleExp_counter, 1); + // Calling "put" explicitly should call the UR function. + EXPECT_EQ(urIPCGetMemHandleExp_counter, 2); EXPECT_EQ(urIPCPutMemHandleExp_counter, 1); EXPECT_EQ(urIPCOpenMemHandleExp_counter, 0); EXPECT_EQ(urIPCCloseMemHandleExp_counter, 0); - EXPECT_EQ(urIPCGetMemHandleDataExp_counter, 0); } TEST_F(IPCTests, IPCOpenClose) { - syclexp::ipc_memory_handle_data_t HandleData{DummyHandleData, - DummyHandleDataSize}; + syclexp::ipc_memory::handle_data_t HandleData{ + DummyHandleData, DummyHandleData + DummyHandleDataSize}; void *Ptr = syclexp::ipc_memory::open(HandleData, Ctxt, Ctxt.get_devices()[0]); EXPECT_EQ(Ptr, DummyPtr); @@ -207,7 +145,6 @@ TEST_F(IPCTests, IPCOpenClose) { EXPECT_EQ(urIPCPutMemHandleExp_counter, 0); EXPECT_EQ(urIPCOpenMemHandleExp_counter, 1); EXPECT_EQ(urIPCCloseMemHandleExp_counter, 0); - EXPECT_EQ(urIPCGetMemHandleDataExp_counter, 0); syclexp::ipc_memory::close(Ptr, Ctxt); @@ -216,7 +153,6 @@ TEST_F(IPCTests, IPCOpenClose) { EXPECT_EQ(urIPCPutMemHandleExp_counter, 0); EXPECT_EQ(urIPCOpenMemHandleExp_counter, 1); EXPECT_EQ(urIPCCloseMemHandleExp_counter, 1); - EXPECT_EQ(urIPCGetMemHandleDataExp_counter, 0); } } // namespace From fa44def2156fa33aa774fc24c5d2ad1ddb87163d Mon Sep 17 00:00:00 2001 From: "Larsen, Steffen" Date: Mon, 6 Oct 2025 00:18:35 -0700 Subject: [PATCH 18/38] Change IPC API (UR) Signed-off-by: Larsen, Steffen --- unified-runtime/include/ur_api.h | 79 +++++------------- unified-runtime/include/ur_api_funcs.def | 1 - unified-runtime/include/ur_ddi.h | 15 ++-- unified-runtime/include/ur_print.h | 10 --- unified-runtime/include/ur_print.hpp | 60 +++----------- .../core/EXP-INTER-PROCESS-COMMUNICATION.rst | 5 -- .../core/exp-inter-process-communication.yml | 60 ++++---------- unified-runtime/scripts/core/registry.yml | 3 - .../source/adapters/cuda/memory.cpp | 52 ++++++------ .../source/adapters/cuda/memory.hpp | 5 -- .../adapters/cuda/ur_interface_loader.cpp | 1 - .../source/adapters/hip/memory.cpp | 11 +-- .../source/adapters/hip/memory.hpp | 3 - .../adapters/hip/ur_interface_loader.cpp | 1 - .../source/adapters/level_zero/memory.cpp | 52 ++++++------ .../source/adapters/level_zero/memory.hpp | 5 -- .../level_zero/ur_interface_loader.cpp | 1 - .../level_zero/ur_interface_loader.hpp | 12 +-- .../source/adapters/level_zero/v2/memory.cpp | 52 ++++++------ .../source/adapters/level_zero/v2/memory.hpp | 5 -- .../source/adapters/mock/ur_mockddi.cpp | 75 +++-------------- .../source/adapters/native_cpu/memory.cpp | 11 +-- .../source/adapters/native_cpu/memory.hpp | 3 - .../native_cpu/ur_interface_loader.cpp | 1 - .../source/adapters/offload/memory.cpp | 11 +-- .../source/adapters/offload/memory.hpp | 3 - .../adapters/offload/ur_interface_loader.cpp | 1 - .../source/adapters/opencl/memory.cpp | 9 +-- .../source/adapters/opencl/memory.hpp | 3 - .../adapters/opencl/ur_interface_loader.cpp | 1 - .../loader/layers/tracing/ur_trcddi.cpp | 80 ++++--------------- .../loader/layers/validation/ur_valddi.cpp | 78 +++++------------- unified-runtime/source/loader/loader.def.in | 2 - unified-runtime/source/loader/loader.map.in | 2 - unified-runtime/source/loader/ur_ldrddi.cpp | 47 +++-------- unified-runtime/source/loader/ur_libapi.cpp | 71 +++++----------- unified-runtime/source/loader/ur_print.cpp | 8 -- unified-runtime/source/ur_api.cpp | 57 ++++--------- 38 files changed, 226 insertions(+), 670 deletions(-) diff --git a/unified-runtime/include/ur_api.h b/unified-runtime/include/ur_api.h index f0e87e0a616da..f1a5deb921b87 100644 --- a/unified-runtime/include/ur_api.h +++ b/unified-runtime/include/ur_api.h @@ -483,8 +483,6 @@ typedef enum ur_function_t { UR_FUNCTION_IPC_OPEN_MEM_HANDLE_EXP = 291, /// Enumerator for ::urIPCCloseMemHandleExp UR_FUNCTION_IPC_CLOSE_MEM_HANDLE_EXP = 292, - /// Enumerator for ::urIPCGetMemHandleDataExp - UR_FUNCTION_IPC_GET_MEM_HANDLE_DATA_EXP = 293, /// @cond UR_FUNCTION_FORCE_UINT32 = 0x7fffffff /// @endcond @@ -12391,10 +12389,6 @@ UR_APIEXPORT ur_result_t UR_APICALL urEnqueueTimestampRecordingExp( #if !defined(__GNUC__) #pragma region inter_process_communication_(experimental) #endif -/////////////////////////////////////////////////////////////////////////////// -/// @brief Handle of inter-process communicable memory -typedef struct ur_exp_ipc_mem_handle_t_ *ur_exp_ipc_mem_handle_t; - /////////////////////////////////////////////////////////////////////////////// /// @brief Gets an inter-process memory handle for a pointer to device USM /// memory @@ -12406,9 +12400,10 @@ typedef struct ur_exp_ipc_mem_handle_t_ *ur_exp_ipc_mem_handle_t; /// - ::UR_RESULT_ERROR_ADAPTER_SPECIFIC /// - ::UR_RESULT_ERROR_INVALID_NULL_HANDLE /// + `NULL == hContext` -/// - ::UR_RESULT_ERROR_INVALID_NULL_POINTER -/// + `NULL == phIPCMem` /// - ::UR_RESULT_ERROR_INVALID_CONTEXT +/// - ::UR_RESULT_ERROR_INVALID_NULL_POINTER +/// + `NULL == pIPCMemHandleData` +/// + `NULL == pIPCMemHandleDataSizeRet` /// - ::UR_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::UR_RESULT_ERROR_OUT_OF_RESOURCES UR_APIEXPORT ur_result_t UR_APICALL urIPCGetMemHandleExp( @@ -12416,8 +12411,10 @@ UR_APIEXPORT ur_result_t UR_APICALL urIPCGetMemHandleExp( ur_context_handle_t hContext, /// [in] pointer to device USM memory void *pMem, - /// [out][alloc] pointer to the resulting IPC memory handle - ur_exp_ipc_mem_handle_t *phIPCMem); + /// [out][optional] a pointer to the IPC memory handle data + void *pIPCMemHandleData, + /// [out][optional] size of the resulting IPC memory handle data + size_t *pIPCMemHandleDataSizeRet); /////////////////////////////////////////////////////////////////////////////// /// @brief Releases an inter-process memory handle @@ -12429,23 +12426,20 @@ UR_APIEXPORT ur_result_t UR_APICALL urIPCGetMemHandleExp( /// - ::UR_RESULT_ERROR_ADAPTER_SPECIFIC /// - ::UR_RESULT_ERROR_INVALID_NULL_HANDLE /// + `NULL == hContext` -/// + `NULL == hIPCMem` +/// - ::UR_RESULT_ERROR_INVALID_NULL_POINTER +/// + `NULL == pIPCMemHandleData` /// - ::UR_RESULT_ERROR_INVALID_CONTEXT /// - ::UR_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::UR_RESULT_ERROR_OUT_OF_RESOURCES UR_APIEXPORT ur_result_t UR_APICALL urIPCPutMemHandleExp( /// [in] handle of the context object ur_context_handle_t hContext, - /// [in] the IPC memory handle - ur_exp_ipc_mem_handle_t hIPCMem, - /// [in] true if the backend resource should be released, false if the - /// backend resource will be released when freeing the corresponding - /// device USM memory - ur_bool_t putBackendResource); + /// [in] a pointer to the IPC memory handle data + void *pIPCMemHandleData); /////////////////////////////////////////////////////////////////////////////// -/// @brief Opens an inter-process memory handle from raw data to get the -/// corresponding pointer to device USM memory +/// @brief Opens an inter-process memory handle to get the corresponding pointer +/// to device USM memory /// /// @returns /// - ::UR_RESULT_SUCCESS @@ -12457,7 +12451,7 @@ UR_APIEXPORT ur_result_t UR_APICALL urIPCPutMemHandleExp( /// + `NULL == hDevice` /// - ::UR_RESULT_ERROR_INVALID_CONTEXT /// - ::UR_RESULT_ERROR_INVALID_NULL_POINTER -/// + `NULL == ipcMemHandleData` +/// + `NULL == pIPCMemHandleData` /// + `NULL == ppMem` /// - ::UR_RESULT_ERROR_INVALID_VALUE /// + ipcMemHandleDataSize is not the same as the size of IPC memory @@ -12471,7 +12465,7 @@ UR_APIEXPORT ur_result_t UR_APICALL urIPCOpenMemHandleExp( /// was allocated on ur_device_handle_t hDevice, /// [in] the IPC memory handle data - void *ipcMemHandleData, + void *pIPCMemHandleData, /// [in] size of the IPC memory handle data size_t ipcMemHandleDataSize, /// [out] pointer to a pointer to device USM memory @@ -12498,30 +12492,6 @@ UR_APIEXPORT ur_result_t UR_APICALL urIPCCloseMemHandleExp( /// [in] pointer to device USM memory opened through urIPCOpenMemHandleExp void *pMem); -/////////////////////////////////////////////////////////////////////////////// -/// @brief Gets the data of an inter-process memory handle -/// -/// @returns -/// - ::UR_RESULT_SUCCESS -/// - ::UR_RESULT_ERROR_UNINITIALIZED -/// - ::UR_RESULT_ERROR_DEVICE_LOST -/// - ::UR_RESULT_ERROR_ADAPTER_SPECIFIC -/// - ::UR_RESULT_ERROR_INVALID_NULL_HANDLE -/// + `NULL == hContext` -/// + `NULL == hIPCMem` -/// - ::UR_RESULT_ERROR_INVALID_CONTEXT -/// - ::UR_RESULT_ERROR_OUT_OF_HOST_MEMORY -/// - ::UR_RESULT_ERROR_OUT_OF_RESOURCES -UR_APIEXPORT ur_result_t UR_APICALL urIPCGetMemHandleDataExp( - /// [in] handle of the context object - ur_context_handle_t hContext, - /// [in] the IPC memory handle - ur_exp_ipc_mem_handle_t hIPCMem, - /// [out][optional] a pointer to the IPC memory handle data - void **ppIPCHandleData, - /// [out][optional] size of the resulting IPC memory handle data - size_t *pIPCMemHandleDataSizeRet); - #if !defined(__GNUC__) #pragma endregion #endif @@ -15604,7 +15574,8 @@ typedef struct ur_command_buffer_get_native_handle_exp_params_t { typedef struct ur_ipc_get_mem_handle_exp_params_t { ur_context_handle_t *phContext; void **ppMem; - ur_exp_ipc_mem_handle_t **pphIPCMem; + void **ppIPCMemHandleData; + size_t **ppIPCMemHandleDataSizeRet; } ur_ipc_get_mem_handle_exp_params_t; /////////////////////////////////////////////////////////////////////////////// @@ -15613,8 +15584,7 @@ typedef struct ur_ipc_get_mem_handle_exp_params_t { /// allowing the callback the ability to modify the parameter's value typedef struct ur_ipc_put_mem_handle_exp_params_t { ur_context_handle_t *phContext; - ur_exp_ipc_mem_handle_t *phIPCMem; - ur_bool_t *pputBackendResource; + void **ppIPCMemHandleData; } ur_ipc_put_mem_handle_exp_params_t; /////////////////////////////////////////////////////////////////////////////// @@ -15624,7 +15594,7 @@ typedef struct ur_ipc_put_mem_handle_exp_params_t { typedef struct ur_ipc_open_mem_handle_exp_params_t { ur_context_handle_t *phContext; ur_device_handle_t *phDevice; - void **pipcMemHandleData; + void **ppIPCMemHandleData; size_t *pipcMemHandleDataSize; void ***pppMem; } ur_ipc_open_mem_handle_exp_params_t; @@ -15638,17 +15608,6 @@ typedef struct ur_ipc_close_mem_handle_exp_params_t { void **ppMem; } ur_ipc_close_mem_handle_exp_params_t; -/////////////////////////////////////////////////////////////////////////////// -/// @brief Function parameters for urIPCGetMemHandleDataExp -/// @details Each entry is a pointer to the parameter passed to the function; -/// allowing the callback the ability to modify the parameter's value -typedef struct ur_ipc_get_mem_handle_data_exp_params_t { - ur_context_handle_t *phContext; - ur_exp_ipc_mem_handle_t *phIPCMem; - void ***pppIPCHandleData; - size_t **ppIPCMemHandleDataSizeRet; -} ur_ipc_get_mem_handle_data_exp_params_t; - /////////////////////////////////////////////////////////////////////////////// /// @brief Function parameters for urMemoryExportAllocExportableMemoryExp /// @details Each entry is a pointer to the parameter passed to the function; diff --git a/unified-runtime/include/ur_api_funcs.def b/unified-runtime/include/ur_api_funcs.def index 4b72a768d8ca3..ab189345ce9d0 100644 --- a/unified-runtime/include/ur_api_funcs.def +++ b/unified-runtime/include/ur_api_funcs.def @@ -210,7 +210,6 @@ _UR_API(urIPCGetMemHandleExp) _UR_API(urIPCPutMemHandleExp) _UR_API(urIPCOpenMemHandleExp) _UR_API(urIPCCloseMemHandleExp) -_UR_API(urIPCGetMemHandleDataExp) _UR_API(urMemoryExportAllocExportableMemoryExp) _UR_API(urMemoryExportFreeExportableMemoryExp) _UR_API(urMemoryExportExportMemoryHandleExp) diff --git a/unified-runtime/include/ur_ddi.h b/unified-runtime/include/ur_ddi.h index ec400de8c758f..4df199f12e363 100644 --- a/unified-runtime/include/ur_ddi.h +++ b/unified-runtime/include/ur_ddi.h @@ -1789,13 +1789,14 @@ typedef ur_result_t(UR_APICALL *ur_pfnGetCommandBufferExpProcAddrTable_t)( /////////////////////////////////////////////////////////////////////////////// /// @brief Function-pointer for urIPCGetMemHandleExp -typedef ur_result_t(UR_APICALL *ur_pfnIPCGetMemHandleExp_t)( - ur_context_handle_t, void *, ur_exp_ipc_mem_handle_t *); +typedef ur_result_t(UR_APICALL *ur_pfnIPCGetMemHandleExp_t)(ur_context_handle_t, + void *, void *, + size_t *); /////////////////////////////////////////////////////////////////////////////// /// @brief Function-pointer for urIPCPutMemHandleExp -typedef ur_result_t(UR_APICALL *ur_pfnIPCPutMemHandleExp_t)( - ur_context_handle_t, ur_exp_ipc_mem_handle_t, ur_bool_t); +typedef ur_result_t(UR_APICALL *ur_pfnIPCPutMemHandleExp_t)(ur_context_handle_t, + void *); /////////////////////////////////////////////////////////////////////////////// /// @brief Function-pointer for urIPCOpenMemHandleExp @@ -1807,11 +1808,6 @@ typedef ur_result_t(UR_APICALL *ur_pfnIPCOpenMemHandleExp_t)( typedef ur_result_t(UR_APICALL *ur_pfnIPCCloseMemHandleExp_t)( ur_context_handle_t, void *); -/////////////////////////////////////////////////////////////////////////////// -/// @brief Function-pointer for urIPCGetMemHandleDataExp -typedef ur_result_t(UR_APICALL *ur_pfnIPCGetMemHandleDataExp_t)( - ur_context_handle_t, ur_exp_ipc_mem_handle_t, void **, size_t *); - /////////////////////////////////////////////////////////////////////////////// /// @brief Table of IPCExp functions pointers typedef struct ur_ipc_exp_dditable_t { @@ -1819,7 +1815,6 @@ typedef struct ur_ipc_exp_dditable_t { ur_pfnIPCPutMemHandleExp_t pfnPutMemHandleExp; ur_pfnIPCOpenMemHandleExp_t pfnOpenMemHandleExp; ur_pfnIPCCloseMemHandleExp_t pfnCloseMemHandleExp; - ur_pfnIPCGetMemHandleDataExp_t pfnGetMemHandleDataExp; } ur_ipc_exp_dditable_t; /////////////////////////////////////////////////////////////////////////////// diff --git a/unified-runtime/include/ur_print.h b/unified-runtime/include/ur_print.h index dd38252f71399..eedd6df43d9b9 100644 --- a/unified-runtime/include/ur_print.h +++ b/unified-runtime/include/ur_print.h @@ -3530,16 +3530,6 @@ UR_APIEXPORT ur_result_t UR_APICALL urPrintIpcCloseMemHandleExpParams( const struct ur_ipc_close_mem_handle_exp_params_t *params, char *buffer, const size_t buff_size, size_t *out_size); -/////////////////////////////////////////////////////////////////////////////// -/// @brief Print ur_ipc_get_mem_handle_data_exp_params_t struct -/// @returns -/// - ::UR_RESULT_SUCCESS -/// - ::UR_RESULT_ERROR_INVALID_SIZE -/// - `buff_size < out_size` -UR_APIEXPORT ur_result_t UR_APICALL urPrintIpcGetMemHandleDataExpParams( - const struct ur_ipc_get_mem_handle_data_exp_params_t *params, char *buffer, - const size_t buff_size, size_t *out_size); - /////////////////////////////////////////////////////////////////////////////// /// @brief Print ur_memory_export_alloc_exportable_memory_exp_params_t struct /// @returns diff --git a/unified-runtime/include/ur_print.hpp b/unified-runtime/include/ur_print.hpp index 1208761abc78b..92bb2b063d080 100644 --- a/unified-runtime/include/ur_print.hpp +++ b/unified-runtime/include/ur_print.hpp @@ -42,7 +42,6 @@ template <> struct is_handle : std::true_type {}; template <> struct is_handle : std::true_type {}; -template <> struct is_handle : std::true_type {}; template inline constexpr bool is_handle_v = is_handle::value; template inline ur_result_t printPtr(std::ostream &os, const T *ptr); @@ -1287,9 +1286,6 @@ inline std::ostream &operator<<(std::ostream &os, enum ur_function_t value) { case UR_FUNCTION_IPC_CLOSE_MEM_HANDLE_EXP: os << "UR_FUNCTION_IPC_CLOSE_MEM_HANDLE_EXP"; break; - case UR_FUNCTION_IPC_GET_MEM_HANDLE_DATA_EXP: - os << "UR_FUNCTION_IPC_GET_MEM_HANDLE_DATA_EXP"; - break; default: os << "unknown enumerator"; break; @@ -20356,9 +20352,14 @@ inline std::ostream &operator<<( os << *(params->ppMem); os << ", "; - os << ".phIPCMem = "; + os << ".pIPCMemHandleData = "; - ur::details::printPtr(os, *(params->pphIPCMem)); + ur::details::printPtr(os, *(params->ppIPCMemHandleData)); + + os << ", "; + os << ".pIPCMemHandleDataSizeRet = "; + + ur::details::printPtr(os, *(params->ppIPCMemHandleDataSizeRet)); return os; } @@ -20376,14 +20377,9 @@ inline std::ostream &operator<<( ur::details::printPtr(os, *(params->phContext)); os << ", "; - os << ".hIPCMem = "; - - ur::details::printPtr(os, *(params->phIPCMem)); - - os << ", "; - os << ".putBackendResource = "; + os << ".pIPCMemHandleData = "; - os << *(params->pputBackendResource); + ur::details::printPtr(os, *(params->ppIPCMemHandleData)); return os; } @@ -20406,9 +20402,9 @@ inline std::ostream &operator<<( ur::details::printPtr(os, *(params->phDevice)); os << ", "; - os << ".ipcMemHandleData = "; + os << ".pIPCMemHandleData = "; - os << *(params->pipcMemHandleData); + os << *(params->ppIPCMemHandleData); os << ", "; os << ".ipcMemHandleDataSize = "; @@ -20444,37 +20440,6 @@ operator<<(std::ostream &os, return os; } -/////////////////////////////////////////////////////////////////////////////// -/// @brief Print operator for the ur_ipc_get_mem_handle_data_exp_params_t type -/// @returns -/// std::ostream & -inline std::ostream & -operator<<(std::ostream &os, - [[maybe_unused]] const struct ur_ipc_get_mem_handle_data_exp_params_t - *params) { - - os << ".hContext = "; - - ur::details::printPtr(os, *(params->phContext)); - - os << ", "; - os << ".hIPCMem = "; - - ur::details::printPtr(os, *(params->phIPCMem)); - - os << ", "; - os << ".ppIPCHandleData = "; - - ur::details::printPtr(os, *(params->pppIPCHandleData)); - - os << ", "; - os << ".pIPCMemHandleDataSizeRet = "; - - ur::details::printPtr(os, *(params->ppIPCMemHandleDataSizeRet)); - - return os; -} - /////////////////////////////////////////////////////////////////////////////// /// @brief Print operator for the /// ur_memory_export_alloc_exportable_memory_exp_params_t type @@ -21951,9 +21916,6 @@ inline ur_result_t UR_APICALL printFunctionParams(std::ostream &os, case UR_FUNCTION_IPC_CLOSE_MEM_HANDLE_EXP: { os << (const struct ur_ipc_close_mem_handle_exp_params_t *)params; } break; - case UR_FUNCTION_IPC_GET_MEM_HANDLE_DATA_EXP: { - os << (const struct ur_ipc_get_mem_handle_data_exp_params_t *)params; - } break; case UR_FUNCTION_MEMORY_EXPORT_ALLOC_EXPORTABLE_MEMORY_EXP: { os << (const struct ur_memory_export_alloc_exportable_memory_exp_params_t *) params; diff --git a/unified-runtime/scripts/core/EXP-INTER-PROCESS-COMMUNICATION.rst b/unified-runtime/scripts/core/EXP-INTER-PROCESS-COMMUNICATION.rst index 73d0616a1d7c3..647f6f09ac23b 100644 --- a/unified-runtime/scripts/core/EXP-INTER-PROCESS-COMMUNICATION.rst +++ b/unified-runtime/scripts/core/EXP-INTER-PROCESS-COMMUNICATION.rst @@ -35,10 +35,6 @@ Enums * ${x}_device_info_t * ${X}_DEVICE_INFO_IPC_MEMORY_SUPPORT_EXP -Types -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -* ${x}_exp_ipc_mem_handle_t - Functions ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * Inter-Process Communication @@ -46,7 +42,6 @@ Functions * ${x}IPCPutMemHandleExp * ${x}IPCOpenMemHandleExp * ${x}IPCCloseMemHandleExp - * ${x}IPCGetMemHandleDataExp Changelog -------------------------------------------------------------------------------- diff --git a/unified-runtime/scripts/core/exp-inter-process-communication.yml b/unified-runtime/scripts/core/exp-inter-process-communication.yml index 5ec212ca18414..117e66d815ba9 100644 --- a/unified-runtime/scripts/core/exp-inter-process-communication.yml +++ b/unified-runtime/scripts/core/exp-inter-process-communication.yml @@ -24,10 +24,6 @@ etors: value: "0x2023" desc: "[$x_bool_t] returns true if the device supports inter-process communicable memory handles" --- #-------------------------------------------------------------------------- -type: handle -desc: "Handle of inter-process communicable memory" -name: "$x_exp_ipc_mem_handle_t" ---- #-------------------------------------------------------------------------- type: function desc: "Gets an inter-process memory handle for a pointer to device USM memory" class: $xIPC @@ -40,15 +36,19 @@ params: - type: void * name: pMem desc: "[in] pointer to device USM memory" - - type: $x_exp_ipc_mem_handle_t* - name: phIPCMem - desc: "[out][alloc] pointer to the resulting IPC memory handle" + - type: void* + name: pIPCMemHandleData + desc: "[out][optional] a pointer to the IPC memory handle data" + - type: size_t* + name: pIPCMemHandleDataSizeRet + desc: "[out][optional] size of the resulting IPC memory handle data" returns: - $X_RESULT_ERROR_INVALID_CONTEXT - $X_RESULT_ERROR_INVALID_NULL_HANDLE: - "`NULL == hContext`" - $X_RESULT_ERROR_INVALID_NULL_POINTER: - - "`NULL == phIPCMem`" + - "`NULL == pIPCMemHandleData`" + - "`NULL == pIPCMemHandleDataSizeRet`" - $X_RESULT_ERROR_OUT_OF_HOST_MEMORY - $X_RESULT_ERROR_OUT_OF_RESOURCES --- #-------------------------------------------------------------------------- @@ -61,22 +61,20 @@ params: - type: $x_context_handle_t name: hContext desc: "[in] handle of the context object" - - type: $x_exp_ipc_mem_handle_t - name: hIPCMem - desc: "[in] the IPC memory handle" - - type: $x_bool_t - name: putBackendResource - desc: "[in] true if the backend resource should be released, false if the backend resource will be released when freeing the corresponding device USM memory" + - type: void* + name: pIPCMemHandleData + desc: "[in] a pointer to the IPC memory handle data" returns: - $X_RESULT_ERROR_INVALID_CONTEXT - $X_RESULT_ERROR_INVALID_NULL_HANDLE: - "`NULL == hContext`" - - "`NULL == hIPCMem`" + - $X_RESULT_ERROR_INVALID_NULL_POINTER: + - "`NULL == pIPCMemHandleData`" - $X_RESULT_ERROR_OUT_OF_HOST_MEMORY - $X_RESULT_ERROR_OUT_OF_RESOURCES --- #-------------------------------------------------------------------------- type: function -desc: "Opens an inter-process memory handle from raw data to get the corresponding pointer to device USM memory" +desc: "Opens an inter-process memory handle to get the corresponding pointer to device USM memory" class: $xIPC name: OpenMemHandleExp ordinal: "0" @@ -88,7 +86,7 @@ params: name: hDevice desc: "[in] handle of the device object the corresponding USM device memory was allocated on" - type: void * - name: ipcMemHandleData + name: pIPCMemHandleData desc: "[in] the IPC memory handle data" - type: size_t name: ipcMemHandleDataSize @@ -102,7 +100,7 @@ returns: - "`NULL == hContext`" - "`NULL == hDevice`" - $X_RESULT_ERROR_INVALID_NULL_POINTER: - - "`NULL == ipcMemHandleData`" + - "`NULL == pIPCMemHandleData`" - "`NULL == ppMem`" - $X_RESULT_ERROR_INVALID_VALUE: - "ipcMemHandleDataSize is not the same as the size of IPC memory handle data" @@ -129,29 +127,3 @@ returns: - "`NULL == pMem`" - $X_RESULT_ERROR_OUT_OF_HOST_MEMORY - $X_RESULT_ERROR_OUT_OF_RESOURCES ---- #-------------------------------------------------------------------------- -type: function -desc: "Gets the data of an inter-process memory handle" -class: $xIPC -name: GetMemHandleDataExp -ordinal: "0" -params: - - type: $x_context_handle_t - name: hContext - desc: "[in] handle of the context object" - - type: $x_exp_ipc_mem_handle_t - name: hIPCMem - desc: "[in] the IPC memory handle" - - type: void** - name: ppIPCHandleData - desc: "[out][optional] a pointer to the IPC memory handle data" - - type: size_t* - name: pIPCMemHandleDataSizeRet - desc: "[out][optional] size of the resulting IPC memory handle data" -returns: - - $X_RESULT_ERROR_INVALID_CONTEXT - - $X_RESULT_ERROR_INVALID_NULL_HANDLE: - - "`NULL == hContext`" - - "`NULL == hIPCMem`" - - $X_RESULT_ERROR_OUT_OF_HOST_MEMORY - - $X_RESULT_ERROR_OUT_OF_RESOURCES diff --git a/unified-runtime/scripts/core/registry.yml b/unified-runtime/scripts/core/registry.yml index 020374a3484bb..6adfd0d449563 100644 --- a/unified-runtime/scripts/core/registry.yml +++ b/unified-runtime/scripts/core/registry.yml @@ -682,9 +682,6 @@ etors: - name: IPC_CLOSE_MEM_HANDLE_EXP desc: Enumerator for $xIPCCloseMemHandleExp value: '292' -- name: IPC_GET_MEM_HANDLE_DATA_EXP - desc: Enumerator for $xIPCGetMemHandleDataExp - value: '293' --- type: enum desc: Defines structure types diff --git a/unified-runtime/source/adapters/cuda/memory.cpp b/unified-runtime/source/adapters/cuda/memory.cpp index 07436425d10d2..bdc33e6755158 100644 --- a/unified-runtime/source/adapters/cuda/memory.cpp +++ b/unified-runtime/source/adapters/cuda/memory.cpp @@ -591,34 +591,40 @@ CUsurfObject SurfaceMem::getSurface(const ur_device_handle_t Device) { return SurfObjs[OuterMemStruct->getContext()->getDeviceIndex(Device)]; } -UR_APIEXPORT ur_result_t UR_APICALL urIPCGetMemHandleExp( - ur_context_handle_t, void *pMem, ur_exp_ipc_mem_handle_t *phIPCMem) { - auto resHandle = std::make_unique(); - +UR_APIEXPORT ur_result_t UR_APICALL +urIPCGetMemHandleExp(ur_context_handle_t, void *pMem, void *pIPCMemHandleData, + size_t *pIPCMemHandleDataSizeRet) { umf_memory_pool_handle_t umfPool; auto umfRet = umfPoolByPtr(pMem, &umfPool); if (umfRet != UMF_RESULT_SUCCESS || !umfPool) return UR_RESULT_ERROR_UNKNOWN; - umfRet = umfGetIPCHandle(pMem, &resHandle->UMFHandle, &resHandle->HandleSize); - if (umfRet != UMF_RESULT_SUCCESS || !resHandle->UMFHandle || - resHandle->HandleSize == 0) - return UR_RESULT_ERROR_UNKNOWN; + // Fast path for returning the size of the handle only. + if (!pIPCMemHandleData) { + auto umfRet = umfPoolGetIPCHandleSize(umfPool, pIPCMemHandleDataSizeRet); + if (umfRet != UMF_RESULT_SUCCESS || *pIPCMemHandleDataSizeRet == 0) + return UR_RESULT_ERROR_UNKNOWN; + return UR_RESULT_SUCCESS; + } - *phIPCMem = resHandle.release(); + size_t fallbackUMFHandleSize = 0; + size_t *umfHandleSize = pIPCMemHandleDataSizeRet != nullptr + ? pIPCMemHandleDataSizeRet + : &fallbackUMFHandleSize; + umf_ipc_handle_t umfHandle; + umfRet = umfGetIPCHandle(pMem, &umfHandle, umfHandleSize); + if (umfRet != UMF_RESULT_SUCCESS || !umfHandle || *umfHandleSize == 0) + return UR_RESULT_ERROR_UNKNOWN; + std::memcpy(pIPCMemHandleData, umfHandle, *umfHandleSize); return UR_RESULT_SUCCESS; } UR_APIEXPORT ur_result_t UR_APICALL -urIPCPutMemHandleExp(ur_context_handle_t, ur_exp_ipc_mem_handle_t hIPCMem, - ur_bool_t putBackendResource) { - if (putBackendResource) { - auto umfRet = umfPutIPCHandle(hIPCMem->UMFHandle); - if (umfRet != UMF_RESULT_SUCCESS) - return UR_RESULT_ERROR_UNKNOWN; - } - std::free(hIPCMem); - return UR_RESULT_SUCCESS; +urIPCPutMemHandleExp(ur_context_handle_t, void *pIPCMemHandleData) { + auto umfRet = + umfPutIPCHandle(reinterpret_cast(pIPCMemHandleData)); + return umfRet == UMF_RESULT_SUCCESS ? UR_RESULT_SUCCESS + : UR_RESULT_ERROR_UNKNOWN; } UR_APIEXPORT ur_result_t UR_APICALL urIPCOpenMemHandleExp( @@ -652,13 +658,3 @@ UR_APIEXPORT ur_result_t UR_APICALL urIPCCloseMemHandleExp(ur_context_handle_t, return umfRet == UMF_RESULT_SUCCESS ? UR_RESULT_SUCCESS : UR_RESULT_ERROR_UNKNOWN; } - -UR_APIEXPORT ur_result_t UR_APICALL urIPCGetMemHandleDataExp( - ur_context_handle_t, ur_exp_ipc_mem_handle_t hIPCMem, - void **ppIPCHandleData, size_t *pIPCMemHandleDataSizeRet) { - if (ppIPCHandleData) - *ppIPCHandleData = hIPCMem->UMFHandle; - if (pIPCMemHandleDataSizeRet) - *pIPCMemHandleDataSizeRet = hIPCMem->HandleSize; - return UR_RESULT_SUCCESS; -} diff --git a/unified-runtime/source/adapters/cuda/memory.hpp b/unified-runtime/source/adapters/cuda/memory.hpp index 9d3f19c4b9c58..4e72e6dd15bec 100644 --- a/unified-runtime/source/adapters/cuda/memory.hpp +++ b/unified-runtime/source/adapters/cuda/memory.hpp @@ -440,8 +440,3 @@ struct ur_mem_handle_t_ : ur::cuda::handle_base { } } }; - -struct ur_exp_ipc_mem_handle_t_ { - umf_ipc_handle_t UMFHandle = nullptr; - size_t HandleSize = 0; -}; diff --git a/unified-runtime/source/adapters/cuda/ur_interface_loader.cpp b/unified-runtime/source/adapters/cuda/ur_interface_loader.cpp index 2eb42d8bc0dea..a53266ecbe20a 100644 --- a/unified-runtime/source/adapters/cuda/ur_interface_loader.cpp +++ b/unified-runtime/source/adapters/cuda/ur_interface_loader.cpp @@ -469,7 +469,6 @@ UR_DLLEXPORT ur_result_t UR_APICALL urGetIPCExpProcAddrTable( pDdiTable->pfnPutMemHandleExp = urIPCPutMemHandleExp; pDdiTable->pfnOpenMemHandleExp = urIPCOpenMemHandleExp; pDdiTable->pfnCloseMemHandleExp = urIPCCloseMemHandleExp; - pDdiTable->pfnGetMemHandleDataExp = urIPCGetMemHandleDataExp; return UR_RESULT_SUCCESS; } diff --git a/unified-runtime/source/adapters/hip/memory.cpp b/unified-runtime/source/adapters/hip/memory.cpp index 20ce56eed9297..354af8b99f561 100644 --- a/unified-runtime/source/adapters/hip/memory.cpp +++ b/unified-runtime/source/adapters/hip/memory.cpp @@ -642,12 +642,12 @@ hipSurfaceObject_t SurfaceMem::getSurface(const ur_device_handle_t Device) { } UR_APIEXPORT ur_result_t UR_APICALL -urIPCGetMemHandleExp(ur_context_handle_t, void *, ur_exp_ipc_mem_handle_t *) { +urIPCGetMemHandleExp(ur_context_handle_t, void *, void *, size_t*) { return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; } -UR_APIEXPORT ur_result_t UR_APICALL -urIPCPutMemHandleExp(ur_context_handle_t, ur_exp_ipc_mem_handle_t, ur_bool_t) { +UR_APIEXPORT ur_result_t UR_APICALL urIPCPutMemHandleExp(ur_context_handle_t, + void *) { return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; } @@ -662,8 +662,3 @@ UR_APIEXPORT ur_result_t UR_APICALL urIPCCloseMemHandleExp(ur_context_handle_t, void *) { return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; } - -UR_APIEXPORT ur_result_t UR_APICALL urIPCGetMemHandleDataExp( - ur_context_handle_t, ur_exp_ipc_mem_handle_t, void **, size_t *) { - return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; -} diff --git a/unified-runtime/source/adapters/hip/memory.hpp b/unified-runtime/source/adapters/hip/memory.hpp index d825d153b04ce..239e3949c740c 100644 --- a/unified-runtime/source/adapters/hip/memory.hpp +++ b/unified-runtime/source/adapters/hip/memory.hpp @@ -433,6 +433,3 @@ struct ur_mem_handle_t_ : ur::hip::handle_base { } } }; - -// IPC is currently not supported in the HIP adaptor. -struct ur_exp_ipc_mem_handle_t_ {}; diff --git a/unified-runtime/source/adapters/hip/ur_interface_loader.cpp b/unified-runtime/source/adapters/hip/ur_interface_loader.cpp index 9c6cf548b4198..978570a96376a 100644 --- a/unified-runtime/source/adapters/hip/ur_interface_loader.cpp +++ b/unified-runtime/source/adapters/hip/ur_interface_loader.cpp @@ -462,7 +462,6 @@ UR_DLLEXPORT ur_result_t UR_APICALL urGetIPCExpProcAddrTable( pDdiTable->pfnPutMemHandleExp = urIPCPutMemHandleExp; pDdiTable->pfnOpenMemHandleExp = urIPCOpenMemHandleExp; pDdiTable->pfnCloseMemHandleExp = urIPCCloseMemHandleExp; - pDdiTable->pfnGetMemHandleDataExp = urIPCGetMemHandleDataExp; return UR_RESULT_SUCCESS; } diff --git a/unified-runtime/source/adapters/level_zero/memory.cpp b/unified-runtime/source/adapters/level_zero/memory.cpp index d5301b0d693a5..7bd1ae19f54cd 100644 --- a/unified-runtime/source/adapters/level_zero/memory.cpp +++ b/unified-runtime/source/adapters/level_zero/memory.cpp @@ -1953,33 +1953,38 @@ ur_result_t urEnqueueWriteHostPipe( } ur_result_t urIPCGetMemHandleExp(ur_context_handle_t, void *pMem, - ur_exp_ipc_mem_handle_t *phIPCMem) { - auto resHandle = std::make_unique(); - + void *pIPCMemHandleData, + size_t *pIPCMemHandleDataSizeRet) { umf_memory_pool_handle_t umfPool; auto umfRet = umfPoolByPtr(pMem, &umfPool); if (umfRet != UMF_RESULT_SUCCESS || !umfPool) return UR_RESULT_ERROR_UNKNOWN; - umfRet = umfGetIPCHandle(pMem, &resHandle->UMFHandle, &resHandle->HandleSize); - if (umfRet != UMF_RESULT_SUCCESS || !resHandle->UMFHandle || - resHandle->HandleSize == 0) - return UR_RESULT_ERROR_UNKNOWN; + // Fast path for returning the size of the handle only. + if (!pIPCMemHandleData) { + auto umfRet = umfPoolGetIPCHandleSize(umfPool, pIPCMemHandleDataSizeRet); + if (umfRet != UMF_RESULT_SUCCESS || *pIPCMemHandleDataSizeRet == 0) + return UR_RESULT_ERROR_UNKNOWN; + return UR_RESULT_SUCCESS; + } - *phIPCMem = resHandle.release(); + size_t fallbackUMFHandleSize = 0; + size_t *umfHandleSize = pIPCMemHandleDataSizeRet != nullptr + ? pIPCMemHandleDataSizeRet + : &fallbackUMFHandleSize; + umf_ipc_handle_t umfHandle; + umfRet = umfGetIPCHandle(pMem, &umfHandle, umfHandleSize); + if (umfRet != UMF_RESULT_SUCCESS || !umfHandle || *umfHandleSize == 0) + return UR_RESULT_ERROR_UNKNOWN; + std::memcpy(pIPCMemHandleData, umfHandle, *umfHandleSize); return UR_RESULT_SUCCESS; } -ur_result_t urIPCPutMemHandleExp(ur_context_handle_t, - ur_exp_ipc_mem_handle_t hIPCMem, - ur_bool_t putBackendResource) { - if (putBackendResource) { - auto umfRet = umfPutIPCHandle(hIPCMem->UMFHandle); - if (umfRet != UMF_RESULT_SUCCESS) - return UR_RESULT_ERROR_UNKNOWN; - } - std::free(hIPCMem); - return UR_RESULT_SUCCESS; +ur_result_t urIPCPutMemHandleExp(ur_context_handle_t, void *pIPCMemHandleData) { + auto umfRet = + umfPutIPCHandle(reinterpret_cast(pIPCMemHandleData)); + return umfRet == UMF_RESULT_SUCCESS ? UR_RESULT_SUCCESS + : UR_RESULT_ERROR_UNKNOWN; } ur_result_t urIPCOpenMemHandleExp(ur_context_handle_t hContext, @@ -2018,17 +2023,6 @@ ur_result_t urIPCCloseMemHandleExp(ur_context_handle_t, void *pMem) { : UR_RESULT_ERROR_UNKNOWN; } -ur_result_t urIPCGetMemHandleDataExp(ur_context_handle_t, - ur_exp_ipc_mem_handle_t hIPCMem, - void **ppIPCHandleData, - size_t *pIPCMemHandleDataSizeRet) { - if (ppIPCHandleData) - *ppIPCHandleData = hIPCMem->UMFHandle; - if (pIPCMemHandleDataSizeRet) - *pIPCMemHandleDataSizeRet = hIPCMem->HandleSize; - return UR_RESULT_SUCCESS; -} - } // namespace ur::level_zero // If indirect access tracking is enabled then performs reference counting, diff --git a/unified-runtime/source/adapters/level_zero/memory.hpp b/unified-runtime/source/adapters/level_zero/memory.hpp index cc3917f0e6b43..9d96eee2a499e 100644 --- a/unified-runtime/source/adapters/level_zero/memory.hpp +++ b/unified-runtime/source/adapters/level_zero/memory.hpp @@ -244,11 +244,6 @@ struct ur_image final : ur_mem_handle_t_ { ze_image_handle_t ZeImage; }; -struct ur_exp_ipc_mem_handle_t_ { - umf_ipc_handle_t UMFHandle = nullptr; - size_t HandleSize = 0; -}; - template ur_result_t createUrMemFromZeImage(ur_context_handle_t Context, ze_image_handle_t ZeImage, diff --git a/unified-runtime/source/adapters/level_zero/ur_interface_loader.cpp b/unified-runtime/source/adapters/level_zero/ur_interface_loader.cpp index fe2d9d49e6024..269a21f6c56ef 100644 --- a/unified-runtime/source/adapters/level_zero/ur_interface_loader.cpp +++ b/unified-runtime/source/adapters/level_zero/ur_interface_loader.cpp @@ -268,7 +268,6 @@ UR_APIEXPORT ur_result_t UR_APICALL urGetIPCExpProcAddrTable( pDdiTable->pfnPutMemHandleExp = ur::level_zero::urIPCPutMemHandleExp; pDdiTable->pfnOpenMemHandleExp = ur::level_zero::urIPCOpenMemHandleExp; pDdiTable->pfnCloseMemHandleExp = ur::level_zero::urIPCCloseMemHandleExp; - pDdiTable->pfnGetMemHandleDataExp = ur::level_zero::urIPCGetMemHandleDataExp; return result; } diff --git a/unified-runtime/source/adapters/level_zero/ur_interface_loader.hpp b/unified-runtime/source/adapters/level_zero/ur_interface_loader.hpp index d6af4f2042b2f..765d965b98154 100644 --- a/unified-runtime/source/adapters/level_zero/ur_interface_loader.hpp +++ b/unified-runtime/source/adapters/level_zero/ur_interface_loader.hpp @@ -769,19 +769,15 @@ ur_result_t urEnqueueTimestampRecordingExp( ur_queue_handle_t hQueue, bool blocking, uint32_t numEventsInWaitList, const ur_event_handle_t *phEventWaitList, ur_event_handle_t *phEvent); ur_result_t urIPCGetMemHandleExp(ur_context_handle_t hContext, void *pMem, - ur_exp_ipc_mem_handle_t *phIPCMem); + void *pIPCMemHandleData, + size_t *pIPCMemHandleDataSizeRet); ur_result_t urIPCPutMemHandleExp(ur_context_handle_t hContext, - ur_exp_ipc_mem_handle_t hIPCMem, - ur_bool_t putBackendResource); + void *pIPCMemHandleData); ur_result_t urIPCOpenMemHandleExp(ur_context_handle_t hContext, ur_device_handle_t hDevice, - void *ipcMemHandleData, + void *pIPCMemHandleData, size_t ipcMemHandleDataSize, void **ppMem); ur_result_t urIPCCloseMemHandleExp(ur_context_handle_t hContext, void *pMem); -ur_result_t urIPCGetMemHandleDataExp(ur_context_handle_t hContext, - ur_exp_ipc_mem_handle_t hIPCMem, - void **ppIPCHandleData, - size_t *pIPCMemHandleDataSizeRet); ur_result_t urMemoryExportAllocExportableMemoryExp( ur_context_handle_t hContext, ur_device_handle_t hDevice, size_t alignment, size_t size, ur_exp_external_mem_type_t handleTypeToExport, void **ppMem); diff --git a/unified-runtime/source/adapters/level_zero/v2/memory.cpp b/unified-runtime/source/adapters/level_zero/v2/memory.cpp index 7baf43f768557..42af135d086b4 100644 --- a/unified-runtime/source/adapters/level_zero/v2/memory.cpp +++ b/unified-runtime/source/adapters/level_zero/v2/memory.cpp @@ -782,33 +782,38 @@ ur_result_t urMemImageGetInfo(ur_mem_handle_t /*hMemory*/, } ur_result_t urIPCGetMemHandleExp(ur_context_handle_t, void *pMem, - ur_exp_ipc_mem_handle_t *phIPCMem) { - auto resHandle = std::make_unique(); - + void *pIPCMemHandleData, + size_t *pIPCMemHandleDataSizeRet) { umf_memory_pool_handle_t umfPool; auto umfRet = umfPoolByPtr(pMem, &umfPool); if (umfRet != UMF_RESULT_SUCCESS || !umfPool) return UR_RESULT_ERROR_UNKNOWN; - umfRet = umfGetIPCHandle(pMem, &resHandle->UMFHandle, &resHandle->HandleSize); - if (umfRet != UMF_RESULT_SUCCESS || !resHandle->UMFHandle || - resHandle->HandleSize == 0) - return UR_RESULT_ERROR_UNKNOWN; + // Fast path for returning the size of the handle only. + if (!pIPCMemHandleData) { + auto umfRet = umfPoolGetIPCHandleSize(umfPool, pIPCMemHandleDataSizeRet); + if (umfRet != UMF_RESULT_SUCCESS || *pIPCMemHandleDataSizeRet == 0) + return UR_RESULT_ERROR_UNKNOWN; + return UR_RESULT_SUCCESS; + } - *phIPCMem = resHandle.release(); + size_t fallbackUMFHandleSize = 0; + size_t *umfHandleSize = pIPCMemHandleDataSizeRet != nullptr + ? pIPCMemHandleDataSizeRet + : &fallbackUMFHandleSize; + umf_ipc_handle_t umfHandle; + umfRet = umfGetIPCHandle(pMem, &umfHandle, umfHandleSize); + if (umfRet != UMF_RESULT_SUCCESS || !umfHandle || *umfHandleSize == 0) + return UR_RESULT_ERROR_UNKNOWN; + std::memcpy(pIPCMemHandleData, umfHandle, *umfHandleSize); return UR_RESULT_SUCCESS; } -ur_result_t urIPCPutMemHandleExp(ur_context_handle_t, - ur_exp_ipc_mem_handle_t hIPCMem, - ur_bool_t putBackendResource) { - if (putBackendResource) { - auto umfRet = umfPutIPCHandle(hIPCMem->UMFHandle); - if (umfRet != UMF_RESULT_SUCCESS) - return UR_RESULT_ERROR_UNKNOWN; - } - std::free(hIPCMem); - return UR_RESULT_SUCCESS; +ur_result_t urIPCPutMemHandleExp(ur_context_handle_t, void *pIPCMemHandleData) { + auto umfRet = + umfPutIPCHandle(reinterpret_cast(pIPCMemHandleData)); + return umfRet == UMF_RESULT_SUCCESS ? UR_RESULT_SUCCESS + : UR_RESULT_ERROR_UNKNOWN; } ur_result_t urIPCOpenMemHandleExp(ur_context_handle_t hContext, @@ -848,15 +853,4 @@ ur_result_t urIPCCloseMemHandleExp(ur_context_handle_t, void *pMem) { : UR_RESULT_ERROR_UNKNOWN; } -ur_result_t urIPCGetMemHandleDataExp(ur_context_handle_t, - ur_exp_ipc_mem_handle_t hIPCMem, - void **ppIPCHandleData, - size_t *pIPCMemHandleDataSizeRet) { - if (ppIPCHandleData) - *ppIPCHandleData = hIPCMem->UMFHandle; - if (pIPCMemHandleDataSizeRet) - *pIPCMemHandleDataSizeRet = hIPCMem->HandleSize; - return UR_RESULT_SUCCESS; -} - } // namespace ur::level_zero diff --git a/unified-runtime/source/adapters/level_zero/v2/memory.hpp b/unified-runtime/source/adapters/level_zero/v2/memory.hpp index c61a171c511c4..813d09bf864c2 100644 --- a/unified-runtime/source/adapters/level_zero/v2/memory.hpp +++ b/unified-runtime/source/adapters/level_zero/v2/memory.hpp @@ -293,8 +293,3 @@ struct ur_mem_handle_t_ : ur::handle_base { ur_mem_sub_buffer_t, ur_mem_image_t> mem; }; - -struct ur_exp_ipc_mem_handle_t_ { - umf_ipc_handle_t UMFHandle = nullptr; - size_t HandleSize = 0; -}; diff --git a/unified-runtime/source/adapters/mock/ur_mockddi.cpp b/unified-runtime/source/adapters/mock/ur_mockddi.cpp index 5314fdfdd6c93..719f6ec6f85c8 100644 --- a/unified-runtime/source/adapters/mock/ur_mockddi.cpp +++ b/unified-runtime/source/adapters/mock/ur_mockddi.cpp @@ -11311,11 +11311,14 @@ __urdlllocal ur_result_t UR_APICALL urIPCGetMemHandleExp( ur_context_handle_t hContext, /// [in] pointer to device USM memory void *pMem, - /// [out][alloc] pointer to the resulting IPC memory handle - ur_exp_ipc_mem_handle_t *phIPCMem) try { + /// [out][optional] a pointer to the IPC memory handle data + void *pIPCMemHandleData, + /// [out][optional] size of the resulting IPC memory handle data + size_t *pIPCMemHandleDataSizeRet) try { ur_result_t result = UR_RESULT_SUCCESS; - ur_ipc_get_mem_handle_exp_params_t params = {&hContext, &pMem, &phIPCMem}; + ur_ipc_get_mem_handle_exp_params_t params = { + &hContext, &pMem, &pIPCMemHandleData, &pIPCMemHandleDataSizeRet}; auto beforeCallback = reinterpret_cast( mock::getCallbacks().get_before_callback("urIPCGetMemHandleExp")); @@ -11355,16 +11358,11 @@ __urdlllocal ur_result_t UR_APICALL urIPCGetMemHandleExp( __urdlllocal ur_result_t UR_APICALL urIPCPutMemHandleExp( /// [in] handle of the context object ur_context_handle_t hContext, - /// [in] the IPC memory handle - ur_exp_ipc_mem_handle_t hIPCMem, - /// [in] true if the backend resource should be released, false if the - /// backend resource will be released when freeing the corresponding - /// device USM memory - ur_bool_t putBackendResource) try { + /// [in] a pointer to the IPC memory handle data + void *pIPCMemHandleData) try { ur_result_t result = UR_RESULT_SUCCESS; - ur_ipc_put_mem_handle_exp_params_t params = {&hContext, &hIPCMem, - &putBackendResource}; + ur_ipc_put_mem_handle_exp_params_t params = {&hContext, &pIPCMemHandleData}; auto beforeCallback = reinterpret_cast( mock::getCallbacks().get_before_callback("urIPCPutMemHandleExp")); @@ -11408,7 +11406,7 @@ __urdlllocal ur_result_t UR_APICALL urIPCOpenMemHandleExp( /// was allocated on ur_device_handle_t hDevice, /// [in] the IPC memory handle data - void *ipcMemHandleData, + void *pIPCMemHandleData, /// [in] size of the IPC memory handle data size_t ipcMemHandleDataSize, /// [out] pointer to a pointer to device USM memory @@ -11416,7 +11414,7 @@ __urdlllocal ur_result_t UR_APICALL urIPCOpenMemHandleExp( ur_result_t result = UR_RESULT_SUCCESS; ur_ipc_open_mem_handle_exp_params_t params = { - &hContext, &hDevice, &ipcMemHandleData, &ipcMemHandleDataSize, &ppMem}; + &hContext, &hDevice, &pIPCMemHandleData, &ipcMemHandleDataSize, &ppMem}; auto beforeCallback = reinterpret_cast( mock::getCallbacks().get_before_callback("urIPCOpenMemHandleExp")); @@ -11495,55 +11493,6 @@ __urdlllocal ur_result_t UR_APICALL urIPCCloseMemHandleExp( return exceptionToResult(std::current_exception()); } -/////////////////////////////////////////////////////////////////////////////// -/// @brief Intercept function for urIPCGetMemHandleDataExp -__urdlllocal ur_result_t UR_APICALL urIPCGetMemHandleDataExp( - /// [in] handle of the context object - ur_context_handle_t hContext, - /// [in] the IPC memory handle - ur_exp_ipc_mem_handle_t hIPCMem, - /// [out][optional] a pointer to the IPC memory handle data - void **ppIPCHandleData, - /// [out][optional] size of the resulting IPC memory handle data - size_t *pIPCMemHandleDataSizeRet) try { - ur_result_t result = UR_RESULT_SUCCESS; - - ur_ipc_get_mem_handle_data_exp_params_t params = { - &hContext, &hIPCMem, &ppIPCHandleData, &pIPCMemHandleDataSizeRet}; - - auto beforeCallback = reinterpret_cast( - mock::getCallbacks().get_before_callback("urIPCGetMemHandleDataExp")); - if (beforeCallback) { - result = beforeCallback(¶ms); - if (result != UR_RESULT_SUCCESS) { - return result; - } - } - - auto replaceCallback = reinterpret_cast( - mock::getCallbacks().get_replace_callback("urIPCGetMemHandleDataExp")); - if (replaceCallback) { - result = replaceCallback(¶ms); - } else { - - result = UR_RESULT_SUCCESS; - } - - if (result != UR_RESULT_SUCCESS) { - return result; - } - - auto afterCallback = reinterpret_cast( - mock::getCallbacks().get_after_callback("urIPCGetMemHandleDataExp")); - if (afterCallback) { - return afterCallback(¶ms); - } - - return result; -} catch (...) { - return exceptionToResult(std::current_exception()); -} - /////////////////////////////////////////////////////////////////////////////// /// @brief Intercept function for urMemoryExportAllocExportableMemoryExp __urdlllocal ur_result_t UR_APICALL urMemoryExportAllocExportableMemoryExp( @@ -12750,8 +12699,6 @@ UR_DLLEXPORT ur_result_t UR_APICALL urGetIPCExpProcAddrTable( pDdiTable->pfnCloseMemHandleExp = driver::urIPCCloseMemHandleExp; - pDdiTable->pfnGetMemHandleDataExp = driver::urIPCGetMemHandleDataExp; - return result; } catch (...) { return exceptionToResult(std::current_exception()); diff --git a/unified-runtime/source/adapters/native_cpu/memory.cpp b/unified-runtime/source/adapters/native_cpu/memory.cpp index 957c97d1f820e..eef3fdb6d7310 100644 --- a/unified-runtime/source/adapters/native_cpu/memory.cpp +++ b/unified-runtime/source/adapters/native_cpu/memory.cpp @@ -140,12 +140,12 @@ UR_APIEXPORT ur_result_t UR_APICALL urMemImageGetInfo( } UR_APIEXPORT ur_result_t UR_APICALL -urIPCGetMemHandleExp(ur_context_handle_t, void *, ur_exp_ipc_mem_handle_t *) { +urIPCGetMemHandleExp(ur_context_handle_t, void *, void *, size_t*) { return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; } -UR_APIEXPORT ur_result_t UR_APICALL -urIPCPutMemHandleExp(ur_context_handle_t, ur_exp_ipc_mem_handle_t, ur_bool_t) { +UR_APIEXPORT ur_result_t UR_APICALL urIPCPutMemHandleExp(ur_context_handle_t, + void *) { return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; } @@ -160,8 +160,3 @@ UR_APIEXPORT ur_result_t UR_APICALL urIPCCloseMemHandleExp(ur_context_handle_t, void *) { return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; } - -UR_APIEXPORT ur_result_t UR_APICALL urIPCGetMemHandleDataExp( - ur_context_handle_t, ur_exp_ipc_mem_handle_t, void **, size_t *) { - return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; -} diff --git a/unified-runtime/source/adapters/native_cpu/memory.hpp b/unified-runtime/source/adapters/native_cpu/memory.hpp index 6285287e2457b..ca6e3e77f5e87 100644 --- a/unified-runtime/source/adapters/native_cpu/memory.hpp +++ b/unified-runtime/source/adapters/native_cpu/memory.hpp @@ -69,6 +69,3 @@ struct ur_buffer final : ur_mem_handle_t_ { size_t Origin; // only valid if Parent != nullptr } SubBuffer; }; - -// IPC is currently not supported in the native CPU adaptor. -struct ur_exp_ipc_mem_handle_t_ {}; diff --git a/unified-runtime/source/adapters/native_cpu/ur_interface_loader.cpp b/unified-runtime/source/adapters/native_cpu/ur_interface_loader.cpp index f0c36bb6dadc2..492f005c866dd 100644 --- a/unified-runtime/source/adapters/native_cpu/ur_interface_loader.cpp +++ b/unified-runtime/source/adapters/native_cpu/ur_interface_loader.cpp @@ -446,7 +446,6 @@ UR_DLLEXPORT ur_result_t UR_APICALL urGetIPCExpProcAddrTable( pDdiTable->pfnPutMemHandleExp = urIPCPutMemHandleExp; pDdiTable->pfnOpenMemHandleExp = urIPCOpenMemHandleExp; pDdiTable->pfnCloseMemHandleExp = urIPCCloseMemHandleExp; - pDdiTable->pfnGetMemHandleDataExp = urIPCGetMemHandleDataExp; return UR_RESULT_SUCCESS; } diff --git a/unified-runtime/source/adapters/offload/memory.cpp b/unified-runtime/source/adapters/offload/memory.cpp index 716d4ef8e89ef..5d25e2b40c5d0 100644 --- a/unified-runtime/source/adapters/offload/memory.cpp +++ b/unified-runtime/source/adapters/offload/memory.cpp @@ -163,12 +163,12 @@ UR_APIEXPORT ur_result_t UR_APICALL urMemImageGetInfo(ur_mem_handle_t, } UR_APIEXPORT ur_result_t UR_APICALL -urIPCGetMemHandleExp(ur_context_handle_t, void *, ur_exp_ipc_mem_handle_t *) { +urIPCGetMemHandleExp(ur_context_handle_t, void *, void *, size_t*) { return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; } -UR_APIEXPORT ur_result_t UR_APICALL -urIPCPutMemHandleExp(ur_context_handle_t, ur_exp_ipc_mem_handle_t, ur_bool_t) { +UR_APIEXPORT ur_result_t UR_APICALL urIPCPutMemHandleExp(ur_context_handle_t, + void *) { return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; } @@ -183,8 +183,3 @@ UR_APIEXPORT ur_result_t UR_APICALL urIPCCloseMemHandleExp(ur_context_handle_t, void *) { return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; } - -UR_APIEXPORT ur_result_t UR_APICALL urIPCGetMemHandleDataExp( - ur_context_handle_t, ur_exp_ipc_mem_handle_t, void **, size_t *) { - return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; -} diff --git a/unified-runtime/source/adapters/offload/memory.hpp b/unified-runtime/source/adapters/offload/memory.hpp index a4742d7b288d3..59b62ea12961a 100644 --- a/unified-runtime/source/adapters/offload/memory.hpp +++ b/unified-runtime/source/adapters/offload/memory.hpp @@ -117,6 +117,3 @@ struct ur_mem_handle_t_ : RefCounted { return nullptr; } }; - -// IPC is currently not supported in the offload adaptor. -struct ur_exp_ipc_mem_handle_t_ {}; diff --git a/unified-runtime/source/adapters/offload/ur_interface_loader.cpp b/unified-runtime/source/adapters/offload/ur_interface_loader.cpp index 6c50db68b97fe..0e1cbbf9994e4 100644 --- a/unified-runtime/source/adapters/offload/ur_interface_loader.cpp +++ b/unified-runtime/source/adapters/offload/ur_interface_loader.cpp @@ -399,7 +399,6 @@ UR_DLLEXPORT ur_result_t UR_APICALL urGetIPCExpProcAddrTable( pDdiTable->pfnPutMemHandleExp = urIPCPutMemHandleExp; pDdiTable->pfnOpenMemHandleExp = urIPCOpenMemHandleExp; pDdiTable->pfnCloseMemHandleExp = urIPCCloseMemHandleExp; - pDdiTable->pfnGetMemHandleDataExp = urIPCGetMemHandleDataExp; return UR_RESULT_SUCCESS; } diff --git a/unified-runtime/source/adapters/opencl/memory.cpp b/unified-runtime/source/adapters/opencl/memory.cpp index 0fe1192d588f0..e913b486ded21 100644 --- a/unified-runtime/source/adapters/opencl/memory.cpp +++ b/unified-runtime/source/adapters/opencl/memory.cpp @@ -581,12 +581,12 @@ UR_APIEXPORT ur_result_t UR_APICALL urMemRelease(ur_mem_handle_t hMem) { } UR_APIEXPORT ur_result_t UR_APICALL -urIPCGetMemHandleExp(ur_context_handle_t, void *, ur_exp_ipc_mem_handle_t *) { +urIPCGetMemHandleExp(ur_context_handle_t, void *, void *, size_t*) { return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; } UR_APIEXPORT ur_result_t UR_APICALL -urIPCPutMemHandleExp(ur_context_handle_t, ur_exp_ipc_mem_handle_t, ur_bool_t) { +urIPCPutMemHandleExp(ur_context_handle_t, void *) { return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; } @@ -601,8 +601,3 @@ UR_APIEXPORT ur_result_t UR_APICALL urIPCCloseMemHandleExp(ur_context_handle_t, void *) { return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; } - -UR_APIEXPORT ur_result_t UR_APICALL urIPCGetMemHandleDataExp( - ur_context_handle_t, ur_exp_ipc_mem_handle_t, void **, size_t *) { - return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; -} diff --git a/unified-runtime/source/adapters/opencl/memory.hpp b/unified-runtime/source/adapters/opencl/memory.hpp index f799fdf9b3a29..025b7f4acef8b 100644 --- a/unified-runtime/source/adapters/opencl/memory.hpp +++ b/unified-runtime/source/adapters/opencl/memory.hpp @@ -41,6 +41,3 @@ struct ur_mem_handle_t_ : ur::opencl::handle_base { ur_context_handle_t Ctx, ur_mem_handle_t &Mem); }; - -// IPC is currently not supported in the OpenCL adaptor. -struct ur_exp_ipc_mem_handle_t_ {}; diff --git a/unified-runtime/source/adapters/opencl/ur_interface_loader.cpp b/unified-runtime/source/adapters/opencl/ur_interface_loader.cpp index 18585431b7fad..cf473f6526808 100644 --- a/unified-runtime/source/adapters/opencl/ur_interface_loader.cpp +++ b/unified-runtime/source/adapters/opencl/ur_interface_loader.cpp @@ -449,7 +449,6 @@ UR_DLLEXPORT ur_result_t UR_APICALL urGetIPCExpProcAddrTable( pDdiTable->pfnPutMemHandleExp = urIPCPutMemHandleExp; pDdiTable->pfnOpenMemHandleExp = urIPCOpenMemHandleExp; pDdiTable->pfnCloseMemHandleExp = urIPCCloseMemHandleExp; - pDdiTable->pfnGetMemHandleDataExp = urIPCGetMemHandleDataExp; return UR_RESULT_SUCCESS; } diff --git a/unified-runtime/source/loader/layers/tracing/ur_trcddi.cpp b/unified-runtime/source/loader/layers/tracing/ur_trcddi.cpp index 51b4be076fdbd..b37fe358cdf9c 100644 --- a/unified-runtime/source/loader/layers/tracing/ur_trcddi.cpp +++ b/unified-runtime/source/loader/layers/tracing/ur_trcddi.cpp @@ -9581,21 +9581,25 @@ __urdlllocal ur_result_t UR_APICALL urIPCGetMemHandleExp( ur_context_handle_t hContext, /// [in] pointer to device USM memory void *pMem, - /// [out][alloc] pointer to the resulting IPC memory handle - ur_exp_ipc_mem_handle_t *phIPCMem) { + /// [out][optional] a pointer to the IPC memory handle data + void *pIPCMemHandleData, + /// [out][optional] size of the resulting IPC memory handle data + size_t *pIPCMemHandleDataSizeRet) { auto pfnGetMemHandleExp = getContext()->urDdiTable.IPCExp.pfnGetMemHandleExp; if (nullptr == pfnGetMemHandleExp) return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; - ur_ipc_get_mem_handle_exp_params_t params = {&hContext, &pMem, &phIPCMem}; + ur_ipc_get_mem_handle_exp_params_t params = { + &hContext, &pMem, &pIPCMemHandleData, &pIPCMemHandleDataSizeRet}; uint64_t instance = getContext()->notify_begin( UR_FUNCTION_IPC_GET_MEM_HANDLE_EXP, "urIPCGetMemHandleExp", ¶ms); auto &logger = getContext()->logger; UR_LOG_L(logger, INFO, " ---> urIPCGetMemHandleExp\n"); - ur_result_t result = pfnGetMemHandleExp(hContext, pMem, phIPCMem); + ur_result_t result = pfnGetMemHandleExp(hContext, pMem, pIPCMemHandleData, + pIPCMemHandleDataSizeRet); getContext()->notify_end(UR_FUNCTION_IPC_GET_MEM_HANDLE_EXP, "urIPCGetMemHandleExp", ¶ms, &result, instance); @@ -9616,27 +9620,21 @@ __urdlllocal ur_result_t UR_APICALL urIPCGetMemHandleExp( __urdlllocal ur_result_t UR_APICALL urIPCPutMemHandleExp( /// [in] handle of the context object ur_context_handle_t hContext, - /// [in] the IPC memory handle - ur_exp_ipc_mem_handle_t hIPCMem, - /// [in] true if the backend resource should be released, false if the - /// backend resource will be released when freeing the corresponding - /// device USM memory - ur_bool_t putBackendResource) { + /// [in] a pointer to the IPC memory handle data + void *pIPCMemHandleData) { auto pfnPutMemHandleExp = getContext()->urDdiTable.IPCExp.pfnPutMemHandleExp; if (nullptr == pfnPutMemHandleExp) return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; - ur_ipc_put_mem_handle_exp_params_t params = {&hContext, &hIPCMem, - &putBackendResource}; + ur_ipc_put_mem_handle_exp_params_t params = {&hContext, &pIPCMemHandleData}; uint64_t instance = getContext()->notify_begin( UR_FUNCTION_IPC_PUT_MEM_HANDLE_EXP, "urIPCPutMemHandleExp", ¶ms); auto &logger = getContext()->logger; UR_LOG_L(logger, INFO, " ---> urIPCPutMemHandleExp\n"); - ur_result_t result = - pfnPutMemHandleExp(hContext, hIPCMem, putBackendResource); + ur_result_t result = pfnPutMemHandleExp(hContext, pIPCMemHandleData); getContext()->notify_end(UR_FUNCTION_IPC_PUT_MEM_HANDLE_EXP, "urIPCPutMemHandleExp", ¶ms, &result, instance); @@ -9661,7 +9659,7 @@ __urdlllocal ur_result_t UR_APICALL urIPCOpenMemHandleExp( /// was allocated on ur_device_handle_t hDevice, /// [in] the IPC memory handle data - void *ipcMemHandleData, + void *pIPCMemHandleData, /// [in] size of the IPC memory handle data size_t ipcMemHandleDataSize, /// [out] pointer to a pointer to device USM memory @@ -9673,14 +9671,14 @@ __urdlllocal ur_result_t UR_APICALL urIPCOpenMemHandleExp( return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; ur_ipc_open_mem_handle_exp_params_t params = { - &hContext, &hDevice, &ipcMemHandleData, &ipcMemHandleDataSize, &ppMem}; + &hContext, &hDevice, &pIPCMemHandleData, &ipcMemHandleDataSize, &ppMem}; uint64_t instance = getContext()->notify_begin( UR_FUNCTION_IPC_OPEN_MEM_HANDLE_EXP, "urIPCOpenMemHandleExp", ¶ms); auto &logger = getContext()->logger; UR_LOG_L(logger, INFO, " ---> urIPCOpenMemHandleExp\n"); - ur_result_t result = pfnOpenMemHandleExp(hContext, hDevice, ipcMemHandleData, + ur_result_t result = pfnOpenMemHandleExp(hContext, hDevice, pIPCMemHandleData, ipcMemHandleDataSize, ppMem); getContext()->notify_end(UR_FUNCTION_IPC_OPEN_MEM_HANDLE_EXP, @@ -9734,50 +9732,6 @@ __urdlllocal ur_result_t UR_APICALL urIPCCloseMemHandleExp( return result; } -/////////////////////////////////////////////////////////////////////////////// -/// @brief Intercept function for urIPCGetMemHandleDataExp -__urdlllocal ur_result_t UR_APICALL urIPCGetMemHandleDataExp( - /// [in] handle of the context object - ur_context_handle_t hContext, - /// [in] the IPC memory handle - ur_exp_ipc_mem_handle_t hIPCMem, - /// [out][optional] a pointer to the IPC memory handle data - void **ppIPCHandleData, - /// [out][optional] size of the resulting IPC memory handle data - size_t *pIPCMemHandleDataSizeRet) { - auto pfnGetMemHandleDataExp = - getContext()->urDdiTable.IPCExp.pfnGetMemHandleDataExp; - - if (nullptr == pfnGetMemHandleDataExp) - return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; - - ur_ipc_get_mem_handle_data_exp_params_t params = { - &hContext, &hIPCMem, &ppIPCHandleData, &pIPCMemHandleDataSizeRet}; - uint64_t instance = - getContext()->notify_begin(UR_FUNCTION_IPC_GET_MEM_HANDLE_DATA_EXP, - "urIPCGetMemHandleDataExp", ¶ms); - - auto &logger = getContext()->logger; - UR_LOG_L(logger, INFO, " ---> urIPCGetMemHandleDataExp\n"); - - ur_result_t result = pfnGetMemHandleDataExp( - hContext, hIPCMem, ppIPCHandleData, pIPCMemHandleDataSizeRet); - - getContext()->notify_end(UR_FUNCTION_IPC_GET_MEM_HANDLE_DATA_EXP, - "urIPCGetMemHandleDataExp", ¶ms, &result, - instance); - - if (logger.getLevel() <= UR_LOGGER_LEVEL_INFO) { - std::ostringstream args_str; - ur::extras::printFunctionParams( - args_str, UR_FUNCTION_IPC_GET_MEM_HANDLE_DATA_EXP, ¶ms); - UR_LOG_L(logger, INFO, " <--- urIPCGetMemHandleDataExp({}) -> {};\n", - args_str.str(), result); - } - - return result; -} - /////////////////////////////////////////////////////////////////////////////// /// @brief Intercept function for urMemoryExportAllocExportableMemoryExp __urdlllocal ur_result_t UR_APICALL urMemoryExportAllocExportableMemoryExp( @@ -11024,10 +10978,6 @@ __urdlllocal ur_result_t UR_APICALL urGetIPCExpProcAddrTable( dditable.pfnCloseMemHandleExp = pDdiTable->pfnCloseMemHandleExp; pDdiTable->pfnCloseMemHandleExp = ur_tracing_layer::urIPCCloseMemHandleExp; - dditable.pfnGetMemHandleDataExp = pDdiTable->pfnGetMemHandleDataExp; - pDdiTable->pfnGetMemHandleDataExp = - ur_tracing_layer::urIPCGetMemHandleDataExp; - return result; } /////////////////////////////////////////////////////////////////////////////// diff --git a/unified-runtime/source/loader/layers/validation/ur_valddi.cpp b/unified-runtime/source/loader/layers/validation/ur_valddi.cpp index 5f6af5a55f8a4..8d2d577b2b613 100644 --- a/unified-runtime/source/loader/layers/validation/ur_valddi.cpp +++ b/unified-runtime/source/loader/layers/validation/ur_valddi.cpp @@ -10344,8 +10344,10 @@ __urdlllocal ur_result_t UR_APICALL urIPCGetMemHandleExp( ur_context_handle_t hContext, /// [in] pointer to device USM memory void *pMem, - /// [out][alloc] pointer to the resulting IPC memory handle - ur_exp_ipc_mem_handle_t *phIPCMem) { + /// [out][optional] a pointer to the IPC memory handle data + void *pIPCMemHandleData, + /// [out][optional] size of the resulting IPC memory handle data + size_t *pIPCMemHandleDataSizeRet) { auto pfnGetMemHandleExp = getContext()->urDdiTable.IPCExp.pfnGetMemHandleExp; if (nullptr == pfnGetMemHandleExp) { @@ -10353,7 +10355,10 @@ __urdlllocal ur_result_t UR_APICALL urIPCGetMemHandleExp( } if (getContext()->enableParameterValidation) { - if (NULL == phIPCMem) + if (NULL == pIPCMemHandleData) + return UR_RESULT_ERROR_INVALID_NULL_POINTER; + + if (NULL == pIPCMemHandleDataSizeRet) return UR_RESULT_ERROR_INVALID_NULL_POINTER; if (NULL == hContext) @@ -10365,7 +10370,8 @@ __urdlllocal ur_result_t UR_APICALL urIPCGetMemHandleExp( URLOG_CTX_INVALID_REFERENCE(hContext); } - ur_result_t result = pfnGetMemHandleExp(hContext, pMem, phIPCMem); + ur_result_t result = pfnGetMemHandleExp(hContext, pMem, pIPCMemHandleData, + pIPCMemHandleDataSizeRet); return result; } @@ -10375,12 +10381,8 @@ __urdlllocal ur_result_t UR_APICALL urIPCGetMemHandleExp( __urdlllocal ur_result_t UR_APICALL urIPCPutMemHandleExp( /// [in] handle of the context object ur_context_handle_t hContext, - /// [in] the IPC memory handle - ur_exp_ipc_mem_handle_t hIPCMem, - /// [in] true if the backend resource should be released, false if the - /// backend resource will be released when freeing the corresponding - /// device USM memory - ur_bool_t putBackendResource) { + /// [in] a pointer to the IPC memory handle data + void *pIPCMemHandleData) { auto pfnPutMemHandleExp = getContext()->urDdiTable.IPCExp.pfnPutMemHandleExp; if (nullptr == pfnPutMemHandleExp) { @@ -10388,10 +10390,10 @@ __urdlllocal ur_result_t UR_APICALL urIPCPutMemHandleExp( } if (getContext()->enableParameterValidation) { - if (NULL == hContext) - return UR_RESULT_ERROR_INVALID_NULL_HANDLE; + if (NULL == pIPCMemHandleData) + return UR_RESULT_ERROR_INVALID_NULL_POINTER; - if (NULL == hIPCMem) + if (NULL == hContext) return UR_RESULT_ERROR_INVALID_NULL_HANDLE; } @@ -10400,8 +10402,7 @@ __urdlllocal ur_result_t UR_APICALL urIPCPutMemHandleExp( URLOG_CTX_INVALID_REFERENCE(hContext); } - ur_result_t result = - pfnPutMemHandleExp(hContext, hIPCMem, putBackendResource); + ur_result_t result = pfnPutMemHandleExp(hContext, pIPCMemHandleData); return result; } @@ -10415,7 +10416,7 @@ __urdlllocal ur_result_t UR_APICALL urIPCOpenMemHandleExp( /// was allocated on ur_device_handle_t hDevice, /// [in] the IPC memory handle data - void *ipcMemHandleData, + void *pIPCMemHandleData, /// [in] size of the IPC memory handle data size_t ipcMemHandleDataSize, /// [out] pointer to a pointer to device USM memory @@ -10428,7 +10429,7 @@ __urdlllocal ur_result_t UR_APICALL urIPCOpenMemHandleExp( } if (getContext()->enableParameterValidation) { - if (NULL == ipcMemHandleData) + if (NULL == pIPCMemHandleData) return UR_RESULT_ERROR_INVALID_NULL_POINTER; if (NULL == ppMem) @@ -10451,7 +10452,7 @@ __urdlllocal ur_result_t UR_APICALL urIPCOpenMemHandleExp( URLOG_CTX_INVALID_REFERENCE(hDevice); } - ur_result_t result = pfnOpenMemHandleExp(hContext, hDevice, ipcMemHandleData, + ur_result_t result = pfnOpenMemHandleExp(hContext, hDevice, pIPCMemHandleData, ipcMemHandleDataSize, ppMem); return result; @@ -10489,43 +10490,6 @@ __urdlllocal ur_result_t UR_APICALL urIPCCloseMemHandleExp( return result; } -/////////////////////////////////////////////////////////////////////////////// -/// @brief Intercept function for urIPCGetMemHandleDataExp -__urdlllocal ur_result_t UR_APICALL urIPCGetMemHandleDataExp( - /// [in] handle of the context object - ur_context_handle_t hContext, - /// [in] the IPC memory handle - ur_exp_ipc_mem_handle_t hIPCMem, - /// [out][optional] a pointer to the IPC memory handle data - void **ppIPCHandleData, - /// [out][optional] size of the resulting IPC memory handle data - size_t *pIPCMemHandleDataSizeRet) { - auto pfnGetMemHandleDataExp = - getContext()->urDdiTable.IPCExp.pfnGetMemHandleDataExp; - - if (nullptr == pfnGetMemHandleDataExp) { - return UR_RESULT_ERROR_UNINITIALIZED; - } - - if (getContext()->enableParameterValidation) { - if (NULL == hContext) - return UR_RESULT_ERROR_INVALID_NULL_HANDLE; - - if (NULL == hIPCMem) - return UR_RESULT_ERROR_INVALID_NULL_HANDLE; - } - - if (getContext()->enableLifetimeValidation && - !getContext()->refCountContext->isReferenceValid(hContext)) { - URLOG_CTX_INVALID_REFERENCE(hContext); - } - - ur_result_t result = pfnGetMemHandleDataExp( - hContext, hIPCMem, ppIPCHandleData, pIPCMemHandleDataSizeRet); - - return result; -} - /////////////////////////////////////////////////////////////////////////////// /// @brief Intercept function for urMemoryExportAllocExportableMemoryExp __urdlllocal ur_result_t UR_APICALL urMemoryExportAllocExportableMemoryExp( @@ -11812,10 +11776,6 @@ UR_DLLEXPORT ur_result_t UR_APICALL urGetIPCExpProcAddrTable( dditable.pfnCloseMemHandleExp = pDdiTable->pfnCloseMemHandleExp; pDdiTable->pfnCloseMemHandleExp = ur_validation_layer::urIPCCloseMemHandleExp; - dditable.pfnGetMemHandleDataExp = pDdiTable->pfnGetMemHandleDataExp; - pDdiTable->pfnGetMemHandleDataExp = - ur_validation_layer::urIPCGetMemHandleDataExp; - return result; } diff --git a/unified-runtime/source/loader/loader.def.in b/unified-runtime/source/loader/loader.def.in index a09ecdf084ddd..f0b8f93e94a55 100644 --- a/unified-runtime/source/loader/loader.def.in +++ b/unified-runtime/source/loader/loader.def.in @@ -133,7 +133,6 @@ EXPORTS urGetUsmP2PExpProcAddrTable urGetVirtualMemProcAddrTable urIPCCloseMemHandleExp - urIPCGetMemHandleDataExp urIPCGetMemHandleExp urIPCOpenMemHandleExp urIPCPutMemHandleExp @@ -368,7 +367,6 @@ EXPORTS urPrintImageFormat urPrintImageInfo urPrintIpcCloseMemHandleExpParams - urPrintIpcGetMemHandleDataExpParams urPrintIpcGetMemHandleExpParams urPrintIpcOpenMemHandleExpParams urPrintIpcPutMemHandleExpParams diff --git a/unified-runtime/source/loader/loader.map.in b/unified-runtime/source/loader/loader.map.in index 08c16c8e43c42..8e19fd1db9e19 100644 --- a/unified-runtime/source/loader/loader.map.in +++ b/unified-runtime/source/loader/loader.map.in @@ -133,7 +133,6 @@ urGetUsmP2PExpProcAddrTable; urGetVirtualMemProcAddrTable; urIPCCloseMemHandleExp; - urIPCGetMemHandleDataExp; urIPCGetMemHandleExp; urIPCOpenMemHandleExp; urIPCPutMemHandleExp; @@ -368,7 +367,6 @@ urPrintImageFormat; urPrintImageInfo; urPrintIpcCloseMemHandleExpParams; - urPrintIpcGetMemHandleDataExpParams; urPrintIpcGetMemHandleExpParams; urPrintIpcOpenMemHandleExpParams; urPrintIpcPutMemHandleExpParams; diff --git a/unified-runtime/source/loader/ur_ldrddi.cpp b/unified-runtime/source/loader/ur_ldrddi.cpp index b6a7b812b3feb..1fb8c04b4bc3c 100644 --- a/unified-runtime/source/loader/ur_ldrddi.cpp +++ b/unified-runtime/source/loader/ur_ldrddi.cpp @@ -5459,8 +5459,10 @@ __urdlllocal ur_result_t UR_APICALL urIPCGetMemHandleExp( ur_context_handle_t hContext, /// [in] pointer to device USM memory void *pMem, - /// [out][alloc] pointer to the resulting IPC memory handle - ur_exp_ipc_mem_handle_t *phIPCMem) { + /// [out][optional] a pointer to the IPC memory handle data + void *pIPCMemHandleData, + /// [out][optional] size of the resulting IPC memory handle data + size_t *pIPCMemHandleDataSizeRet) { auto *dditable = *reinterpret_cast(hContext); @@ -5469,7 +5471,8 @@ __urdlllocal ur_result_t UR_APICALL urIPCGetMemHandleExp( return UR_RESULT_ERROR_UNINITIALIZED; // forward to device-platform - return pfnGetMemHandleExp(hContext, pMem, phIPCMem); + return pfnGetMemHandleExp(hContext, pMem, pIPCMemHandleData, + pIPCMemHandleDataSizeRet); } /////////////////////////////////////////////////////////////////////////////// @@ -5477,12 +5480,8 @@ __urdlllocal ur_result_t UR_APICALL urIPCGetMemHandleExp( __urdlllocal ur_result_t UR_APICALL urIPCPutMemHandleExp( /// [in] handle of the context object ur_context_handle_t hContext, - /// [in] the IPC memory handle - ur_exp_ipc_mem_handle_t hIPCMem, - /// [in] true if the backend resource should be released, false if the - /// backend resource will be released when freeing the corresponding - /// device USM memory - ur_bool_t putBackendResource) { + /// [in] a pointer to the IPC memory handle data + void *pIPCMemHandleData) { auto *dditable = *reinterpret_cast(hContext); @@ -5491,7 +5490,7 @@ __urdlllocal ur_result_t UR_APICALL urIPCPutMemHandleExp( return UR_RESULT_ERROR_UNINITIALIZED; // forward to device-platform - return pfnPutMemHandleExp(hContext, hIPCMem, putBackendResource); + return pfnPutMemHandleExp(hContext, pIPCMemHandleData); } /////////////////////////////////////////////////////////////////////////////// @@ -5503,7 +5502,7 @@ __urdlllocal ur_result_t UR_APICALL urIPCOpenMemHandleExp( /// was allocated on ur_device_handle_t hDevice, /// [in] the IPC memory handle data - void *ipcMemHandleData, + void *pIPCMemHandleData, /// [in] size of the IPC memory handle data size_t ipcMemHandleDataSize, /// [out] pointer to a pointer to device USM memory @@ -5516,7 +5515,7 @@ __urdlllocal ur_result_t UR_APICALL urIPCOpenMemHandleExp( return UR_RESULT_ERROR_UNINITIALIZED; // forward to device-platform - return pfnOpenMemHandleExp(hContext, hDevice, ipcMemHandleData, + return pfnOpenMemHandleExp(hContext, hDevice, pIPCMemHandleData, ipcMemHandleDataSize, ppMem); } @@ -5538,29 +5537,6 @@ __urdlllocal ur_result_t UR_APICALL urIPCCloseMemHandleExp( return pfnCloseMemHandleExp(hContext, pMem); } -/////////////////////////////////////////////////////////////////////////////// -/// @brief Intercept function for urIPCGetMemHandleDataExp -__urdlllocal ur_result_t UR_APICALL urIPCGetMemHandleDataExp( - /// [in] handle of the context object - ur_context_handle_t hContext, - /// [in] the IPC memory handle - ur_exp_ipc_mem_handle_t hIPCMem, - /// [out][optional] a pointer to the IPC memory handle data - void **ppIPCHandleData, - /// [out][optional] size of the resulting IPC memory handle data - size_t *pIPCMemHandleDataSizeRet) { - - auto *dditable = *reinterpret_cast(hContext); - - auto *pfnGetMemHandleDataExp = dditable->IPCExp.pfnGetMemHandleDataExp; - if (nullptr == pfnGetMemHandleDataExp) - return UR_RESULT_ERROR_UNINITIALIZED; - - // forward to device-platform - return pfnGetMemHandleDataExp(hContext, hIPCMem, ppIPCHandleData, - pIPCMemHandleDataSizeRet); -} - /////////////////////////////////////////////////////////////////////////////// /// @brief Intercept function for urMemoryExportAllocExportableMemoryExp __urdlllocal ur_result_t UR_APICALL urMemoryExportAllocExportableMemoryExp( @@ -6477,7 +6453,6 @@ UR_DLLEXPORT ur_result_t UR_APICALL urGetIPCExpProcAddrTable( pDdiTable->pfnPutMemHandleExp = ur_loader::urIPCPutMemHandleExp; pDdiTable->pfnOpenMemHandleExp = ur_loader::urIPCOpenMemHandleExp; pDdiTable->pfnCloseMemHandleExp = ur_loader::urIPCCloseMemHandleExp; - pDdiTable->pfnGetMemHandleDataExp = ur_loader::urIPCGetMemHandleDataExp; } else { // return pointers directly to platform's DDIs *pDdiTable = ur_loader::getContext()->platforms.front().dditable.IPCExp; diff --git a/unified-runtime/source/loader/ur_libapi.cpp b/unified-runtime/source/loader/ur_libapi.cpp index ea79cb71ab8ea..5cd5365a6a7ae 100644 --- a/unified-runtime/source/loader/ur_libapi.cpp +++ b/unified-runtime/source/loader/ur_libapi.cpp @@ -10022,9 +10022,10 @@ ur_result_t UR_APICALL urEnqueueTimestampRecordingExp( /// - ::UR_RESULT_ERROR_ADAPTER_SPECIFIC /// - ::UR_RESULT_ERROR_INVALID_NULL_HANDLE /// + `NULL == hContext` -/// - ::UR_RESULT_ERROR_INVALID_NULL_POINTER -/// + `NULL == phIPCMem` /// - ::UR_RESULT_ERROR_INVALID_CONTEXT +/// - ::UR_RESULT_ERROR_INVALID_NULL_POINTER +/// + `NULL == pIPCMemHandleData` +/// + `NULL == pIPCMemHandleDataSizeRet` /// - ::UR_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::UR_RESULT_ERROR_OUT_OF_RESOURCES ur_result_t UR_APICALL urIPCGetMemHandleExp( @@ -10032,14 +10033,17 @@ ur_result_t UR_APICALL urIPCGetMemHandleExp( ur_context_handle_t hContext, /// [in] pointer to device USM memory void *pMem, - /// [out][alloc] pointer to the resulting IPC memory handle - ur_exp_ipc_mem_handle_t *phIPCMem) try { + /// [out][optional] a pointer to the IPC memory handle data + void *pIPCMemHandleData, + /// [out][optional] size of the resulting IPC memory handle data + size_t *pIPCMemHandleDataSizeRet) try { auto pfnGetMemHandleExp = ur_lib::getContext()->urDdiTable.IPCExp.pfnGetMemHandleExp; if (nullptr == pfnGetMemHandleExp) return UR_RESULT_ERROR_UNINITIALIZED; - return pfnGetMemHandleExp(hContext, pMem, phIPCMem); + return pfnGetMemHandleExp(hContext, pMem, pIPCMemHandleData, + pIPCMemHandleDataSizeRet); } catch (...) { return exceptionToResult(std::current_exception()); } @@ -10054,32 +10058,29 @@ ur_result_t UR_APICALL urIPCGetMemHandleExp( /// - ::UR_RESULT_ERROR_ADAPTER_SPECIFIC /// - ::UR_RESULT_ERROR_INVALID_NULL_HANDLE /// + `NULL == hContext` -/// + `NULL == hIPCMem` +/// - ::UR_RESULT_ERROR_INVALID_NULL_POINTER +/// + `NULL == pIPCMemHandleData` /// - ::UR_RESULT_ERROR_INVALID_CONTEXT /// - ::UR_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::UR_RESULT_ERROR_OUT_OF_RESOURCES ur_result_t UR_APICALL urIPCPutMemHandleExp( /// [in] handle of the context object ur_context_handle_t hContext, - /// [in] the IPC memory handle - ur_exp_ipc_mem_handle_t hIPCMem, - /// [in] true if the backend resource should be released, false if the - /// backend resource will be released when freeing the corresponding - /// device USM memory - ur_bool_t putBackendResource) try { + /// [in] a pointer to the IPC memory handle data + void *pIPCMemHandleData) try { auto pfnPutMemHandleExp = ur_lib::getContext()->urDdiTable.IPCExp.pfnPutMemHandleExp; if (nullptr == pfnPutMemHandleExp) return UR_RESULT_ERROR_UNINITIALIZED; - return pfnPutMemHandleExp(hContext, hIPCMem, putBackendResource); + return pfnPutMemHandleExp(hContext, pIPCMemHandleData); } catch (...) { return exceptionToResult(std::current_exception()); } /////////////////////////////////////////////////////////////////////////////// -/// @brief Opens an inter-process memory handle from raw data to get the -/// corresponding pointer to device USM memory +/// @brief Opens an inter-process memory handle to get the corresponding pointer +/// to device USM memory /// /// @returns /// - ::UR_RESULT_SUCCESS @@ -10091,7 +10092,7 @@ ur_result_t UR_APICALL urIPCPutMemHandleExp( /// + `NULL == hDevice` /// - ::UR_RESULT_ERROR_INVALID_CONTEXT /// - ::UR_RESULT_ERROR_INVALID_NULL_POINTER -/// + `NULL == ipcMemHandleData` +/// + `NULL == pIPCMemHandleData` /// + `NULL == ppMem` /// - ::UR_RESULT_ERROR_INVALID_VALUE /// + ipcMemHandleDataSize is not the same as the size of IPC memory @@ -10105,7 +10106,7 @@ ur_result_t UR_APICALL urIPCOpenMemHandleExp( /// was allocated on ur_device_handle_t hDevice, /// [in] the IPC memory handle data - void *ipcMemHandleData, + void *pIPCMemHandleData, /// [in] size of the IPC memory handle data size_t ipcMemHandleDataSize, /// [out] pointer to a pointer to device USM memory @@ -10115,7 +10116,7 @@ ur_result_t UR_APICALL urIPCOpenMemHandleExp( if (nullptr == pfnOpenMemHandleExp) return UR_RESULT_ERROR_UNINITIALIZED; - return pfnOpenMemHandleExp(hContext, hDevice, ipcMemHandleData, + return pfnOpenMemHandleExp(hContext, hDevice, pIPCMemHandleData, ipcMemHandleDataSize, ppMem); } catch (...) { return exceptionToResult(std::current_exception()); @@ -10151,40 +10152,6 @@ ur_result_t UR_APICALL urIPCCloseMemHandleExp( return exceptionToResult(std::current_exception()); } -/////////////////////////////////////////////////////////////////////////////// -/// @brief Gets the data of an inter-process memory handle -/// -/// @returns -/// - ::UR_RESULT_SUCCESS -/// - ::UR_RESULT_ERROR_UNINITIALIZED -/// - ::UR_RESULT_ERROR_DEVICE_LOST -/// - ::UR_RESULT_ERROR_ADAPTER_SPECIFIC -/// - ::UR_RESULT_ERROR_INVALID_NULL_HANDLE -/// + `NULL == hContext` -/// + `NULL == hIPCMem` -/// - ::UR_RESULT_ERROR_INVALID_CONTEXT -/// - ::UR_RESULT_ERROR_OUT_OF_HOST_MEMORY -/// - ::UR_RESULT_ERROR_OUT_OF_RESOURCES -ur_result_t UR_APICALL urIPCGetMemHandleDataExp( - /// [in] handle of the context object - ur_context_handle_t hContext, - /// [in] the IPC memory handle - ur_exp_ipc_mem_handle_t hIPCMem, - /// [out][optional] a pointer to the IPC memory handle data - void **ppIPCHandleData, - /// [out][optional] size of the resulting IPC memory handle data - size_t *pIPCMemHandleDataSizeRet) try { - auto pfnGetMemHandleDataExp = - ur_lib::getContext()->urDdiTable.IPCExp.pfnGetMemHandleDataExp; - if (nullptr == pfnGetMemHandleDataExp) - return UR_RESULT_ERROR_UNINITIALIZED; - - return pfnGetMemHandleDataExp(hContext, hIPCMem, ppIPCHandleData, - pIPCMemHandleDataSizeRet); -} catch (...) { - return exceptionToResult(std::current_exception()); -} - /////////////////////////////////////////////////////////////////////////////// /// @brief Allocate an exportable memory region and return a pointer to that /// allocation. diff --git a/unified-runtime/source/loader/ur_print.cpp b/unified-runtime/source/loader/ur_print.cpp index 4c5552733bd38..9001ae8018fb5 100644 --- a/unified-runtime/source/loader/ur_print.cpp +++ b/unified-runtime/source/loader/ur_print.cpp @@ -2032,14 +2032,6 @@ ur_result_t urPrintIpcCloseMemHandleExpParams( return str_copy(&ss, buffer, buff_size, out_size); } -ur_result_t urPrintIpcGetMemHandleDataExpParams( - const struct ur_ipc_get_mem_handle_data_exp_params_t *params, char *buffer, - const size_t buff_size, size_t *out_size) { - std::stringstream ss; - ss << params; - return str_copy(&ss, buffer, buff_size, out_size); -} - ur_result_t urPrintKernelCreateParams(const struct ur_kernel_create_params_t *params, char *buffer, const size_t buff_size, diff --git a/unified-runtime/source/ur_api.cpp b/unified-runtime/source/ur_api.cpp index b973cba487838..28949e0182abd 100644 --- a/unified-runtime/source/ur_api.cpp +++ b/unified-runtime/source/ur_api.cpp @@ -8729,9 +8729,10 @@ ur_result_t UR_APICALL urEnqueueTimestampRecordingExp( /// - ::UR_RESULT_ERROR_ADAPTER_SPECIFIC /// - ::UR_RESULT_ERROR_INVALID_NULL_HANDLE /// + `NULL == hContext` -/// - ::UR_RESULT_ERROR_INVALID_NULL_POINTER -/// + `NULL == phIPCMem` /// - ::UR_RESULT_ERROR_INVALID_CONTEXT +/// - ::UR_RESULT_ERROR_INVALID_NULL_POINTER +/// + `NULL == pIPCMemHandleData` +/// + `NULL == pIPCMemHandleDataSizeRet` /// - ::UR_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::UR_RESULT_ERROR_OUT_OF_RESOURCES ur_result_t UR_APICALL urIPCGetMemHandleExp( @@ -8739,8 +8740,10 @@ ur_result_t UR_APICALL urIPCGetMemHandleExp( ur_context_handle_t hContext, /// [in] pointer to device USM memory void *pMem, - /// [out][alloc] pointer to the resulting IPC memory handle - ur_exp_ipc_mem_handle_t *phIPCMem) { + /// [out][optional] a pointer to the IPC memory handle data + void *pIPCMemHandleData, + /// [out][optional] size of the resulting IPC memory handle data + size_t *pIPCMemHandleDataSizeRet) { ur_result_t result = UR_RESULT_SUCCESS; return result; } @@ -8755,26 +8758,23 @@ ur_result_t UR_APICALL urIPCGetMemHandleExp( /// - ::UR_RESULT_ERROR_ADAPTER_SPECIFIC /// - ::UR_RESULT_ERROR_INVALID_NULL_HANDLE /// + `NULL == hContext` -/// + `NULL == hIPCMem` +/// - ::UR_RESULT_ERROR_INVALID_NULL_POINTER +/// + `NULL == pIPCMemHandleData` /// - ::UR_RESULT_ERROR_INVALID_CONTEXT /// - ::UR_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::UR_RESULT_ERROR_OUT_OF_RESOURCES ur_result_t UR_APICALL urIPCPutMemHandleExp( /// [in] handle of the context object ur_context_handle_t hContext, - /// [in] the IPC memory handle - ur_exp_ipc_mem_handle_t hIPCMem, - /// [in] true if the backend resource should be released, false if the - /// backend resource will be released when freeing the corresponding - /// device USM memory - ur_bool_t putBackendResource) { + /// [in] a pointer to the IPC memory handle data + void *pIPCMemHandleData) { ur_result_t result = UR_RESULT_SUCCESS; return result; } /////////////////////////////////////////////////////////////////////////////// -/// @brief Opens an inter-process memory handle from raw data to get the -/// corresponding pointer to device USM memory +/// @brief Opens an inter-process memory handle to get the corresponding pointer +/// to device USM memory /// /// @returns /// - ::UR_RESULT_SUCCESS @@ -8786,7 +8786,7 @@ ur_result_t UR_APICALL urIPCPutMemHandleExp( /// + `NULL == hDevice` /// - ::UR_RESULT_ERROR_INVALID_CONTEXT /// - ::UR_RESULT_ERROR_INVALID_NULL_POINTER -/// + `NULL == ipcMemHandleData` +/// + `NULL == pIPCMemHandleData` /// + `NULL == ppMem` /// - ::UR_RESULT_ERROR_INVALID_VALUE /// + ipcMemHandleDataSize is not the same as the size of IPC memory @@ -8800,7 +8800,7 @@ ur_result_t UR_APICALL urIPCOpenMemHandleExp( /// was allocated on ur_device_handle_t hDevice, /// [in] the IPC memory handle data - void *ipcMemHandleData, + void *pIPCMemHandleData, /// [in] size of the IPC memory handle data size_t ipcMemHandleDataSize, /// [out] pointer to a pointer to device USM memory @@ -8833,33 +8833,6 @@ ur_result_t UR_APICALL urIPCCloseMemHandleExp( return result; } -/////////////////////////////////////////////////////////////////////////////// -/// @brief Gets the data of an inter-process memory handle -/// -/// @returns -/// - ::UR_RESULT_SUCCESS -/// - ::UR_RESULT_ERROR_UNINITIALIZED -/// - ::UR_RESULT_ERROR_DEVICE_LOST -/// - ::UR_RESULT_ERROR_ADAPTER_SPECIFIC -/// - ::UR_RESULT_ERROR_INVALID_NULL_HANDLE -/// + `NULL == hContext` -/// + `NULL == hIPCMem` -/// - ::UR_RESULT_ERROR_INVALID_CONTEXT -/// - ::UR_RESULT_ERROR_OUT_OF_HOST_MEMORY -/// - ::UR_RESULT_ERROR_OUT_OF_RESOURCES -ur_result_t UR_APICALL urIPCGetMemHandleDataExp( - /// [in] handle of the context object - ur_context_handle_t hContext, - /// [in] the IPC memory handle - ur_exp_ipc_mem_handle_t hIPCMem, - /// [out][optional] a pointer to the IPC memory handle data - void **ppIPCHandleData, - /// [out][optional] size of the resulting IPC memory handle data - size_t *pIPCMemHandleDataSizeRet) { - ur_result_t result = UR_RESULT_SUCCESS; - return result; -} - /////////////////////////////////////////////////////////////////////////////// /// @brief Allocate an exportable memory region and return a pointer to that /// allocation. From 7873e13f67c21d08e797dfc4981992ab277de598 Mon Sep 17 00:00:00 2001 From: "Larsen, Steffen" Date: Mon, 6 Oct 2025 00:20:25 -0700 Subject: [PATCH 19/38] Fix formatting Signed-off-by: Larsen, Steffen --- unified-runtime/source/adapters/hip/memory.cpp | 5 +++-- unified-runtime/source/adapters/native_cpu/memory.cpp | 5 +++-- unified-runtime/source/adapters/offload/memory.cpp | 5 +++-- unified-runtime/source/adapters/opencl/memory.cpp | 9 +++++---- 4 files changed, 14 insertions(+), 10 deletions(-) diff --git a/unified-runtime/source/adapters/hip/memory.cpp b/unified-runtime/source/adapters/hip/memory.cpp index 354af8b99f561..4c646ed64a1e4 100644 --- a/unified-runtime/source/adapters/hip/memory.cpp +++ b/unified-runtime/source/adapters/hip/memory.cpp @@ -641,8 +641,9 @@ hipSurfaceObject_t SurfaceMem::getSurface(const ur_device_handle_t Device) { return SurfObjs[OuterMemStruct->getContext()->getDeviceIndex(Device)]; } -UR_APIEXPORT ur_result_t UR_APICALL -urIPCGetMemHandleExp(ur_context_handle_t, void *, void *, size_t*) { +UR_APIEXPORT ur_result_t UR_APICALL urIPCGetMemHandleExp(ur_context_handle_t, + void *, void *, + size_t *) { return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; } diff --git a/unified-runtime/source/adapters/native_cpu/memory.cpp b/unified-runtime/source/adapters/native_cpu/memory.cpp index eef3fdb6d7310..15eef80246e66 100644 --- a/unified-runtime/source/adapters/native_cpu/memory.cpp +++ b/unified-runtime/source/adapters/native_cpu/memory.cpp @@ -139,8 +139,9 @@ UR_APIEXPORT ur_result_t UR_APICALL urMemImageGetInfo( DIE_NO_IMPLEMENTATION; } -UR_APIEXPORT ur_result_t UR_APICALL -urIPCGetMemHandleExp(ur_context_handle_t, void *, void *, size_t*) { +UR_APIEXPORT ur_result_t UR_APICALL urIPCGetMemHandleExp(ur_context_handle_t, + void *, void *, + size_t *) { return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; } diff --git a/unified-runtime/source/adapters/offload/memory.cpp b/unified-runtime/source/adapters/offload/memory.cpp index 5d25e2b40c5d0..f17b4f76c636c 100644 --- a/unified-runtime/source/adapters/offload/memory.cpp +++ b/unified-runtime/source/adapters/offload/memory.cpp @@ -162,8 +162,9 @@ UR_APIEXPORT ur_result_t UR_APICALL urMemImageGetInfo(ur_mem_handle_t, return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; } -UR_APIEXPORT ur_result_t UR_APICALL -urIPCGetMemHandleExp(ur_context_handle_t, void *, void *, size_t*) { +UR_APIEXPORT ur_result_t UR_APICALL urIPCGetMemHandleExp(ur_context_handle_t, + void *, void *, + size_t *) { return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; } diff --git a/unified-runtime/source/adapters/opencl/memory.cpp b/unified-runtime/source/adapters/opencl/memory.cpp index e913b486ded21..cda15dfa4db81 100644 --- a/unified-runtime/source/adapters/opencl/memory.cpp +++ b/unified-runtime/source/adapters/opencl/memory.cpp @@ -580,13 +580,14 @@ UR_APIEXPORT ur_result_t UR_APICALL urMemRelease(ur_mem_handle_t hMem) { return UR_RESULT_SUCCESS; } -UR_APIEXPORT ur_result_t UR_APICALL -urIPCGetMemHandleExp(ur_context_handle_t, void *, void *, size_t*) { +UR_APIEXPORT ur_result_t UR_APICALL urIPCGetMemHandleExp(ur_context_handle_t, + void *, void *, + size_t *) { return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; } -UR_APIEXPORT ur_result_t UR_APICALL -urIPCPutMemHandleExp(ur_context_handle_t, void *) { +UR_APIEXPORT ur_result_t UR_APICALL urIPCPutMemHandleExp(ur_context_handle_t, + void *) { return UR_RESULT_ERROR_UNSUPPORTED_FEATURE; } From 2001baa7bfcdb8947a7db0b3af3953bb4cc88321 Mon Sep 17 00:00:00 2001 From: "Larsen, Steffen" Date: Mon, 6 Oct 2025 01:40:38 -0700 Subject: [PATCH 20/38] Fix failures Signed-off-by: Larsen, Steffen --- sycl/test-e2e/Experimental/ipc_memory.cpp | 5 +++-- sycl/test/abi/sycl_symbols_windows.dump | 20 ++++---------------- 2 files changed, 7 insertions(+), 18 deletions(-) diff --git a/sycl/test-e2e/Experimental/ipc_memory.cpp b/sycl/test-e2e/Experimental/ipc_memory.cpp index eed4c8f99628e..48a4ba7ae0431 100644 --- a/sycl/test-e2e/Experimental/ipc_memory.cpp +++ b/sycl/test-e2e/Experimental/ipc_memory.cpp @@ -49,7 +49,7 @@ int spawner(int argc, char *argv[]) { // Write handle data to file. { syclexp::ipc_memory::handle_data_t HandleData = - syclexp::ipc_memory.get(DataPtr, Q.get_context()); + syclexp::ipc_memory::get(DataPtr, Q.get_context()); size_t HandleDataSize = HandleData.size(); std::fstream FS(CommsFile, std::ios_base::out | std::ios_base::binary); FS.write(reinterpret_cast(&HandleDataSize), sizeof(size_t)); @@ -87,7 +87,8 @@ int consumer() { FS.read(HandleData.get(), HandleSize); // Open IPC handle. - syclexp::ipc_memory_handle_data_t Handle{HandleData.get(), HandleSize}; + syclexp::ipc_memory::handle_data_t Handle{HandleData.get(), + HandleData.get() + HandleSize}; int *DataPtr = reinterpret_cast( syclexp::ipc_memory::open(Handle, Q.get_context(), Q.get_device())); diff --git a/sycl/test/abi/sycl_symbols_windows.dump b/sycl/test/abi/sycl_symbols_windows.dump index c379eff83cc9e..61094418720a9 100644 --- a/sycl/test/abi/sycl_symbols_windows.dump +++ b/sycl/test/abi/sycl_symbols_windows.dump @@ -447,10 +447,6 @@ ??0image_plain@detail@_V1@sycl@@IEAA@_KAEBVcontext@23@Vevent@23@V?$unique_ptr@VSYCLMemObjAllocator@detail@_V1@sycl@@U?$default_delete@VSYCLMemObjAllocator@detail@_V1@sycl@@@std@@@std@@EW4image_channel_order@23@W4image_channel_type@23@_NV?$range@$02@23@@Z ??0image_plain@detail@_V1@sycl@@QEAA@$$QEAV0123@@Z ??0image_plain@detail@_V1@sycl@@QEAA@AEBV0123@@Z -??0ipc_memory@experimental@oneapi@ext@_V1@sycl@@QEAA@AEBV012345@@Z -??0ipc_memory@experimental@oneapi@ext@_V1@sycl@@QEAA@PEAXAEBVcontext@45@@Z -??0ipc_memory@experimental@oneapi@ext@_V1@sycl@@AEAA@V?$shared_ptr@Vipc_memory_impl@detail@_V1@sycl@@@std@@@Z -??0ipc_memory@experimental@oneapi@ext@_V1@sycl@@QEAA@$$QEAV012345@@Z ??0kernel@_V1@sycl@@AEAA@V?$shared_ptr@Vkernel_impl@detail@_V1@sycl@@@std@@@Z ??0kernel@_V1@sycl@@QEAA@$$QEAV012@@Z ??0kernel@_V1@sycl@@QEAA@AEBV012@@Z @@ -542,7 +538,6 @@ ??1image_mem@experimental@oneapi@ext@_V1@sycl@@QEAA@XZ ??1image_mem_impl@detail@experimental@oneapi@ext@_V1@sycl@@QEAA@XZ ??1image_plain@detail@_V1@sycl@@QEAA@XZ -??1ipc_memory@experimental@oneapi@ext@_V1@sycl@@QEAA@XZ ??1kernel@_V1@sycl@@QEAA@XZ ??1kernel_bundle_plain@detail@_V1@sycl@@QEAA@XZ ??1kernel_id@_V1@sycl@@QEAA@XZ @@ -563,8 +558,6 @@ ??4?$OwnerLessBase@Vevent@_V1@sycl@@@detail@_V1@sycl@@QEAAAEAV0123@AEBV0123@@Z ??4?$OwnerLessBase@Vexecutable_command_graph@detail@experimental@oneapi@ext@_V1@sycl@@@detail@_V1@sycl@@QEAAAEAV0123@$$QEAV0123@@Z ??4?$OwnerLessBase@Vexecutable_command_graph@detail@experimental@oneapi@ext@_V1@sycl@@@detail@_V1@sycl@@QEAAAEAV0123@AEBV0123@@Z -??4?$OwnerLessBase@Vipc_memory@experimental@oneapi@ext@_V1@sycl@@@detail@_V1@sycl@@QEAAAEAV0123@AEBV0123@@Z -??4?$OwnerLessBase@Vipc_memory@experimental@oneapi@ext@_V1@sycl@@@detail@_V1@sycl@@QEAAAEAV0123@$$QEAV0123@@Z ??4?$OwnerLessBase@Vkernel@_V1@sycl@@@detail@_V1@sycl@@QEAAAEAV0123@$$QEAV0123@@Z ??4?$OwnerLessBase@Vkernel@_V1@sycl@@@detail@_V1@sycl@@QEAAAEAV0123@AEBV0123@@Z ??4?$OwnerLessBase@Vkernel_id@_V1@sycl@@@detail@_V1@sycl@@QEAAAEAV0123@$$QEAV0123@@Z @@ -643,8 +636,6 @@ ??4image_mem@experimental@oneapi@ext@_V1@sycl@@QEAAAEAV012345@AEBV012345@@Z ??4image_plain@detail@_V1@sycl@@QEAAAEAV0123@$$QEAV0123@@Z ??4image_plain@detail@_V1@sycl@@QEAAAEAV0123@AEBV0123@@Z -??4ipc_memory@experimental@oneapi@ext@_V1@sycl@@QEAAAEAV012345@AEBV012345@@Z -??4ipc_memory@experimental@oneapi@ext@_V1@sycl@@QEAAAEAV012345@$$QEAV012345@@Z ??4kernel@_V1@sycl@@QEAAAEAV012@$$QEAV012@@Z ??4kernel@_V1@sycl@@QEAAAEAV012@AEBV012@@Z ??4kernel_bundle_plain@detail@_V1@sycl@@QEAAAEAV0123@$$QEAV0123@@Z @@ -3840,7 +3831,7 @@ ?category@exception@_V1@sycl@@QEBAAEBVerror_category@std@@XZ ?checkNodePropertiesAndThrow@modifiable_command_graph@detail@experimental@oneapi@ext@_V1@sycl@@KAXAEBVproperty_list@67@@Z ?clearArgs@handler@_V1@sycl@@AEAAXXZ -?close@ipc_memory@experimental@oneapi@ext@_V1@sycl@@SAXPEAXAEBVcontext@56@@Z +?close@ipc_memory@experimental@oneapi@ext@_V1@sycl@@YAXPEAXAEBVcontext@56@@Z ?code@exception@_V1@sycl@@QEBAAEBVerror_code@std@@XZ ?compile_from_source@detail@experimental@oneapi@ext@_V1@sycl@@YA?AV?$kernel_bundle@$00@56@AEAV?$kernel_bundle@$02@56@AEBV?$vector@Vdevice@_V1@sycl@@V?$allocator@Vdevice@_V1@sycl@@@std@@@std@@AEBV?$vector@Vstring_view@detail@_V1@sycl@@V?$allocator@Vstring_view@detail@_V1@sycl@@@std@@@std@@PEAVstring@156@2@Z ?compile_impl@detail@_V1@sycl@@YA?AV?$shared_ptr@Vkernel_bundle_impl@detail@_V1@sycl@@@std@@AEBV?$kernel_bundle@$0A@@23@AEBV?$vector@Vdevice@_V1@sycl@@V?$allocator@Vdevice@_V1@sycl@@@std@@@5@AEBVproperty_list@23@@Z @@ -3995,8 +3986,6 @@ ?ext_oneapi_owner_before@?$OwnerLessBase@Vevent@_V1@sycl@@@detail@_V1@sycl@@QEBA_NAEBVevent@34@@Z ?ext_oneapi_owner_before@?$OwnerLessBase@Vexecutable_command_graph@detail@experimental@oneapi@ext@_V1@sycl@@@detail@_V1@sycl@@QEBA_NAEBV?$weak_object_base@Vexecutable_command_graph@detail@experimental@oneapi@ext@_V1@sycl@@@2oneapi@ext@34@@Z ?ext_oneapi_owner_before@?$OwnerLessBase@Vexecutable_command_graph@detail@experimental@oneapi@ext@_V1@sycl@@@detail@_V1@sycl@@QEBA_NAEBVexecutable_command_graph@2experimental@oneapi@ext@34@@Z -?ext_oneapi_owner_before@?$OwnerLessBase@Vipc_memory@experimental@oneapi@ext@_V1@sycl@@@detail@_V1@sycl@@QEBA_NAEBV?$weak_object_base@Vipc_memory@experimental@oneapi@ext@_V1@sycl@@@2oneapi@ext@34@@Z -?ext_oneapi_owner_before@?$OwnerLessBase@Vipc_memory@experimental@oneapi@ext@_V1@sycl@@@detail@_V1@sycl@@QEBA_NAEBVipc_memory@experimental@oneapi@ext@34@@Z ?ext_oneapi_owner_before@?$OwnerLessBase@Vkernel@_V1@sycl@@@detail@_V1@sycl@@QEBA_NAEBV?$weak_object_base@Vkernel@_V1@sycl@@@2oneapi@ext@34@@Z ?ext_oneapi_owner_before@?$OwnerLessBase@Vkernel@_V1@sycl@@@detail@_V1@sycl@@QEBA_NAEBVkernel@34@@Z ?ext_oneapi_owner_before@?$OwnerLessBase@Vkernel_id@_V1@sycl@@@detail@_V1@sycl@@QEBA_NAEBV?$weak_object_base@Vkernel_id@_V1@sycl@@@2oneapi@ext@34@@Z @@ -4056,6 +4045,7 @@ ?frexp_impl@detail@_V1@sycl@@YANNPEAH@Z ?get@context@_V1@sycl@@QEBAPEAU_cl_context@@XZ ?get@device@_V1@sycl@@QEBAPEAU_cl_device_id@@XZ +?get@ipc_memory@experimental@oneapi@ext@_V1@sycl@@YA?AV?$vector@DV?$allocator@D@std@@@std@@PEAXAEBVcontext@56@@Z ?get@kernel@_V1@sycl@@QEBAPEAU_cl_kernel@@XZ ?get@platform@_V1@sycl@@QEBAPEAU_cl_platform_id@@XZ ?get@queue@_V1@sycl@@QEBAPEAU_cl_command_queue@@XZ @@ -4191,7 +4181,6 @@ ?get_filtering_mode@sampler@_V1@sycl@@QEBA?AW4filtering_mode@23@XZ ?get_flags@stream@_V1@sycl@@AEBAIXZ ?get_handle@image_mem@experimental@oneapi@ext@_V1@sycl@@QEBA?AUimage_mem_handle@23456@XZ -?get_handle_data@ipc_memory@experimental@oneapi@ext@_V1@sycl@@QEBA?AV?$span@D$0?0@56@XZ ?get_image_channel_type@experimental@oneapi@ext@_V1@sycl@@YA?AW4image_channel_type@45@Uimage_mem_handle@12345@AEBVdevice@45@AEBVcontext@45@@Z ?get_image_channel_type@experimental@oneapi@ext@_V1@sycl@@YA?AW4image_channel_type@45@Uimage_mem_handle@12345@AEBVqueue@45@@Z ?get_image_memory_support@experimental@oneapi@ext@_V1@sycl@@YA?AV?$vector@W4image_memory_handle_type@experimental@oneapi@ext@_V1@sycl@@V?$allocator@W4image_memory_handle_type@experimental@oneapi@ext@_V1@sycl@@@std@@@std@@AEBUimage_descriptor@12345@AEBVdevice@45@AEBVcontext@45@@Z @@ -4231,7 +4220,6 @@ ?get_pointer_type@detail@_V1@sycl@@YA?AW4alloc@usm@23@PEBXAEAVcontext_impl@123@@Z ?get_precision@stream@_V1@sycl@@QEBA_KXZ ?get_predecessors@node@experimental@oneapi@ext@_V1@sycl@@QEBA?AV?$vector@Vnode@experimental@oneapi@ext@_V1@sycl@@V?$allocator@Vnode@experimental@oneapi@ext@_V1@sycl@@@std@@@std@@XZ -?get_ptr@ipc_memory@experimental@oneapi@ext@_V1@sycl@@QEBAPEAXXZ ?get_queue@fusion_wrapper@experimental@codeplay@ext@_V1@sycl@@QEBA?AVqueue@56@XZ ?get_range@image_mem@experimental@oneapi@ext@_V1@sycl@@QEBA?AV?$range@$02@56@XZ ?get_range@image_plain@detail@_V1@sycl@@IEBA?AV?$range@$02@34@XZ @@ -4365,7 +4353,7 @@ ?modf_impl@detail@_V1@sycl@@YANNPEAN@Z ?name@SYCLCategory@detail@_V1@sycl@@UEBAPEBDXZ ?native_specialization_constant@kernel_bundle_plain@detail@_V1@sycl@@QEBA_NXZ -?open@ipc_memory@experimental@oneapi@ext@_V1@sycl@@SAPEAXV?$span@D$0?0@56@AEBVcontext@56@AEBVdevice@56@@Z +?open@ipc_memory@experimental@oneapi@ext@_V1@sycl@@YAPEAXAEAV?$vector@DV?$allocator@D@std@@@std@@AEBVcontext@56@AEBVdevice@56@@Z ?parallel_for@handler@_V1@sycl@@QEAAXV?$range@$00@23@Vkernel@23@@Z ?parallel_for@handler@_V1@sycl@@QEAAXV?$range@$01@23@Vkernel@23@@Z ?parallel_for@handler@_V1@sycl@@QEAAXV?$range@$02@23@Vkernel@23@@Z @@ -4385,7 +4373,7 @@ ?print_graph@modifiable_command_graph@detail@experimental@oneapi@ext@_V1@sycl@@IEBAXVstring_view@267@_N@Z ?print_graph@modifiable_command_graph@detail@experimental@oneapi@ext@_V1@sycl@@QEBAXV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@_N@Z ?processArg@handler@_V1@sycl@@AEAAXPEAXAEBW4kernel_param_kind_t@detail@23@H_KAEA_K_N4@Z -?put@ipc_memory@experimental@oneapi@ext@_V1@sycl@@QEAAXXZ +?put@ipc_memory@experimental@oneapi@ext@_V1@sycl@@YAXAEAV?$vector@DV?$allocator@D@std@@@std@@AEBVcontext@56@@Z ?query@tls_code_loc_t@detail@_V1@sycl@@QEAAAEBUcode_location@234@XZ ?reduComputeWGSize@detail@_V1@sycl@@YA_K_K0AEA_K@Z ?reduGetMaxNumConcurrentWorkGroups@detail@_V1@sycl@@YAIAEAVhandler@23@@Z From 68ea80ee27a64de6b021e7e4e094c509642737bf Mon Sep 17 00:00:00 2001 From: "Larsen, Steffen" Date: Mon, 13 Oct 2025 02:21:42 -0700 Subject: [PATCH 21/38] Address feedback Signed-off-by: Larsen, Steffen --- ...neapi_inter_process_communication.asciidoc | 84 ++++++++++++------- sycl/source/ipc_memory.cpp | 5 ++ 2 files changed, 57 insertions(+), 32 deletions(-) diff --git a/sycl/doc/extensions/experimental/sycl_ext_oneapi_inter_process_communication.asciidoc b/sycl/doc/extensions/experimental/sycl_ext_oneapi_inter_process_communication.asciidoc index 5d4ad94898194..8ab0da9b0d850 100644 --- a/sycl/doc/extensions/experimental/sycl_ext_oneapi_inter_process_communication.asciidoc +++ b/sycl/doc/extensions/experimental/sycl_ext_oneapi_inter_process_communication.asciidoc @@ -52,16 +52,6 @@ change incompatibly in future versions of {dpcpp} without prior notice. specification.* -== Backend support status - -The APIs in this extension may be used only on a device that has -`aspect::ext_oneapi_ipc_memory`. The application must check that the device has -this aspect before submitting a kernel using any of the APIs in this -extension. If the application fails to do this, the implementation throws -a synchronous exception with the `errc::kernel_not_supported` error code -when the kernel is submitted to the queue. - - == Overview This extension adds the ability for SYCL programs to share device USM memory @@ -77,11 +67,11 @@ handle data to retrieve the corresponding device USM memory. This extension provides a feature-test macro as described in the core SYCL specification. An implementation supporting this extension must predefine the -macro `SYCL_EXT_ONEAPI_IPC` to one of the values defined in the table -below. Applications can test for the existence of this macro to determine if -the implementation supports this feature, or applications can test the macro's -value to determine which of the extension's features the implementation -supports. +macro `SYCL_EXT_ONEAPI_INTER_PROCESS_COMMUNICATION` to one of the values defined +in the table below. Applications can test for the existence of this macro to +determine if the implementation supports this feature, or applications can test +the macro's value to determine which of the extension's features the +implementation supports. [%header,cols="1,5"] |=== @@ -93,6 +83,22 @@ supports. feature-test macro always has this value. |=== +=== Extension to `enum class aspect` + +[source] +---- +namespace sycl { +enum class aspect { + ... + ext_oneapi_ipc_memory +} +} +---- + +If a SYCL device has this aspect, that device supports `ipc_memory::get()` free +function specified in the following section. + + === Inter-process communicable memory @@ -123,14 +129,18 @@ a| a! [source] ---- -get(void *ptr, const sycl::context &ctx) +handle_data_t get(void *ptr, const sycl::context &ctx) ---- !==== -_Returns:_ A `handle_data_t` object containing the data of the IPC memory handle -in `ctx` from a pointer `ptr` to device USM memory. -Calling this function with a `ptr` that does not point to device USM memory, the -behaviors is undefined. +_Preconditions:_ `ptr` is a pointer to USM device memory on some device _D_ in +context `ctx` and device _D_ returns `true` for +`device::has(aspect::ext_oneapi_ipc_memory)`. + +_Returns:_ An IPC "handle" to this USM memory allocation. The bytes of this +handle can be transferred to another process on the same system, and the other +process can use the handle to get a pointer to the same USM allocation through a +call to the `open()` function. !==== a! @@ -140,13 +150,13 @@ void put(handle_data_t &handle_data, const sycl::context &ctx) ---- !==== -_Effects:_ Instructs the underlying IPC memory resources to be returned to -the backend. Freeing the device USM memory used when the handle data was created -through a call to `get()` will have the same effect as calling this function, -so a direct call to this function is not strictly required. -Calling this function after `sycl::free()` has been called on the device USM -memory used when the handle data was created through a call to `get()` will -result in undefined behavior. +_Preconditions:_ `handle_data` is the IPC "handle" to USM device memory that was +returned from a call to get either in this process or in some other process on +the same system. The USM device memory has not yet been freed in this process. + +_Effects:_ Deallocates resources associated with the handle. These resources are +automatically deallocated when the USM device memory is freed, so it is not +strictly necessary to call the `put` function. !==== a! @@ -157,11 +167,21 @@ static void *open(handle_data_t &handle_data, const sycl::context &ctx, ---- !==== -_Effects:_ Returns a pointer to the same device USM memory as the device USM -memory associated with `handle_data`. -The handle data is allowed to be from another process on the host system. -If the handle data has been destroyed, calling this function results in -undefined behavior. +_Preconditions:_ `handle_data` is the IPC "handle" to USM device memory that was +returned from a call to the `get` function either in this process or in some +other process on the same system. That USM device memory is accessible on device +`dev`. + +_Returns:_ A pointer to the same USM device memory represented by `handle_data`. +This pointer can be used in any API taking a USM device memory pointer, except +it cannot be passed to `sycl::free`. Instead, use the `close` function to free +this memory pointer. + +_Throws:_ + * An exception with the `errc::feature_not_supported` error code if device + `dev` does not have `aspect::ext_oneapi_ipc_memory`. + * An exception with the `errc::invalid` error code if the handle data + `handle_data` has an unexpected number of bytes. !==== a! diff --git a/sycl/source/ipc_memory.cpp b/sycl/source/ipc_memory.cpp index 0268307a3ddd9..97fa05d3fa10d 100644 --- a/sycl/source/ipc_memory.cpp +++ b/sycl/source/ipc_memory.cpp @@ -38,6 +38,11 @@ __SYCL_EXPORT void put(handle_data_t &HandleData, const sycl::context &Ctx) { __SYCL_EXPORT void *open(handle_data_t &HandleData, const sycl::context &Ctx, const sycl::device &Dev) { + if (!Dev.has(aspect::ext_oneapi_ipc_memory)) + throw sycl::exception( + sycl::make_error_code(errc::feature_not_supported), + "Device does not support aspect::ext_oneapi_ipc_memory."); + auto CtxImpl = sycl::detail::getSyclObjImpl(Ctx); sycl::detail::adapter_impl &Adapter = CtxImpl->getAdapter(); From d1d9a1a068c3b83a3b5b860d8c3232b9fe12741d Mon Sep 17 00:00:00 2001 From: "Larsen, Steffen" Date: Mon, 13 Oct 2025 04:25:50 -0700 Subject: [PATCH 22/38] Fix unittest Signed-off-by: Larsen, Steffen --- sycl/unittests/Extensions/IPC.cpp | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/sycl/unittests/Extensions/IPC.cpp b/sycl/unittests/Extensions/IPC.cpp index faa5fad9fd0c8..0235ae93b7e4b 100644 --- a/sycl/unittests/Extensions/IPC.cpp +++ b/sycl/unittests/Extensions/IPC.cpp @@ -68,6 +68,20 @@ ur_result_t replace_urIPCCloseMemHandleExp(void *pParams) { return UR_RESULT_SUCCESS; } +ur_result_t after_urDeviceGetInfo(void *pParams) { + auto params = *static_cast(pParams); + switch (*params.ppropName) { + case UR_DEVICE_INFO_IPC_MEMORY_SUPPORT_EXP: + if (*params.ppPropSizeRet) + **params.ppPropSizeRet = sizeof(ur_bool_t); + if (*params.ppPropValue) + *static_cast(*params.ppPropValue) = ur_bool_t{true}; + return UR_RESULT_SUCCESS; + default: + return UR_RESULT_SUCCESS; + } +} + class IPCTests : public ::testing::Test { public: IPCTests() : Mock{}, Ctxt(sycl::platform()) {} @@ -87,6 +101,8 @@ class IPCTests : public ::testing::Test { replace_urIPCOpenMemHandleExp); mock::getCallbacks().set_replace_callback("urIPCCloseMemHandleExp", replace_urIPCCloseMemHandleExp); + mock::getCallbacks().set_after_callback("urDeviceGetInfo", + after_urDeviceGetInfo); } sycl::unittest::UrMock<> Mock; From 01e3a65602014c3fddcc00f13de8a91c7b5927ae Mon Sep 17 00:00:00 2001 From: "Larsen, Steffen" Date: Mon, 13 Oct 2025 07:34:46 -0700 Subject: [PATCH 23/38] Switch to std::byte Signed-off-by: Larsen, Steffen --- ...ycl_ext_oneapi_inter_process_communication.asciidoc | 2 +- .../sycl/ext/oneapi/experimental/ipc_memory.hpp | 10 ++++++---- sycl/test/abi/sycl_symbols_linux.dump | 4 ++-- sycl/unittests/Extensions/IPC.cpp | 4 +++- 4 files changed, 12 insertions(+), 8 deletions(-) diff --git a/sycl/doc/extensions/experimental/sycl_ext_oneapi_inter_process_communication.asciidoc b/sycl/doc/extensions/experimental/sycl_ext_oneapi_inter_process_communication.asciidoc index 8ab0da9b0d850..4459a41384a51 100644 --- a/sycl/doc/extensions/experimental/sycl_ext_oneapi_inter_process_communication.asciidoc +++ b/sycl/doc/extensions/experimental/sycl_ext_oneapi_inter_process_communication.asciidoc @@ -108,7 +108,7 @@ namespace. ``` namespace sycl::ext::oneapi::experimental::ipc_memory { -using handle_data_t = std::vector; +using handle_data_t = std::vector; handle_data_t get(void *ptr, const sycl::context &ctx); diff --git a/sycl/include/sycl/ext/oneapi/experimental/ipc_memory.hpp b/sycl/include/sycl/ext/oneapi/experimental/ipc_memory.hpp index 0e37597047116..02dfa59daf797 100644 --- a/sycl/include/sycl/ext/oneapi/experimental/ipc_memory.hpp +++ b/sycl/include/sycl/ext/oneapi/experimental/ipc_memory.hpp @@ -8,12 +8,12 @@ #pragma once +#if (!defined(_HAS_STD_BYTE) || _HAS_STD_BYTE != 0) + #include #include -#include -#include -#include +#include namespace sycl { inline namespace _V1 { @@ -23,7 +23,7 @@ class device; namespace ext::oneapi::experimental::ipc_memory { -using handle_data_t = std::vector; +using handle_data_t = std::vector; __SYCL_EXPORT handle_data_t get(void *Ptr, const sycl::context &Ctx); @@ -37,3 +37,5 @@ __SYCL_EXPORT void close(void *Ptr, const sycl::context &Ctx); } // namespace ext::oneapi::experimental::ipc_memory } // namespace _V1 } // namespace sycl + +#endif diff --git a/sycl/test/abi/sycl_symbols_linux.dump b/sycl/test/abi/sycl_symbols_linux.dump index 1ab8caa4fd05d..e1947798622b0 100644 --- a/sycl/test/abi/sycl_symbols_linux.dump +++ b/sycl/test/abi/sycl_symbols_linux.dump @@ -2998,8 +2998,8 @@ _ZN4sycl3_V13ext6oneapi10level_zero6detail11make_deviceERKNS0_8platformEm _ZN4sycl3_V13ext6oneapi12experimental10async_freeERKNS0_5queueEPvRKNS0_6detail13code_locationE _ZN4sycl3_V13ext6oneapi12experimental10async_freeERNS0_7handlerEPv _ZN4sycl3_V13ext6oneapi12experimental10ipc_memory3getEPvRKNS0_7contextE -_ZN4sycl3_V13ext6oneapi12experimental10ipc_memory3putERSt6vectorIcSaIcEERKNS0_7contextE -_ZN4sycl3_V13ext6oneapi12experimental10ipc_memory4openERSt6vectorIcSaIcEERKNS0_7contextERKNS0_6deviceE +_ZN4sycl3_V13ext6oneapi12experimental10ipc_memory3putERSt6vectorISt4byteSaIS6_EERKNS0_7contextE +_ZN4sycl3_V13ext6oneapi12experimental10ipc_memory4openERSt6vectorISt4byteSaIS6_EERKNS0_7contextERKNS0_6deviceE _ZN4sycl3_V13ext6oneapi12experimental10ipc_memory5closeEPvRKNS0_7contextE _ZN4sycl3_V13ext6oneapi12experimental10mem_adviseENS0_5queueEPvmiRKNS0_6detail13code_locationE _ZN4sycl3_V13ext6oneapi12experimental11memory_pool21increase_threshold_toEm diff --git a/sycl/unittests/Extensions/IPC.cpp b/sycl/unittests/Extensions/IPC.cpp index 0235ae93b7e4b..b17f0d85cee7b 100644 --- a/sycl/unittests/Extensions/IPC.cpp +++ b/sycl/unittests/Extensions/IPC.cpp @@ -22,7 +22,9 @@ int DummyInt = 42; void *DummyPtr = &DummyInt; constexpr size_t DummyHandleDataSize = 10; -char DummyHandleData[DummyHandleDataSize] = {9, 8, 7, 6, 5, 4, 3, 2, 1}; +std::byte DummyHandleData[DummyHandleDataSize] = { + std::byte{9}, std::byte{8}, std::byte{7}, std::byte{6}, std::byte{5}, + std::byte{4}, std::byte{3}, std::byte{2}, std::byte{1}}; thread_local int urIPCGetMemHandleExp_counter = 0; thread_local int urIPCPutMemHandleExp_counter = 0; From 3bf5099052f411213f986f4925270dc8902b98f0 Mon Sep 17 00:00:00 2001 From: "Larsen, Steffen" Date: Mon, 13 Oct 2025 07:50:20 -0700 Subject: [PATCH 24/38] Fix include Signed-off-by: Larsen, Steffen --- sycl/include/sycl/ext/oneapi/experimental/ipc_memory.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/sycl/include/sycl/ext/oneapi/experimental/ipc_memory.hpp b/sycl/include/sycl/ext/oneapi/experimental/ipc_memory.hpp index 02dfa59daf797..dfd11ee8ace18 100644 --- a/sycl/include/sycl/ext/oneapi/experimental/ipc_memory.hpp +++ b/sycl/include/sycl/ext/oneapi/experimental/ipc_memory.hpp @@ -14,6 +14,7 @@ #include #include +#include namespace sycl { inline namespace _V1 { From ebdc9e3b018700dfdd47b5da861350c097955d02 Mon Sep 17 00:00:00 2001 From: "Larsen, Steffen" Date: Tue, 14 Oct 2025 00:00:37 -0700 Subject: [PATCH 25/38] Fix tests Signed-off-by: Larsen, Steffen --- sycl/include/sycl/ext/oneapi/experimental/ipc_memory.hpp | 2 +- sycl/test-e2e/Experimental/ipc_memory.cpp | 7 ++++--- sycl/test/abi/sycl_symbols_windows.dump | 6 +++--- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/sycl/include/sycl/ext/oneapi/experimental/ipc_memory.hpp b/sycl/include/sycl/ext/oneapi/experimental/ipc_memory.hpp index dfd11ee8ace18..fae1f2b6235a5 100644 --- a/sycl/include/sycl/ext/oneapi/experimental/ipc_memory.hpp +++ b/sycl/include/sycl/ext/oneapi/experimental/ipc_memory.hpp @@ -14,7 +14,7 @@ #include #include -#include +#include namespace sycl { inline namespace _V1 { diff --git a/sycl/test-e2e/Experimental/ipc_memory.cpp b/sycl/test-e2e/Experimental/ipc_memory.cpp index 48a4ba7ae0431..b32de39cc81a2 100644 --- a/sycl/test-e2e/Experimental/ipc_memory.cpp +++ b/sycl/test-e2e/Experimental/ipc_memory.cpp @@ -53,7 +53,8 @@ int spawner(int argc, char *argv[]) { size_t HandleDataSize = HandleData.size(); std::fstream FS(CommsFile, std::ios_base::out | std::ios_base::binary); FS.write(reinterpret_cast(&HandleDataSize), sizeof(size_t)); - FS.write(HandleData.data(), HandleDataSize); + FS.write(reinterpret_cast(HandleData.data()), + HandleDataSize); } // Spawn other process with an arguement. @@ -83,8 +84,8 @@ int consumer() { std::fstream FS(CommsFile, std::ios_base::in | std::ios_base::binary); size_t HandleSize = 0; FS.read(reinterpret_cast(&HandleSize), sizeof(size_t)); - std::unique_ptr HandleData{new char[HandleSize]}; - FS.read(HandleData.get(), HandleSize); + std::unique_ptr HandleData{new std::byte[HandleSize]}; + FS.read(reinterpret_cast(HandleData.get()), HandleSize); // Open IPC handle. syclexp::ipc_memory::handle_data_t Handle{HandleData.get(), diff --git a/sycl/test/abi/sycl_symbols_windows.dump b/sycl/test/abi/sycl_symbols_windows.dump index 8eab3d1a548ce..e05f726cbc504 100644 --- a/sycl/test/abi/sycl_symbols_windows.dump +++ b/sycl/test/abi/sycl_symbols_windows.dump @@ -4051,7 +4051,7 @@ ?frexp_impl@detail@_V1@sycl@@YANNPEAH@Z ?get@context@_V1@sycl@@QEBAPEAU_cl_context@@XZ ?get@device@_V1@sycl@@QEBAPEAU_cl_device_id@@XZ -?get@ipc_memory@experimental@oneapi@ext@_V1@sycl@@YA?AV?$vector@DV?$allocator@D@std@@@std@@PEAXAEBVcontext@56@@Z +?get@ipc_memory@experimental@oneapi@ext@_V1@sycl@@YA?AV?$vector@W4byte@std@@V?$allocator@W4byte@std@@@2@@std@@PEAXAEBVcontext@56@@Z ?get@kernel@_V1@sycl@@QEBAPEAU_cl_kernel@@XZ ?get@platform@_V1@sycl@@QEBAPEAU_cl_platform_id@@XZ ?get@queue@_V1@sycl@@QEBAPEAU_cl_command_queue@@XZ @@ -4359,7 +4359,7 @@ ?modf_impl@detail@_V1@sycl@@YANNPEAN@Z ?name@SYCLCategory@detail@_V1@sycl@@UEBAPEBDXZ ?native_specialization_constant@kernel_bundle_plain@detail@_V1@sycl@@QEBA_NXZ -?open@ipc_memory@experimental@oneapi@ext@_V1@sycl@@YAPEAXAEAV?$vector@DV?$allocator@D@std@@@std@@AEBVcontext@56@AEBVdevice@56@@Z +?open@ipc_memory@experimental@oneapi@ext@_V1@sycl@@YAPEAXAEAV?$vector@W4byte@std@@V?$allocator@W4byte@std@@@2@@std@@AEBVcontext@56@AEBVdevice@56@@Z ?parallel_for@handler@_V1@sycl@@QEAAXV?$range@$00@23@Vkernel@23@@Z ?parallel_for@handler@_V1@sycl@@QEAAXV?$range@$01@23@Vkernel@23@@Z ?parallel_for@handler@_V1@sycl@@QEAAXV?$range@$02@23@Vkernel@23@@Z @@ -4379,7 +4379,7 @@ ?print_graph@modifiable_command_graph@detail@experimental@oneapi@ext@_V1@sycl@@IEBAXVstring_view@267@_N@Z ?print_graph@modifiable_command_graph@detail@experimental@oneapi@ext@_V1@sycl@@QEBAXV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@_N@Z ?processArg@handler@_V1@sycl@@AEAAXPEAXAEBW4kernel_param_kind_t@detail@23@H_KAEA_K_N4@Z -?put@ipc_memory@experimental@oneapi@ext@_V1@sycl@@YAXAEAV?$vector@DV?$allocator@D@std@@@std@@AEBVcontext@56@@Z +?put@ipc_memory@experimental@oneapi@ext@_V1@sycl@@YAXAEAV?$vector@W4byte@std@@V?$allocator@W4byte@std@@@2@@std@@AEBVcontext@56@@Z ?query@tls_code_loc_t@detail@_V1@sycl@@QEAAAEBUcode_location@234@XZ ?reduComputeWGSize@detail@_V1@sycl@@YA_K_K0AEA_K@Z ?reduGetMaxNumConcurrentWorkGroups@detail@_V1@sycl@@YAIAEAVhandler@23@@Z From 02e961326cb15f76ce751bdd1911ace33e79bb7b Mon Sep 17 00:00:00 2001 From: "Larsen, Steffen" Date: Tue, 14 Oct 2025 00:13:52 -0700 Subject: [PATCH 26/38] Fix stylistic issues Signed-off-by: Larsen, Steffen --- ...cl_ext_oneapi_inter_process_communication.asciidoc | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/sycl/doc/extensions/experimental/sycl_ext_oneapi_inter_process_communication.asciidoc b/sycl/doc/extensions/experimental/sycl_ext_oneapi_inter_process_communication.asciidoc index 4459a41384a51..e084812883172 100644 --- a/sycl/doc/extensions/experimental/sycl_ext_oneapi_inter_process_communication.asciidoc +++ b/sycl/doc/extensions/experimental/sycl_ext_oneapi_inter_process_communication.asciidoc @@ -95,8 +95,8 @@ enum class aspect { } ---- -If a SYCL device has this aspect, that device supports `ipc_memory::get()` free -function specified in the following section. +If a SYCL device has this aspect, that device supports the `get` and `open` +functions specified in the following section. === Inter-process communicable memory @@ -140,7 +140,7 @@ context `ctx` and device _D_ returns `true` for _Returns:_ An IPC "handle" to this USM memory allocation. The bytes of this handle can be transferred to another process on the same system, and the other process can use the handle to get a pointer to the same USM allocation through a -call to the `open()` function. +call to the `open` function. !==== a! @@ -151,7 +151,7 @@ void put(handle_data_t &handle_data, const sycl::context &ctx) !==== _Preconditions:_ `handle_data` is the IPC "handle" to USM device memory that was -returned from a call to get either in this process or in some other process on +returned from a call to `get` either in this process or in some other process on the same system. The USM device memory has not yet been freed in this process. _Effects:_ Deallocates resources associated with the handle. These resources are @@ -178,6 +178,7 @@ it cannot be passed to `sycl::free`. Instead, use the `close` function to free this memory pointer. _Throws:_ + * An exception with the `errc::feature_not_supported` error code if device `dev` does not have `aspect::ext_oneapi_ipc_memory`. * An exception with the `errc::invalid` error code if the handle data @@ -192,7 +193,7 @@ static void close(void *ptr, const sycl::context &ctx) !==== _Effects:_ Closes a device USM pointer previously returned by a call to -`open()`. +the `open` function. |==== From eeb0a8a02a78cb747470e2adda05bdde447b3f4f Mon Sep 17 00:00:00 2001 From: "Larsen, Steffen" Date: Wed, 15 Oct 2025 00:56:57 -0700 Subject: [PATCH 27/38] Make device lookup when failing Signed-off-by: Larsen, Steffen --- ...neapi_inter_process_communication.asciidoc | 7 +++-- sycl/source/ipc_memory.cpp | 26 ++++++++++++++++--- 2 files changed, 28 insertions(+), 5 deletions(-) diff --git a/sycl/doc/extensions/experimental/sycl_ext_oneapi_inter_process_communication.asciidoc b/sycl/doc/extensions/experimental/sycl_ext_oneapi_inter_process_communication.asciidoc index e084812883172..66b44dc88e942 100644 --- a/sycl/doc/extensions/experimental/sycl_ext_oneapi_inter_process_communication.asciidoc +++ b/sycl/doc/extensions/experimental/sycl_ext_oneapi_inter_process_communication.asciidoc @@ -134,14 +134,17 @@ handle_data_t get(void *ptr, const sycl::context &ctx) !==== _Preconditions:_ `ptr` is a pointer to USM device memory on some device _D_ in -context `ctx` and device _D_ returns `true` for -`device::has(aspect::ext_oneapi_ipc_memory)`. +context `ctx`. `ctx` is the same context as `ptr` was allocated against, using +the USM device memory allocation routines. _Returns:_ An IPC "handle" to this USM memory allocation. The bytes of this handle can be transferred to another process on the same system, and the other process can use the handle to get a pointer to the same USM allocation through a call to the `open` function. +_Throws:_ An exception with the `errc::feature_not_supported` error code if +device _D_ does not have `aspect::ext_oneapi_ipc_memory`. + !==== a! [source] diff --git a/sycl/source/ipc_memory.cpp b/sycl/source/ipc_memory.cpp index 97fa05d3fa10d..8e5a7c0728b5e 100644 --- a/sycl/source/ipc_memory.cpp +++ b/sycl/source/ipc_memory.cpp @@ -9,6 +9,7 @@ #include #include #include +#include #include namespace sycl { @@ -19,13 +20,32 @@ __SYCL_EXPORT handle_data_t get(void *Ptr, const sycl::context &Ctx) { auto CtxImpl = sycl::detail::getSyclObjImpl(Ctx); sycl::detail::adapter_impl &Adapter = CtxImpl->getAdapter(); + // If the API fails, check that the device actually supported it. We only do + // this if UR fails to avoid the device-lookup overhead. + auto CheckDeviceSupport = [Ptr, &Ctx]() { + sycl::device Dev = get_pointer_device(Ptr, Ctx); + if (!Dev.has(aspect::ext_oneapi_ipc_memory)) + throw sycl::exception( + sycl::make_error_code(errc::feature_not_supported), + "Device does not support aspect::ext_oneapi_ipc_memory."); + }; + size_t HandleSize = 0; - Adapter.call( - CtxImpl->getHandleRef(), Ptr, nullptr, &HandleSize); + auto UrRes = + Adapter.call_nocheck( + CtxImpl->getHandleRef(), Ptr, nullptr, &HandleSize); + if (UrRes != UR_RESULT_SUCCESS) { + CheckDeviceSupport(); + Adapter.checkUrResult(UrRes); + } handle_data_t Res(HandleSize); - Adapter.call( + UrRes = Adapter.call_nocheck( CtxImpl->getHandleRef(), Ptr, Res.data(), nullptr); + if (UrRes != UR_RESULT_SUCCESS) { + CheckDeviceSupport(); + Adapter.checkUrResult(UrRes); + } return Res; } From 0f3b66ffa4f5a9ffa75c7eacc5ab6c4f11376abe Mon Sep 17 00:00:00 2001 From: "Larsen, Steffen" Date: Thu, 16 Oct 2025 23:32:00 -0700 Subject: [PATCH 28/38] Fix typo and add shortcut Signed-off-by: Larsen, Steffen --- ...neapi_inter_process_communication.asciidoc | 113 +++++++++++++++++- 1 file changed, 112 insertions(+), 1 deletion(-) diff --git a/sycl/doc/extensions/experimental/sycl_ext_oneapi_inter_process_communication.asciidoc b/sycl/doc/extensions/experimental/sycl_ext_oneapi_inter_process_communication.asciidoc index 66b44dc88e942..1ad5084fedfc2 100644 --- a/sycl/doc/extensions/experimental/sycl_ext_oneapi_inter_process_communication.asciidoc +++ b/sycl/doc/extensions/experimental/sycl_ext_oneapi_inter_process_communication.asciidoc @@ -37,10 +37,26 @@ https://github.com/intel/llvm/issues == Dependencies +:khr-default-context: https://registry.khronos.org/SYCL/specs/sycl-2020/html/sycl-2020.html#sec:khr-default-context + This extension is written against the SYCL 2020 revision 10 specification. All references below to the "core SYCL specification" or to section numbers in the SYCL specification refer to that revision. +[_Note:_ The APIs in this extension uses the concept of a per-platform +default context as specified in section 4.6.2 "Platform class" of the core SYCL +specification. +As a convenience, this extension specification describes the behavior of its +APIs by using the `khr_get_default_context` function from {khr-default-context}[ +sycl_khr_default_context], however there is no true dependency on that +extension. +An implementation could still implement +sycl_ext_oneapi_inter_process_communication even without implementing +sycl_khr_default_context because the core SYCL specification still requires +there to be a per-platform default context even if the core SYCL specification +does not provide a convenient way to get it. +_{endnote}_] + == Status @@ -56,7 +72,7 @@ specification.* This extension adds the ability for SYCL programs to share device USM memory allocations between processes. This is done by the allocating process creating -a new IPC memory handle through the new free frunctions and transferring the +a new IPC memory handle through the new free functions and transferring the returned handle data to the other processes. The other processes can use the handle data to retrieve the corresponding device USM memory. @@ -112,13 +128,23 @@ using handle_data_t = std::vector; handle_data_t get(void *ptr, const sycl::context &ctx); +handle_data_t get(void *ptr); + +void put(handle_data_t &handle_data, const sycl::context &ctx); + void put(handle_data_t &handle_data, const sycl::context &ctx); static void *open(handle_data_t handle_data, const sycl::context &ctx, const sycl::device &dev); +static void *open(handle_data_t handle_data, const sycl::device &dev); + +static void *open(handle_data_t handle_data); + static void close(void *ptr, const sycl::context &ctx); +static void close(void *ptr); + } ``` @@ -145,6 +171,23 @@ call to the `open` function. _Throws:_ An exception with the `errc::feature_not_supported` error code if device _D_ does not have `aspect::ext_oneapi_ipc_memory`. +!==== +a! +[source] +---- +handle_data_t get(void *ptr) +---- +!==== + +_Effects_: Equivalent to: + +[source,c++,indent=2] +---- +sycl::device d; +sycl::contxt ctxt = d.get_platform().khr_get_default_context(); +return ipc_memory::get(ptr, ctxt); +---- + !==== a! [source] @@ -161,6 +204,23 @@ _Effects:_ Deallocates resources associated with the handle. These resources are automatically deallocated when the USM device memory is freed, so it is not strictly necessary to call the `put` function. +!==== +a! +[source] +---- +void put(handle_data_t &handle_data) +---- +!==== + +_Effects_: Equivalent to: + +[source,c++,indent=2] +---- +sycl::device d; +sycl::contxt ctxt = d.get_platform().khr_get_default_context(); +return ipc_memory::put(handle_data, ctxt); +---- + !==== a! [source] @@ -187,6 +247,40 @@ _Throws:_ * An exception with the `errc::invalid` error code if the handle data `handle_data` has an unexpected number of bytes. +!==== +a! +[source] +---- +static void *open(handle_data_t &handle_data, const sycl::device &dev) +---- +!==== + +_Effects_: Equivalent to: + +[source,c++,indent=2] +---- +sycl::contxt ctxt = dev.get_platform().khr_get_default_context(); +return ipc_memory::put(handle_data, ctxt, dev); +---- + +!==== +a! +[source] +---- +static void *open(handle_data_t &handle_data, const sycl::context &ctx, + const sycl::device &dev) +---- +!==== + +_Effects_: Equivalent to: + +[source,c++,indent=2] +---- +sycl::device d; +sycl::contxt ctxt = d.get_platform().khr_get_default_context(); +return ipc_memory::open(handle_data, ctxt, d); +---- + !==== a! [source] @@ -198,6 +292,23 @@ static void close(void *ptr, const sycl::context &ctx) _Effects:_ Closes a device USM pointer previously returned by a call to the `open` function. +!==== +a! +[source] +---- +static void close(void *ptr) +---- +!==== + +_Effects_: Equivalent to: + +[source,c++,indent=2] +---- +sycl::device d; +sycl::contxt ctxt = d.get_platform().khr_get_default_context(); +return ipc_memory::close(ptr, ctxt); +---- + |==== From 31aa6a3cb60a4c0ca02d68f0eb35f677ab2e5f37 Mon Sep 17 00:00:00 2001 From: "Larsen, Steffen" Date: Thu, 16 Oct 2025 23:35:34 -0700 Subject: [PATCH 29/38] Address code comments Signed-off-by: Larsen, Steffen --- sycl/source/feature_test.hpp.in | 2 +- sycl/test-e2e/Experimental/ipc_memory.cpp | 3 +-- sycl/unittests/Extensions/IPC.cpp | 2 +- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/sycl/source/feature_test.hpp.in b/sycl/source/feature_test.hpp.in index 0f1e228f1d200..362c31ee241bf 100644 --- a/sycl/source/feature_test.hpp.in +++ b/sycl/source/feature_test.hpp.in @@ -127,7 +127,7 @@ inline namespace _V1 { #define SYCL_KHR_DEFAULT_CONTEXT 1 #define SYCL_EXT_INTEL_EVENT_MODE 1 #define SYCL_EXT_ONEAPI_TANGLE 1 -#define SYCL_EXT_ONEAPI_IPC 1 +#define SYCL_EXT_ONEAPI_INTER_PROCESS_COMMUNICATION 1 // Unfinished KHR extensions. These extensions are only available if the // __DPCPP_ENABLE_UNFINISHED_KHR_EXTENSIONS macro is defined. diff --git a/sycl/test-e2e/Experimental/ipc_memory.cpp b/sycl/test-e2e/Experimental/ipc_memory.cpp index b32de39cc81a2..19d8cb56c772c 100644 --- a/sycl/test-e2e/Experimental/ipc_memory.cpp +++ b/sycl/test-e2e/Experimental/ipc_memory.cpp @@ -57,7 +57,7 @@ int spawner(int argc, char *argv[]) { HandleDataSize); } - // Spawn other process with an arguement. + // Spawn other process with an argument. std::string Cmd = std::string{argv[0]} + " 1"; std::cout << "Spawning: " << Cmd << std::endl; std::system(Cmd.c_str()); @@ -116,6 +116,5 @@ int consumer() { } int main(int argc, char *argv[]) { - // We either have the spawner (if no extra argument it provided) or return argc == 1 ? spawner(argc, argv) : consumer(); } diff --git a/sycl/unittests/Extensions/IPC.cpp b/sycl/unittests/Extensions/IPC.cpp index b17f0d85cee7b..196bb4c795bf9 100644 --- a/sycl/unittests/Extensions/IPC.cpp +++ b/sycl/unittests/Extensions/IPC.cpp @@ -24,7 +24,7 @@ void *DummyPtr = &DummyInt; constexpr size_t DummyHandleDataSize = 10; std::byte DummyHandleData[DummyHandleDataSize] = { std::byte{9}, std::byte{8}, std::byte{7}, std::byte{6}, std::byte{5}, - std::byte{4}, std::byte{3}, std::byte{2}, std::byte{1}}; + std::byte{4}, std::byte{3}, std::byte{2}, std::byte{1}, std::byte{0}}; thread_local int urIPCGetMemHandleExp_counter = 0; thread_local int urIPCPutMemHandleExp_counter = 0; From 33d34a9426341766b5ee781b4fd55a4645145879 Mon Sep 17 00:00:00 2001 From: "Larsen, Steffen" Date: Thu, 16 Oct 2025 23:50:11 -0700 Subject: [PATCH 30/38] Address spec comments Signed-off-by: Larsen, Steffen --- ..._oneapi_inter_process_communication.asciidoc | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/sycl/doc/extensions/experimental/sycl_ext_oneapi_inter_process_communication.asciidoc b/sycl/doc/extensions/experimental/sycl_ext_oneapi_inter_process_communication.asciidoc index 1ad5084fedfc2..190ca0da2fb0d 100644 --- a/sycl/doc/extensions/experimental/sycl_ext_oneapi_inter_process_communication.asciidoc +++ b/sycl/doc/extensions/experimental/sycl_ext_oneapi_inter_process_communication.asciidoc @@ -159,9 +159,9 @@ handle_data_t get(void *ptr, const sycl::context &ctx) ---- !==== -_Preconditions:_ `ptr` is a pointer to USM device memory on some device _D_ in -context `ctx`. `ctx` is the same context as `ptr` was allocated against, using -the USM device memory allocation routines. +_Preconditions:_ `ptr` is a pointer to USM device memory on some device _D_, and +`ctx` is the same context as `ptr` was allocated against, using the USM device +memory allocation routines. _Returns:_ An IPC "handle" to this USM memory allocation. The bytes of this handle can be transferred to another process on the same system, and the other @@ -236,9 +236,10 @@ other process on the same system. That USM device memory is accessible on device `dev`. _Returns:_ A pointer to the same USM device memory represented by `handle_data`. -This pointer can be used in any API taking a USM device memory pointer, except -it cannot be passed to `sycl::free`. Instead, use the `close` function to free -this memory pointer. +The returned pointer is associated with context `ctx`. It can be used wherever a +USM device pointer for device `dev` and context `ctx` is expected, except it +cannot be passed to `sycl::free`. Instead, use the `close` function to free this +memory pointer. _Throws:_ @@ -289,6 +290,10 @@ static void close(void *ptr, const sycl::context &ctx) ---- !==== +_Precondition:_ `ptr` was previously returned from a call to the `open` function +in this same process, where `ctx` was passed as the context. This `ptr` value +has not yet been closed by calling the `close` function. + _Effects:_ Closes a device USM pointer previously returned by a call to the `open` function. From a1a7945da8ab4f72afe0d4b2a53da6c25f9f8953 Mon Sep 17 00:00:00 2001 From: "Larsen, Steffen" Date: Fri, 17 Oct 2025 00:17:24 -0700 Subject: [PATCH 31/38] Clarify put result Signed-off-by: Larsen, Steffen --- .../sycl_ext_oneapi_inter_process_communication.asciidoc | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/sycl/doc/extensions/experimental/sycl_ext_oneapi_inter_process_communication.asciidoc b/sycl/doc/extensions/experimental/sycl_ext_oneapi_inter_process_communication.asciidoc index 190ca0da2fb0d..e64287099ce3b 100644 --- a/sycl/doc/extensions/experimental/sycl_ext_oneapi_inter_process_communication.asciidoc +++ b/sycl/doc/extensions/experimental/sycl_ext_oneapi_inter_process_communication.asciidoc @@ -202,7 +202,10 @@ the same system. The USM device memory has not yet been freed in this process. _Effects:_ Deallocates resources associated with the handle. These resources are automatically deallocated when the USM device memory is freed, so it is not -strictly necessary to call the `put` function. +strictly necessary to call the `put` function. After the resources associated +with the handle have been deallocated, i.e. through a call to the `put` function +or through freeing the USM device memory, the handle data is invalid and using +it in the `put` and `open` functions will result in undefined behavior. !==== a! From 3bc26d073295d0f466b07e9ca2a0502fd93b971f Mon Sep 17 00:00:00 2001 From: "Larsen, Steffen" Date: Fri, 17 Oct 2025 00:19:52 -0700 Subject: [PATCH 32/38] Add note about matching open and close Signed-off-by: Larsen, Steffen --- .../sycl_ext_oneapi_inter_process_communication.asciidoc | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/sycl/doc/extensions/experimental/sycl_ext_oneapi_inter_process_communication.asciidoc b/sycl/doc/extensions/experimental/sycl_ext_oneapi_inter_process_communication.asciidoc index e64287099ce3b..ec195b826a444 100644 --- a/sycl/doc/extensions/experimental/sycl_ext_oneapi_inter_process_communication.asciidoc +++ b/sycl/doc/extensions/experimental/sycl_ext_oneapi_inter_process_communication.asciidoc @@ -244,6 +244,11 @@ USM device pointer for device `dev` and context `ctx` is expected, except it cannot be passed to `sycl::free`. Instead, use the `close` function to free this memory pointer. +[_Note:_ The `open` function can be called multiple times on the same handle +within the same process. The number of calls to the `close` function must be +equal to the number of calls to the `open` function to free the memory pointer. +_{endnote}_] + _Throws:_ * An exception with the `errc::feature_not_supported` error code if device From 6cb2cf3da877c8cfc7aa0f0532f0f5980e6bbc28 Mon Sep 17 00:00:00 2001 From: "Larsen, Steffen" Date: Fri, 17 Oct 2025 00:24:58 -0700 Subject: [PATCH 33/38] Add note about validity of opened ptrs after put Signed-off-by: Larsen, Steffen --- .../sycl_ext_oneapi_inter_process_communication.asciidoc | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/sycl/doc/extensions/experimental/sycl_ext_oneapi_inter_process_communication.asciidoc b/sycl/doc/extensions/experimental/sycl_ext_oneapi_inter_process_communication.asciidoc index ec195b826a444..2fb45fa741462 100644 --- a/sycl/doc/extensions/experimental/sycl_ext_oneapi_inter_process_communication.asciidoc +++ b/sycl/doc/extensions/experimental/sycl_ext_oneapi_inter_process_communication.asciidoc @@ -207,6 +207,11 @@ with the handle have been deallocated, i.e. through a call to the `put` function or through freeing the USM device memory, the handle data is invalid and using it in the `put` and `open` functions will result in undefined behavior. +[_Note:_ Any pointers retrieved through a call to the `open` function in any +process on the system will still be valid and must still be freed through calls +to the `close` function. +_{endnote}_] + !==== a! [source] From 7883b93a1dcdd662c785acaab710b78edec24cb5 Mon Sep 17 00:00:00 2001 From: "Larsen, Steffen" Date: Fri, 17 Oct 2025 00:27:08 -0700 Subject: [PATCH 34/38] Clarify last comment a little more Signed-off-by: Larsen, Steffen --- .../sycl_ext_oneapi_inter_process_communication.asciidoc | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/sycl/doc/extensions/experimental/sycl_ext_oneapi_inter_process_communication.asciidoc b/sycl/doc/extensions/experimental/sycl_ext_oneapi_inter_process_communication.asciidoc index 2fb45fa741462..ff1de79f75c06 100644 --- a/sycl/doc/extensions/experimental/sycl_ext_oneapi_inter_process_communication.asciidoc +++ b/sycl/doc/extensions/experimental/sycl_ext_oneapi_inter_process_communication.asciidoc @@ -208,8 +208,10 @@ or through freeing the USM device memory, the handle data is invalid and using it in the `put` and `open` functions will result in undefined behavior. [_Note:_ Any pointers retrieved through a call to the `open` function in any -process on the system will still be valid and must still be freed through calls -to the `close` function. +process on the system will still be valid after a call to the `put` function and +must still be freed through calls to the `close` function. They are however no +longer valid if the associated memory USM device memory was freed through a call +to the `sycl::free` function. _{endnote}_] !==== From 4410d559942c12c3db1a3152f7e08fd29b88eb06 Mon Sep 17 00:00:00 2001 From: "Larsen, Steffen" Date: Fri, 17 Oct 2025 05:45:31 -0700 Subject: [PATCH 35/38] Address newest comments Signed-off-by: Larsen, Steffen --- ...neapi_inter_process_communication.asciidoc | 45 ++++++++++--------- .../ext/oneapi/experimental/ipc_memory.hpp | 35 +++++++++++++-- 2 files changed, 56 insertions(+), 24 deletions(-) diff --git a/sycl/doc/extensions/experimental/sycl_ext_oneapi_inter_process_communication.asciidoc b/sycl/doc/extensions/experimental/sycl_ext_oneapi_inter_process_communication.asciidoc index ff1de79f75c06..40fbd27c4b79d 100644 --- a/sycl/doc/extensions/experimental/sycl_ext_oneapi_inter_process_communication.asciidoc +++ b/sycl/doc/extensions/experimental/sycl_ext_oneapi_inter_process_communication.asciidoc @@ -132,18 +132,18 @@ handle_data_t get(void *ptr); void put(handle_data_t &handle_data, const sycl::context &ctx); -void put(handle_data_t &handle_data, const sycl::context &ctx); +void put(handle_data_t &handle_data); -static void *open(handle_data_t handle_data, const sycl::context &ctx, +void *open(handle_data_t &handle_data, const sycl::context &ctx, const sycl::device &dev); -static void *open(handle_data_t handle_data, const sycl::device &dev); +void *open(handle_data_t &handle_data, const sycl::device &dev); -static void *open(handle_data_t handle_data); +void *open(handle_data_t &handle_data); -static void close(void *ptr, const sycl::context &ctx); +void close(void *ptr, const sycl::context &ctx); -static void close(void *ptr); +void close(void *ptr); } ``` @@ -184,7 +184,7 @@ _Effects_: Equivalent to: [source,c++,indent=2] ---- sycl::device d; -sycl::contxt ctxt = d.get_platform().khr_get_default_context(); +sycl::context ctxt = d.get_platform().khr_get_default_context(); return ipc_memory::get(ptr, ctxt); ---- @@ -209,9 +209,7 @@ it in the `put` and `open` functions will result in undefined behavior. [_Note:_ Any pointers retrieved through a call to the `open` function in any process on the system will still be valid after a call to the `put` function and -must still be freed through calls to the `close` function. They are however no -longer valid if the associated memory USM device memory was freed through a call -to the `sycl::free` function. +must still be freed through calls to the `close` function. _{endnote}_] !==== @@ -227,15 +225,15 @@ _Effects_: Equivalent to: [source,c++,indent=2] ---- sycl::device d; -sycl::contxt ctxt = d.get_platform().khr_get_default_context(); -return ipc_memory::put(handle_data, ctxt); +sycl::context ctxt = d.get_platform().khr_get_default_context(); +ipc_memory::put(handle_data, ctxt); ---- !==== a! [source] ---- -static void *open(handle_data_t &handle_data, const sycl::context &ctx, +void *open(handle_data_t &handle_data, const sycl::context &ctx, const sycl::device &dev) ---- !==== @@ -256,6 +254,11 @@ within the same process. The number of calls to the `close` function must be equal to the number of calls to the `open` function to free the memory pointer. _{endnote}_] +[_Note:_ The pointer returned from a call to the `open` function is no longer +valid if the associated USM device memory is freed through a call to the +`sycl::free` function. +_{endnote}_] + _Throws:_ * An exception with the `errc::feature_not_supported` error code if device @@ -267,7 +270,7 @@ _Throws:_ a! [source] ---- -static void *open(handle_data_t &handle_data, const sycl::device &dev) +void *open(handle_data_t &handle_data, const sycl::device &dev) ---- !==== @@ -275,7 +278,7 @@ _Effects_: Equivalent to: [source,c++,indent=2] ---- -sycl::contxt ctxt = dev.get_platform().khr_get_default_context(); +sycl::context ctxt = dev.get_platform().khr_get_default_context(); return ipc_memory::put(handle_data, ctxt, dev); ---- @@ -283,7 +286,7 @@ return ipc_memory::put(handle_data, ctxt, dev); a! [source] ---- -static void *open(handle_data_t &handle_data, const sycl::context &ctx, +void *open(handle_data_t &handle_data, const sycl::context &ctx, const sycl::device &dev) ---- !==== @@ -293,7 +296,7 @@ _Effects_: Equivalent to: [source,c++,indent=2] ---- sycl::device d; -sycl::contxt ctxt = d.get_platform().khr_get_default_context(); +sycl::context ctxt = d.get_platform().khr_get_default_context(); return ipc_memory::open(handle_data, ctxt, d); ---- @@ -301,7 +304,7 @@ return ipc_memory::open(handle_data, ctxt, d); a! [source] ---- -static void close(void *ptr, const sycl::context &ctx) +void close(void *ptr, const sycl::context &ctx) ---- !==== @@ -316,7 +319,7 @@ the `open` function. a! [source] ---- -static void close(void *ptr) +void close(void *ptr) ---- !==== @@ -325,8 +328,8 @@ _Effects_: Equivalent to: [source,c++,indent=2] ---- sycl::device d; -sycl::contxt ctxt = d.get_platform().khr_get_default_context(); -return ipc_memory::close(ptr, ctxt); +sycl::context ctxt = d.get_platform().khr_get_default_context(); +ipc_memory::close(ptr, ctxt); ---- |==== diff --git a/sycl/include/sycl/ext/oneapi/experimental/ipc_memory.hpp b/sycl/include/sycl/ext/oneapi/experimental/ipc_memory.hpp index fae1f2b6235a5..f5dc0c5e89ba4 100644 --- a/sycl/include/sycl/ext/oneapi/experimental/ipc_memory.hpp +++ b/sycl/include/sycl/ext/oneapi/experimental/ipc_memory.hpp @@ -10,8 +10,11 @@ #if (!defined(_HAS_STD_BYTE) || _HAS_STD_BYTE != 0) +#include #include #include +#include +#include #include #include @@ -19,22 +22,48 @@ namespace sycl { inline namespace _V1 { -class context; -class device; - namespace ext::oneapi::experimental::ipc_memory { using handle_data_t = std::vector; __SYCL_EXPORT handle_data_t get(void *Ptr, const sycl::context &Ctx); +inline handle_data_t get(void *Ptr) { + sycl::device Dev; + sycl::context Ctx = Dev.get_platform().khr_get_default_context(); + return ipc_memory::get(Ptr, Ctx); +} + __SYCL_EXPORT void put(handle_data_t &HandleData, const sycl::context &Ctx); +inline void put(handle_data_t &HandleData) { + sycl::device Dev; + sycl::context Ctx = Dev.get_platform().khr_get_default_context(); + ipc_memory::put(HandleData, Ctx); +} + __SYCL_EXPORT void *open(handle_data_t &HandleData, const sycl::context &Ctx, const sycl::device &Dev); +inline void *open(handle_data_t &HandleData, const sycl::device &Dev) { + sycl::context Ctx = Dev.get_platform().khr_get_default_context(); + return ipc_memory::open(HandleData, Ctx, Dev); +} + +inline void *open(handle_data_t &HandleData) { + sycl::device Dev; + sycl::context Ctx = Dev.get_platform().khr_get_default_context(); + return ipc_memory::open(HandleData, Ctx, Dev); +} + __SYCL_EXPORT void close(void *Ptr, const sycl::context &Ctx); +inline void close(void *Ptr) { + sycl::device Dev; + sycl::context Ctx = Dev.get_platform().khr_get_default_context(); + ipc_memory::close(Ptr, Ctx); +} + } // namespace ext::oneapi::experimental::ipc_memory } // namespace _V1 } // namespace sycl From 63315d946f588170b29cf2ab99bd4591a3608723 Mon Sep 17 00:00:00 2001 From: "Larsen, Steffen" Date: Fri, 17 Oct 2025 07:28:08 -0700 Subject: [PATCH 36/38] Make arguments const and make work-around Signed-off-by: Larsen, Steffen --- ...neapi_inter_process_communication.asciidoc | 20 +++++++-------- .../ext/oneapi/experimental/ipc_memory.hpp | 13 +++++----- sycl/source/ipc_memory.cpp | 25 +++++++++++++++---- 3 files changed, 37 insertions(+), 21 deletions(-) diff --git a/sycl/doc/extensions/experimental/sycl_ext_oneapi_inter_process_communication.asciidoc b/sycl/doc/extensions/experimental/sycl_ext_oneapi_inter_process_communication.asciidoc index 40fbd27c4b79d..38638594eb64d 100644 --- a/sycl/doc/extensions/experimental/sycl_ext_oneapi_inter_process_communication.asciidoc +++ b/sycl/doc/extensions/experimental/sycl_ext_oneapi_inter_process_communication.asciidoc @@ -130,16 +130,16 @@ handle_data_t get(void *ptr, const sycl::context &ctx); handle_data_t get(void *ptr); -void put(handle_data_t &handle_data, const sycl::context &ctx); +void put(const handle_data_t &handle_data, const sycl::context &ctx); -void put(handle_data_t &handle_data); +void put(const handle_data_t &handle_data); -void *open(handle_data_t &handle_data, const sycl::context &ctx, +void *open(const handle_data_t &handle_data, const sycl::context &ctx, const sycl::device &dev); -void *open(handle_data_t &handle_data, const sycl::device &dev); +void *open(const handle_data_t &handle_data, const sycl::device &dev); -void *open(handle_data_t &handle_data); +void *open(const handle_data_t &handle_data); void close(void *ptr, const sycl::context &ctx); @@ -192,7 +192,7 @@ return ipc_memory::get(ptr, ctxt); a! [source] ---- -void put(handle_data_t &handle_data, const sycl::context &ctx) +void put(const handle_data_t &handle_data, const sycl::context &ctx) ---- !==== @@ -216,7 +216,7 @@ _{endnote}_] a! [source] ---- -void put(handle_data_t &handle_data) +void put(const handle_data_t &handle_data) ---- !==== @@ -233,7 +233,7 @@ ipc_memory::put(handle_data, ctxt); a! [source] ---- -void *open(handle_data_t &handle_data, const sycl::context &ctx, +void *open(const handle_data_t &handle_data, const sycl::context &ctx, const sycl::device &dev) ---- !==== @@ -270,7 +270,7 @@ _Throws:_ a! [source] ---- -void *open(handle_data_t &handle_data, const sycl::device &dev) +void *open(const handle_data_t &handle_data, const sycl::device &dev) ---- !==== @@ -286,7 +286,7 @@ return ipc_memory::put(handle_data, ctxt, dev); a! [source] ---- -void *open(handle_data_t &handle_data, const sycl::context &ctx, +void *open(const handle_data_t &handle_data, const sycl::context &ctx, const sycl::device &dev) ---- !==== diff --git a/sycl/include/sycl/ext/oneapi/experimental/ipc_memory.hpp b/sycl/include/sycl/ext/oneapi/experimental/ipc_memory.hpp index f5dc0c5e89ba4..b213e02fd4434 100644 --- a/sycl/include/sycl/ext/oneapi/experimental/ipc_memory.hpp +++ b/sycl/include/sycl/ext/oneapi/experimental/ipc_memory.hpp @@ -34,23 +34,24 @@ inline handle_data_t get(void *Ptr) { return ipc_memory::get(Ptr, Ctx); } -__SYCL_EXPORT void put(handle_data_t &HandleData, const sycl::context &Ctx); +__SYCL_EXPORT void put(const handle_data_t &HandleData, + const sycl::context &Ctx); -inline void put(handle_data_t &HandleData) { +inline void put(const handle_data_t &HandleData) { sycl::device Dev; sycl::context Ctx = Dev.get_platform().khr_get_default_context(); ipc_memory::put(HandleData, Ctx); } -__SYCL_EXPORT void *open(handle_data_t &HandleData, const sycl::context &Ctx, - const sycl::device &Dev); +__SYCL_EXPORT void *open(const handle_data_t &HandleData, + const sycl::context &Ctx, const sycl::device &Dev); -inline void *open(handle_data_t &HandleData, const sycl::device &Dev) { +inline void *open(const handle_data_t &HandleData, const sycl::device &Dev) { sycl::context Ctx = Dev.get_platform().khr_get_default_context(); return ipc_memory::open(HandleData, Ctx, Dev); } -inline void *open(handle_data_t &HandleData) { +inline void *open(const handle_data_t &HandleData) { sycl::device Dev; sycl::context Ctx = Dev.get_platform().khr_get_default_context(); return ipc_memory::open(HandleData, Ctx, Dev); diff --git a/sycl/source/ipc_memory.cpp b/sycl/source/ipc_memory.cpp index 06a4575c968be..b79ac27cf1ba8 100644 --- a/sycl/source/ipc_memory.cpp +++ b/sycl/source/ipc_memory.cpp @@ -49,15 +49,23 @@ __SYCL_EXPORT handle_data_t get(void *Ptr, const sycl::context &Ctx) { return Res; } -__SYCL_EXPORT void put(handle_data_t &HandleData, const sycl::context &Ctx) { +__SYCL_EXPORT void put(const handle_data_t &HandleData, + const sycl::context &Ctx) { + // TODO: UMF and UR currently requires the handle data to be non-const, so we + // need to make a copy of the data. Once this has been changed, the copy + // can be removed. + // CMPLRLLVM-71181 + // https://github.com/oneapi-src/unified-memory-framework/issues/1536 + handle_data_t HandleDataCopy = HandleData; + auto CtxImpl = sycl::detail::getSyclObjImpl(Ctx); sycl::detail::adapter_impl &Adapter = CtxImpl->getAdapter(); Adapter.call( - CtxImpl->getHandleRef(), HandleData.data()); + CtxImpl->getHandleRef(), HandleDataCopy.data()); } -__SYCL_EXPORT void *open(handle_data_t &HandleData, const sycl::context &Ctx, - const sycl::device &Dev) { +__SYCL_EXPORT void *open(const handle_data_t &HandleData, + const sycl::context &Ctx, const sycl::device &Dev) { if (!Dev.has(aspect::ext_oneapi_ipc_memory)) throw sycl::exception( sycl::make_error_code(errc::feature_not_supported), @@ -66,11 +74,18 @@ __SYCL_EXPORT void *open(handle_data_t &HandleData, const sycl::context &Ctx, auto CtxImpl = sycl::detail::getSyclObjImpl(Ctx); sycl::detail::adapter_impl &Adapter = CtxImpl->getAdapter(); + // TODO: UMF and UR currently requires the handle data to be non-const, so we + // need to make a copy of the data. Once this has been changed, the copy + // can be removed. + // CMPLRLLVM-71181 + // https://github.com/oneapi-src/unified-memory-framework/issues/1536 + handle_data_t HandleDataCopy = HandleData; + void *Ptr = nullptr; ur_result_t UrRes = Adapter.call_nocheck( CtxImpl->getHandleRef(), getSyclObjImpl(Dev)->getHandleRef(), - HandleData.data(), HandleData.size(), &Ptr); + HandleDataCopy.data(), HandleDataCopy.size(), &Ptr); if (UrRes == UR_RESULT_ERROR_INVALID_VALUE) throw sycl::exception(sycl::make_error_code(errc::invalid), "HandleData data size does not correspond " From 679d92238e96652bb118ee5e8414a5139c44320d Mon Sep 17 00:00:00 2001 From: "Larsen, Steffen" Date: Sun, 19 Oct 2025 21:47:18 -0700 Subject: [PATCH 37/38] Specify close calls Signed-off-by: Larsen, Steffen --- .../sycl_ext_oneapi_inter_process_communication.asciidoc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/sycl/doc/extensions/experimental/sycl_ext_oneapi_inter_process_communication.asciidoc b/sycl/doc/extensions/experimental/sycl_ext_oneapi_inter_process_communication.asciidoc index 38638594eb64d..3267a7f62ec7d 100644 --- a/sycl/doc/extensions/experimental/sycl_ext_oneapi_inter_process_communication.asciidoc +++ b/sycl/doc/extensions/experimental/sycl_ext_oneapi_inter_process_communication.asciidoc @@ -250,8 +250,9 @@ cannot be passed to `sycl::free`. Instead, use the `close` function to free this memory pointer. [_Note:_ The `open` function can be called multiple times on the same handle -within the same process. The number of calls to the `close` function must be -equal to the number of calls to the `open` function to free the memory pointer. +within the same process. Each call to the `open` function may return a unique +pointer value even for the same handle, therefore each call to the `open` +function must have a matching call to the `close` function. _{endnote}_] [_Note:_ The pointer returned from a call to the `open` function is no longer From 666b2e0055d77ed1ac9331eb8faba27eb9c3f1b7 Mon Sep 17 00:00:00 2001 From: "Larsen, Steffen" Date: Sun, 19 Oct 2025 22:46:45 -0700 Subject: [PATCH 38/38] Fix Windows symbols Signed-off-by: Larsen, Steffen --- sycl/test/abi/sycl_symbols_windows.dump | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sycl/test/abi/sycl_symbols_windows.dump b/sycl/test/abi/sycl_symbols_windows.dump index e05f726cbc504..ffef8ea065968 100644 --- a/sycl/test/abi/sycl_symbols_windows.dump +++ b/sycl/test/abi/sycl_symbols_windows.dump @@ -4359,7 +4359,7 @@ ?modf_impl@detail@_V1@sycl@@YANNPEAN@Z ?name@SYCLCategory@detail@_V1@sycl@@UEBAPEBDXZ ?native_specialization_constant@kernel_bundle_plain@detail@_V1@sycl@@QEBA_NXZ -?open@ipc_memory@experimental@oneapi@ext@_V1@sycl@@YAPEAXAEAV?$vector@W4byte@std@@V?$allocator@W4byte@std@@@2@@std@@AEBVcontext@56@AEBVdevice@56@@Z +?open@ipc_memory@experimental@oneapi@ext@_V1@sycl@@YAPEAXAEBV?$vector@W4byte@std@@V?$allocator@W4byte@std@@@2@@std@@AEBVcontext@56@AEBVdevice@56@@Z ?parallel_for@handler@_V1@sycl@@QEAAXV?$range@$00@23@Vkernel@23@@Z ?parallel_for@handler@_V1@sycl@@QEAAXV?$range@$01@23@Vkernel@23@@Z ?parallel_for@handler@_V1@sycl@@QEAAXV?$range@$02@23@Vkernel@23@@Z @@ -4379,7 +4379,7 @@ ?print_graph@modifiable_command_graph@detail@experimental@oneapi@ext@_V1@sycl@@IEBAXVstring_view@267@_N@Z ?print_graph@modifiable_command_graph@detail@experimental@oneapi@ext@_V1@sycl@@QEBAXV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@_N@Z ?processArg@handler@_V1@sycl@@AEAAXPEAXAEBW4kernel_param_kind_t@detail@23@H_KAEA_K_N4@Z -?put@ipc_memory@experimental@oneapi@ext@_V1@sycl@@YAXAEAV?$vector@W4byte@std@@V?$allocator@W4byte@std@@@2@@std@@AEBVcontext@56@@Z +?put@ipc_memory@experimental@oneapi@ext@_V1@sycl@@YAXAEBV?$vector@W4byte@std@@V?$allocator@W4byte@std@@@2@@std@@AEBVcontext@56@@Z ?query@tls_code_loc_t@detail@_V1@sycl@@QEAAAEBUcode_location@234@XZ ?reduComputeWGSize@detail@_V1@sycl@@YA_K_K0AEA_K@Z ?reduGetMaxNumConcurrentWorkGroups@detail@_V1@sycl@@YAIAEAVhandler@23@@Z