Skip to main content

nvmeof

nvmeof is a userspace NVMe over Fabrics RDMA initiator for Python. It is a separate package layered on ibverbs because NVMe controller and namespace policy do not belong in low-level verbs bindings.

The data path uses NVMe/RDMA keyed SGL descriptors that point at an existing ibverbs MR. The target transfers blocks directly to or from that MR, including CUDA memory registered by ibverbs.cuda; there is no host staging buffer in the NVMe-to-RDMA-to-GPU path.

Why this does not bundle SPDK

SPDK is a strong choice for a managed native storage service, but it includes an environment abstraction, hugepage/driver setup, native plugins, and a large dependency graph. Embedding it would not produce a self-contained, portable pip/manylinux wheel. This package instead implements the small NVMe/RDMA host protocol directly over the existing portable ibverbs ABI3 extension.

nvmeof itself is a pure-Python py3-none-any wheel. Its ibverbs dependency is an ABI3 manylinux wheel that dlopens the host's libibverbs.so.1 and, only when NVMe/RDMA is used, librdmacm.so.1.

Requirements

  • Linux, an RDMA NIC, and a reachable NVMe/RDMA target.
  • libibverbs.so.1, librdmacm.so.1, and the matching RDMA provider.
  • For GPU I/O: CUDA, an HCA with GPUDirect RDMA, and dma-buf support or the nvidia_peermem module.
  • The target must support keyed SGL data block descriptors. Separate namespace metadata and DH-HMAC-CHAP are not currently supported.

On Debian/Ubuntu the runtime packages are typically:

sudo apt-get install libibverbs1 librdmacm1 ibverbs-providers
python -m pip install nvmeof

Host memory

import nvmeof

with nvmeof.Controller.connect(
    "192.0.2.20",
    "nqn.2026-07.io.example:storage",
    source="192.0.2.21",
) as controller:
    namespace = controller.namespace(1)
    with controller.allocate(128 * 4096) as buffer:
        namespace.read(buffer, slba=0, blocks=128)
        payload = buffer.read()

controller.register(array_or_cpu_tensor) registers an existing contiguous host allocation instead.

Direct GPU memory

import os
os.environ["PYTORCH_CUDA_ALLOC_CONF"] = "expandable_segments:True"

import torch
import nvmeof

tensor = torch.empty(128 * 4096, dtype=torch.uint8, device="cuda:0")

with nvmeof.Controller.connect(
    "192.0.2.20", "nqn.2026-07.io.example:storage"
) as controller:
    namespace = controller.namespace(1)
    with controller.register_gpu(tensor) as gpu_mr:
        # Target NVMe -> target RDMA WRITE -> local GPU memory.
        # Namespace.read flushes completed GPUDirect writes before returning.
        with torch.cuda.device(tensor.device):
            namespace.read(gpu_mr, slba=0, blocks=128)

        # Local GPU memory -> target RDMA READ -> target NVMe.
        # Namespace.write synchronizes the current CUDA context first.
        with torch.cuda.device(tensor.device):
            namespace.write(gpu_mr, slba=1024, blocks=128)
            namespace.flush()

The CUDA context that owns the tensor must be current while issuing GPU I/O. The registered MR must be closed before its controller.

source is optional. Set it to an address on the intended initiator HCA when the host has multiple RDMA NICs. This makes an NVMe -> target NIC -> initiator NIC -> GPU route explicit and prevents route selection from silently choosing an HCA with poor GPU PCIe locality.

Reads and writes larger than the target's MDTS are split into multiple NVMe commands while retaining direct placement in the same registered buffer. The target used for the repository benchmarks advertises a 1 MiB MDTS; 4, 16, and 64 MiB GPU tensors were verified end to end.

Scope

The first implementation provides dynamic controller connection, controller enablement, Identify Controller/Namespace, one I/O queue, synchronous and low-level asynchronous command submission, block read/write splitting, and flush. It deliberately does not claim filesystem semantics, multipath, reconnect, keep-alive, protection information, authentication, or target functionality. KATO is therefore negotiated as zero.

Real-target tests are opt-in through NVME4PY_TARGET and NVME4PY_SUBSYSTEM_NQN. Set NVME4PY_SOURCE to bind the initiator to a specific HCA address. The GPU round-trip test also requires NVME4PY_DESTRUCTIVE=1 and must only be used with a disposable namespace.

Measured multi-QP bandwidth, latency, QP scaling, and PCIe locality results are in BENCHMARKS.md.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

nvmeof-2026.7.21.tar.gz (18.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

nvmeof-2026.7.21-py3-none-any.whl (14.2 kB view details)

Uploaded Python 3

File details

Details for the file nvmeof-2026.7.21.tar.gz.

File metadata

  • Download URL: nvmeof-2026.7.21.tar.gz
  • Upload date:
  • Size: 18.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.14

File hashes

Hashes for nvmeof-2026.7.21.tar.gz
Algorithm Hash digest
SHA256 476e705296e903dfd751c9993baade6f94b13caf0bd78be54aceda6c88e5cd28
MD5 104fac5b92572904e88721d4b9264d97
BLAKE2b-256 91d0044e4144aa1b9a5969d1c50c1e2a102a85adc125314c8c14b0495054e8ab

See more details on using hashes here.

Provenance

The following attestation bundles were made for nvmeof-2026.7.21.tar.gz:

Publisher: publish_nvmeof.yml on d4l3k/rdma4py

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file nvmeof-2026.7.21-py3-none-any.whl.

File metadata

  • Download URL: nvmeof-2026.7.21-py3-none-any.whl
  • Upload date:
  • Size: 14.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.14

File hashes

Hashes for nvmeof-2026.7.21-py3-none-any.whl
Algorithm Hash digest
SHA256 3fbc94fd71cef51c29c99e1984dfe01ff3e47e5885353af40c7ad48965515624
MD5 5bac4bb7d9b3df90ff0c69fb47ec8486
BLAKE2b-256 52f8279a5735239ac0af323180264cc645d587b04d3cfcf07b26e1d476a24076

See more details on using hashes here.

Provenance

The following attestation bundles were made for nvmeof-2026.7.21-py3-none-any.whl:

Publisher: publish_nvmeof.yml on d4l3k/rdma4py

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page