Skip to content

fix: report no RDMA devices when rdma-core is not installed - #108

Open
PerryLink wants to merge 1 commit into
MoonshotAI:mainfrom
PerryLink:fix/rdma-core-missing
Open

PerryLink wants to merge 1 commit into
MoonshotAI:mainfrom
PerryLink:fix/rdma-core-missing

Conversation

@PerryLink

Copy link
Copy Markdown

The defect

_ibv_get_device_list() calls ctypes.CDLL("libibverbs.so.1") unguarded (checkpoint_engine/device_utils.py:51). On any host without rdma-core installed — a slim container, a CI image, any machine with no RDMA NIC — the loader error escapes from this helper and reaches the caller instead of the error the code already raises for this case:

DeviceManager.rdma_device()            device_utils.py:267
  -> _get_my_rdma_device(..., _get_rdma_devices())   :271
       -> _ibv_get_device_list()       :82 -> :51
            -> ctypes.CDLL("libibverbs.so.1")

Measured on a Linux host without rdma-core:

$ python3 -c "import ctypes; ctypes.CDLL('libibverbs.so.1')"
OSError: libibverbs.so.1: cannot open shared object file: No such file or directory

So the user sees the dynamic loader's message, while _get_my_rdma_device() already has the actionable one ready at :89-90:

if not devices:
    raise RuntimeError("no rdma devices found")

That line is unreachable on such a host, because the exception is raised two frames earlier. A missing library is not an unexpected condition here — it means exactly what devices == [] means: there are no RDMA devices to enumerate.

The change

Two hunks in checkpoint_engine/device_utils.py, plus three tests:

  1. _ibv_get_device_list() treats a missing libibverbs as an empty device list, so _get_my_rdma_device() reports no rdma devices found.
  2. _get_rdma_devices() enumerates the HCA list once. When NCCL_IB_HCA parses to nothing, the or fallback called _ibv_get_device_list() a second time — a second CDLL and a second full enumeration for the same answer.

No behaviour change on a host where the library is present: _ibv_get_device_list() returns the same list as before.

Verification

Both new tests are written to fail against the unpatched source, so they detect the change rather than passing vacuously. Reverting only device_utils.py and keeping the tests:

                     with the patch        with the source reverted
new tests            3 passed              3 failed

and the third failure is the second hunk directly:

AssertionError: Expected '_ibv_get_device_list' to have been called once. Called 2 times.
Calls: [call(), call()].

The repository's own CPU gate is unchanged:

$ python -m pytest tests/ -m "not gpu" -q
2 failed, 108 passed, 1 skipped, 12 deselected

The two failures are pre-existing and unrelated to this change — they are Windows-only host artefacts I hit while working here (tests/test_store_barrier.py:34 relies on a libuv-enabled PyTorch, which the Windows wheel is not; tests/test_xpu_parity.py:84 asserts : as the path separator where Windows joins with ;). Both are inert on ubuntu-latest, and the passed count moved from 105 to 108 with these three tests added.

ruff check and ruff format --check are clean across checkpoint_engine/ and tests/ with the repository's own configuration.

What I could not verify

I have no RDMA hardware, no CUDA device, and no multi-node setup, so I did not exercise P2PStore or the P2P update path end to end — only the device-enumeration helper and its two callers, which is where the change is. The _ibv_get_device_list() path with the library present is covered by the existing test_detect_ibv_list, which skips without /sys/class/infiniband.

`_ibv_get_device_list()` called `ctypes.CDLL("libibverbs.so.1")` unguarded, so on
a host without rdma-core the loader error escaped from the helper and reached the
caller of `DeviceManager.rdma_device()` as

    OSError: libibverbs.so.1: cannot open shared object file

instead of the `RuntimeError("no rdma devices found")` that `_get_my_rdma_device()`
already raises for exactly this case.

Treat a missing library as "no devices to enumerate" so that message is the one
the user sees. Also enumerate the HCA list once: when `NCCL_IB_HCA` parses to
nothing the `or` fallback called `_ibv_get_device_list()` a second time.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant