nemo_rl.data_plane.nixl.nixl_io#
NIXL endpoint for the data plane: registration, metadata, blocking transfers.
The agent is created by :func:nemo_rl.utils.checkpoint_engines.nixl._create_nixl_agent,
the same path the checkpoint-engine refit uses.
One NixlEndpoint per process. The agent is not thread-safe; callers
serialise access (the KV client holds a lock, the unit is a Ray actor).
Memory type: DRAM host buffers over UCX.
Module Contents#
Classes#
Every NIXL request in this process that failed short of DONE. |
|
Functions#
Raise :class: |
|
Data#
API#
- nemo_rl.data_plane.nixl.nixl_io.log#
‘getLogger(…)’
- nemo_rl.data_plane.nixl.nixl_io._RDMA_TLS_PREFIXES#
(‘rc’, ‘dc’, ‘ud’, ‘ib’)
- nemo_rl.data_plane.nixl.nixl_io.check_rdma_only(env: Mapping[str, str] | None = None) str#
Raise :class:
TransportPolicyErrorunless UCX can only use RDMA.Allowed: an explicit
UCX_TLSlist with at least one RDMA transport (rc,rc_x,rc_mlx5,dc,ud,ib…) and notcporall, plus same-host helpers (self,sm,shm,cma…); or an exclusion list (^...) that namestcp.UCX_NET_DEVICES, if set, must name RDMA devices (<dev>:<port>), never a netdev such aseth0. UnsetUCX_TLSis rejected: UCX would then fall back to TCP whenever RDMA is unavailable. Returns a one-line description.
- class nemo_rl.data_plane.nixl.nixl_io.Graveyard(max_bytes: int = 4 << 30)#
Every NIXL request in this process that failed short of DONE.
One per process (:data:
GRAVEYARD), so dropping an endpoint or adapter can’t free an entry through garbage collection. An entry holds the request’s handle (never released), its descriptor lists, the agent that owns it, and its local ranges; callers keep the memory behind those ranges alive (the pool retires it, the adapter keeps zero-copy sources).Past
max_bytesof retained memory (local ranges, plus every buffer the pool retires whole) the process is POISONED: every later transfer raises- Class:
DataPlaneFatalbefore touching NIXL.
Initialization
- retain(
- agent: Any,
- h: Any,
- ldesc: Any,
- rdesc: Any,
- local,
- retain_buffer(nbytes: int) None#
Charge a pool buffer retired whole because a failed transfer touches it.
Its transferred ranges were charged by :meth:
retain, so they count twice: the limit errs on the side of poisoning.
- _charge(nbytes: int) None#
- check() None#
- nemo_rl.data_plane.nixl.nixl_io.GRAVEYARD#
‘Graveyard(…)’
- nemo_rl.data_plane.nixl.nixl_io.nixl_available() bool#
- nemo_rl.data_plane.nixl.nixl_io.addr_of(arr: numpy.ndarray) int#
- class nemo_rl.data_plane.nixl.nixl_io.NixlEndpoint(
- name: str,
- *,
- backend: str = NIXL_DEFAULT_BACKEND_NAME,
- init_params: dict[str, Any] | None = None,
- prog_thread: bool = False,
Initialization
- touches_unfinished(addr: int, nbytes: int) bool#
True if
[addr, addr+nbytes)overlaps a transfer that may still run.
- register(arr: numpy.ndarray) int#
Register a contiguous uint8 host array; returns its base address.
- deregister(addr: int) None#
- metadata() bytes#
- add_remote(md: bytes) str#
- has_remote(name: str) bool#
- remove_remote(name: str) None#
- transfer(
- op: str,
- local: Sequence[tuple[int, int]],
- remote: Sequence[tuple[int, int]],
- remote_agent: str,
- *,
- timeout_s: float = 120.0,
Blocking one-sided
WRITE(local→remote) orREAD(remote→local).localandremoteare parallel lists of(addr, nbytes).
- transfer_many(
- ops: Sequence[tuple[str, Sequence[tuple[int, int]], Sequence[tuple[int, int]], str]],
- *,
- timeout_s: float = 120.0,
Post every
(op, local, remote, remote_agent), then wait for all of them.The transfers run at the same time, so N units cost about the slowest one, not the sum. One
timeout_sbounds the wait for the whole batch. Returns one entry per op:Noneonce it is DONE, else its- Class:
TransferError. Ops are independent: a failure of one does not stop the others. Invalid arguments raiseValueErrorbefore anything is posted.
Every posted transfer ends DONE (handle released) or retained (see
- Meth:
_retain), on every exit, including an exception.
- _post(
- i,
- op,
- local,
- remote,
- remote_agent,
- live,
Post one transfer;
live[i]is set while it is still running.
- _fail(
- i,
- op_args,
- live,
- why,
- cause=None,
Retain transfer
i(it may still run) and return its error.
- _retain(
- xfer: tuple[Any, Any, Any],
- local,
Keep a transfer that may still run, for good.
The handle is never released: POSIX hands the request object to its I/O callbacks and deleting it under a pending I/O is a use-after-free.
- _done(xfer: tuple[Any, Any, Any]) None#
- close() None#