Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions cuda_core/cuda/core/_cpp/rt/VMM_DESIGN.md
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,7 @@ descriptor either; it records only that it was imported (`is_mapped`). A
descriptor parked in a `Queue` or sent to a `Pool` pins the memory in the
sender until the receiver unpickles it. Besides `multiprocessing`, a process
with its own file descriptor passing sends the descriptor's `fds`, `sizes`,
and `size` and rebuilds it with `VirtualMemoryIPCBufferDescriptor.from_fds()`,
and `size` and rebuilds it with `VirtualMemoryFdBufferDescriptor.from_fds()`,
which duplicates the integers it is given and always builds a `posix_fd`
descriptor.

Expand Down Expand Up @@ -304,7 +304,7 @@ importer needs access to the exporter's IMEX channel rather than a matching
device index, and the memory may live on another node. The file-descriptor
rules above (ownership, pinning, `pickle` raising, the same-device check) do
not hold for it, so fabric sharing gets a descriptor class of its own instead
of a widened `VirtualMemoryIPCBufferDescriptor`, whose `handles` stay
of a widened `VirtualMemoryFdBufferDescriptor`, whose `handles` stay
`IPCAllocationHandle`s. `from_fds()` is POSIX-only by construction for the
same reason and takes no handle type; a fabric descriptor is plain data and
needs no out-of-band constructor. Tracked on the VMM epic (#2980).
Expand Down
2 changes: 1 addition & 1 deletion cuda_core/cuda/core/_memory/_ipc.pxd
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ cdef class IPCAllocationHandle:

# Descriptor of a VirtualMemoryResource buffer: one exported handle per
# physical allocation that backs the buffer, in address order.
cdef class VirtualMemoryIPCBufferDescriptor(IPCBufferDescriptor):
cdef class VirtualMemoryFdBufferDescriptor(IPCBufferDescriptor):
cdef readonly int _handle_type
cdef readonly tuple _chunk_sizes
cdef readonly tuple _handles
Expand Down
6 changes: 3 additions & 3 deletions cuda_core/cuda/core/_memory/_ipc.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ class IPCAllocationHandle:
@property
def uuid(self) -> uuid.UUID: ...

class VirtualMemoryIPCBufferDescriptor(IPCBufferDescriptor):
class VirtualMemoryFdBufferDescriptor(IPCBufferDescriptor):
"""Serializable object describing a :class:`VirtualMemoryBuffer` that can be shared between processes.

The descriptor holds one exported POSIX file descriptor per physical
Expand Down Expand Up @@ -97,9 +97,9 @@ class VirtualMemoryIPCBufferDescriptor(IPCBufferDescriptor):
_handles: tuple[Any, ...]

@staticmethod
def _from_exports(handle_type: int, chunk_sizes: tuple[int, ...], handles: tuple[Any, ...], size: int) -> VirtualMemoryIPCBufferDescriptor: ...
def _from_exports(handle_type: int, chunk_sizes: tuple[int, ...], handles: tuple[Any, ...], size: int) -> VirtualMemoryFdBufferDescriptor: ...
@classmethod
def from_fds(cls, fds: Iterable[int | IPCAllocationHandle], sizes: Iterable[int], *, size: int | None=None) -> VirtualMemoryIPCBufferDescriptor:
def from_fds(cls, fds: Iterable[int | IPCAllocationHandle], sizes: Iterable[int], *, size: int | None=None) -> VirtualMemoryFdBufferDescriptor:
"""Build a descriptor from POSIX file descriptors received outside ``multiprocessing``.

The exporter sends ``fds``, ``sizes``, and ``size`` of its descriptor
Expand Down
16 changes: 8 additions & 8 deletions cuda_core/cuda/core/_memory/_ipc.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ def _reconstruct_allocation_handle(cls: type, df: object, uuid: uuid.UUID | None
multiprocessing.reduction.register(IPCAllocationHandle, _reduce_allocation_handle)


cdef class VirtualMemoryIPCBufferDescriptor(IPCBufferDescriptor):
cdef class VirtualMemoryFdBufferDescriptor(IPCBufferDescriptor):
"""Serializable object describing a :class:`VirtualMemoryBuffer` that can be shared between processes.

The descriptor holds one exported POSIX file descriptor per physical
Expand Down Expand Up @@ -215,9 +215,9 @@ cdef class VirtualMemoryIPCBufferDescriptor(IPCBufferDescriptor):
@staticmethod
def _from_exports(
handle_type: int, chunk_sizes: tuple[int, ...], handles: tuple, size: int
) -> VirtualMemoryIPCBufferDescriptor:
cdef VirtualMemoryIPCBufferDescriptor self = VirtualMemoryIPCBufferDescriptor.__new__(
VirtualMemoryIPCBufferDescriptor)
) -> VirtualMemoryFdBufferDescriptor:
cdef VirtualMemoryFdBufferDescriptor self = VirtualMemoryFdBufferDescriptor.__new__(
VirtualMemoryFdBufferDescriptor)
self._payload = b""
self._size = size
self._handle_type = handle_type
Expand All @@ -232,7 +232,7 @@ cdef class VirtualMemoryIPCBufferDescriptor(IPCBufferDescriptor):
sizes: Iterable[int],
*,
size: int | None = None,
) -> VirtualMemoryIPCBufferDescriptor:
) -> VirtualMemoryFdBufferDescriptor:
"""Build a descriptor from POSIX file descriptors received outside ``multiprocessing``.

The exporter sends ``fds``, ``sizes``, and ``size`` of its descriptor
Expand Down Expand Up @@ -292,7 +292,7 @@ cdef class VirtualMemoryIPCBufferDescriptor(IPCBufferDescriptor):
raise
# The handle owns the duplicate now; if append fails, the handle closes it once.
handles.append(handle)
return VirtualMemoryIPCBufferDescriptor._from_exports(driver_type, sizes_t, tuple(handles), size)
return VirtualMemoryFdBufferDescriptor._from_exports(driver_type, sizes_t, tuple(handles), size)

@property
def handle_type(self) -> VirtualMemoryHandleType:
Expand Down Expand Up @@ -330,7 +330,7 @@ cdef class VirtualMemoryIPCBufferDescriptor(IPCBufferDescriptor):

def __reduce__(self) -> tuple[object, ...]:
# multiprocessing duplicates the IPCAllocationHandle fds into the receiver; plain pickle raises.
return VirtualMemoryIPCBufferDescriptor._from_exports, (
return VirtualMemoryFdBufferDescriptor._from_exports, (
self._handle_type, self._chunk_sizes, self._handles, self._size)


Expand Down Expand Up @@ -359,7 +359,7 @@ cdef Buffer Buffer_from_ipc_descriptor(
cls, object mr, IPCBufferDescriptor ipc_descriptor, stream
):
"""Import a buffer that was exported from another process."""
if isinstance(ipc_descriptor, VirtualMemoryIPCBufferDescriptor):
if isinstance(ipc_descriptor, VirtualMemoryFdBufferDescriptor):
# Imported here rather than cimported: _virtual_memory_resource
# cimports this module.
from cuda.core._memory._virtual_memory_resource import VirtualMemoryResource
Expand Down
8 changes: 4 additions & 4 deletions cuda_core/cuda/core/_memory/_virtual_memory_resource.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ from typing import Iterable

from cuda.core._device import Device
from cuda.core._memory._buffer import Buffer, MemoryResource
from cuda.core._memory._ipc import VirtualMemoryIPCBufferDescriptor
from cuda.core._memory._ipc import VirtualMemoryFdBufferDescriptor
from cuda.core._stream import Stream
from cuda.core._utils.cuda_utils import driver
from cuda.core.graph import GraphBuilder
Expand Down Expand Up @@ -98,7 +98,7 @@ class VirtualMemoryBuffer(Buffer):
freed when the last buffer that maps it closes.
"""
@property
def ipc_descriptor(self) -> VirtualMemoryIPCBufferDescriptor:
def ipc_descriptor(self) -> VirtualMemoryFdBufferDescriptor:
"""A new descriptor for sharing this buffer with other processes.

Every access exports the physical allocations that back the buffer
Expand Down Expand Up @@ -205,7 +205,7 @@ class VirtualMemoryResource(MemoryResource):
is not visible. Plain ``pickle`` cannot carry the file descriptors; a
process with its own file descriptor passing sends the descriptor's
``fds``, ``sizes``, and ``size`` and rebuilds it with
``VirtualMemoryIPCBufferDescriptor.from_fds()``. The importing resource
``VirtualMemoryFdBufferDescriptor.from_fds()``. The importing resource
maps the memory for its device and the devices in its ``peers`` option,
with its own access options. A descriptor pins the physical memory while
it exists, in every process that holds one, and nothing else does. A
Expand Down Expand Up @@ -346,7 +346,7 @@ class VirtualMemoryResource(MemoryResource):
(``location_type`` ``"host"``, ``"host_numa"``, or
``"host_numa_current"``) is not shared yet.
"""
def _import_ipc_buffer(self, desc: VirtualMemoryIPCBufferDescriptor, stream) -> VirtualMemoryBuffer:
def _import_ipc_buffer(self, desc: VirtualMemoryFdBufferDescriptor, stream) -> VirtualMemoryBuffer:
"""Import a buffer that another process exported; see :meth:`Buffer.from_ipc_descriptor`.

Every exported allocation is imported with this resource's handle
Expand Down
12 changes: 6 additions & 6 deletions cuda_core/cuda/core/_memory/_virtual_memory_resource.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ from cuda.core._memory._buffer cimport (
from cuda.core._memory._ipc cimport (
IPCAllocationHandle,
IPCDataForBuffer,
VirtualMemoryIPCBufferDescriptor,
VirtualMemoryFdBufferDescriptor,
)
from cuda.core._rt cimport (
ContextHandle,
Expand Down Expand Up @@ -296,7 +296,7 @@ cdef class VirtualMemoryBuffer(Buffer):
"""

@property
def ipc_descriptor(self) -> VirtualMemoryIPCBufferDescriptor:
def ipc_descriptor(self) -> VirtualMemoryFdBufferDescriptor:
"""A new descriptor for sharing this buffer with other processes.

Every access exports the physical allocations that back the buffer
Expand Down Expand Up @@ -439,7 +439,7 @@ cdef class VirtualMemoryResource(MemoryResource):
is not visible. Plain ``pickle`` cannot carry the file descriptors; a
process with its own file descriptor passing sends the descriptor's
``fds``, ``sizes``, and ``size`` and rebuilds it with
``VirtualMemoryIPCBufferDescriptor.from_fds()``. The importing resource
``VirtualMemoryFdBufferDescriptor.from_fds()``. The importing resource
maps the memory for its device and the devices in its ``peers`` option,
with its own access options. A descriptor pins the physical memory while
it exists, in every process that holds one, and nothing else does. A
Expand Down Expand Up @@ -916,7 +916,7 @@ cdef class VirtualMemoryResource(MemoryResource):
and self.config.location_type not in _HOST_LOCATION_TYPES
)

def _import_ipc_buffer(self, VirtualMemoryIPCBufferDescriptor desc not None, stream) -> VirtualMemoryBuffer:
def _import_ipc_buffer(self, VirtualMemoryFdBufferDescriptor desc not None, stream) -> VirtualMemoryBuffer:
"""Import a buffer that another process exported; see :meth:`Buffer.from_ipc_descriptor`.

Every exported allocation is imported with this resource's handle
Expand Down Expand Up @@ -1092,7 +1092,7 @@ def _reconstruct_virtual_memory_resource(
return cls(device, replace(config, peers=peers))


cdef VirtualMemoryIPCBufferDescriptor _export_ipc_descriptor(Buffer buf):
cdef VirtualMemoryFdBufferDescriptor _export_ipc_descriptor(Buffer buf):
"""Export the allocations that back ``buf`` as shareable handles, in address order.

Only the allocations that cover ``buf.size`` are exported; a buffer's size
Expand Down Expand Up @@ -1154,4 +1154,4 @@ cdef VirtualMemoryIPCBufferDescriptor _export_ipc_descriptor(Buffer buf):
# The handle owns the fd now; if append fails, the handle closes it once.
handles.append(handle)
sizes.append(chunk)
return VirtualMemoryIPCBufferDescriptor._from_exports(handle_type, tuple(sizes), tuple(handles), buf._size)
return VirtualMemoryFdBufferDescriptor._from_exports(handle_type, tuple(sizes), tuple(handles), buf._size)
2 changes: 1 addition & 1 deletion cuda_core/docs/source/api_private.rst
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ CUDA runtime
_device.DeviceProperties
_memory._ipc.IPCAllocationHandle
_memory._ipc.IPCBufferDescriptor
_memory._ipc.VirtualMemoryIPCBufferDescriptor
_memory._ipc.VirtualMemoryFdBufferDescriptor
_memory._managed_buffer.AccessedBySetProxy


Expand Down
2 changes: 1 addition & 1 deletion cuda_core/docs/source/release/1.3.0-notes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ New features
physical allocation and pins the memory while it exists; nothing else does.
A buffer that contains imported memory cannot be exported again. For a
transport of your own, the descriptor exposes ``fds``, ``sizes``, and
``size``, and ``VirtualMemoryIPCBufferDescriptor.from_fds()`` rebuilds it
``size``, and ``VirtualMemoryFdBufferDescriptor.from_fds()`` rebuilds it
in the receiver. Fabric handles are not shared yet.
(`#2980 <https://github.com/NVIDIA/cuda-python/issues/2980>`__)

Expand Down
10 changes: 5 additions & 5 deletions cuda_core/tests/memory_ipc/test_vmm_ipc.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
from cuda.bindings import driver
from cuda.core import Buffer, Device, MemoryResource, VirtualMemoryResource, VirtualMemoryResourceOptions
from cuda.core._dlpack import DLDeviceType
from cuda.core._memory._ipc import IPCAllocationHandle, IPCBufferDescriptor, VirtualMemoryIPCBufferDescriptor
from cuda.core._memory._ipc import IPCAllocationHandle, IPCBufferDescriptor, VirtualMemoryFdBufferDescriptor
from cuda.core._memory._virtual_memory_resource import VirtualMemoryBuffer
from cuda.core._utils.cuda_utils import CUDAError, handle_return
from cuda.core.utils import StridedMemoryView
Expand Down Expand Up @@ -113,7 +113,7 @@ def _forge(desc, **fields):
fields.setdefault("chunk_sizes", desc._chunk_sizes)
fields.setdefault("handles", desc._handles)
fields.setdefault("size", desc.size)
return VirtualMemoryIPCBufferDescriptor._from_exports(
return VirtualMemoryFdBufferDescriptor._from_exports(
fields["handle_type"], fields["chunk_sizes"], fields["handles"], fields["size"]
)

Expand Down Expand Up @@ -812,7 +812,7 @@ def test_round_trip_with_os_dup(self, vmm_ipc_device):
del desc
gc.collect()
assert _open_fds() == fds0 + 2
rebuilt = VirtualMemoryIPCBufferDescriptor.from_fds(wire["fds"], wire["sizes"], size=wire["size"])
rebuilt = VirtualMemoryFdBufferDescriptor.from_fds(wire["fds"], wire["sizes"], size=wire["size"])
assert _open_fds() == fds0 + 4, "from_fds duplicates the integers it is given"
for fd in wire["fds"]:
os.close(fd) # the caller keeps ownership of its own
Expand All @@ -838,7 +838,7 @@ def test_from_fds_shares_handle_objects_and_rejects_bad_input(self, vmm_ipc_devi
buf = mr.allocate(1)
gran = buf.size
desc = buf.ipc_descriptor
from_fds = VirtualMemoryIPCBufferDescriptor.from_fds
from_fds = VirtualMemoryFdBufferDescriptor.from_fds

shared = from_fds(desc.handles, desc.sizes)
assert shared.handles[0] is desc.handles[0] # an IPCAllocationHandle is shared, not duplicated
Expand Down Expand Up @@ -898,7 +898,7 @@ def child_main(device_id, sock, queue):
with sock:
msg, fds, _flags, _addr = socket.recv_fds(sock, 4096, 16)
header = json.loads(msg)
desc = VirtualMemoryIPCBufferDescriptor.from_fds(fds, header["sizes"], size=header["size"])
desc = VirtualMemoryFdBufferDescriptor.from_fds(fds, header["sizes"], size=header["size"])
for fd in fds:
os.close(fd) # from_fds duplicated them; the received ones are ours to close
imported = Buffer.from_ipc_descriptor(_resource(device), desc, stream=device.default_stream)
Expand Down
Loading