Skip to content

CI: enable GPU tests for nixlbench on DL cluster - #1981

Closed
dpressle wants to merge 2 commits into
ai-dynamo:mainfrom
dpressle:fix/nixlbench_test_dl_gpu
Closed

dpressle wants to merge 2 commits into
ai-dynamo:mainfrom
dpressle:fix/nixlbench_test_dl_gpu

Conversation

@dpressle

@dpressle dpressle commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

For some reason we switched GPU flag off for nixlbench tests on DL cluster.

This commit switch it back on to enable GPU tests for nixlbench.

What?

Describe what this PR is doing.

Why?

Justification for the PR. If there is an existing issue/bug, please reference it. For
bug fixes, the 'Why?' and 'What?' can be merged into a single item.

How?

It is optional, but for complex PRs, please provide information about the design,
architecture, approach, etc.

Summary by CodeRabbit

  • Bug Fixes
    • Updated the GPU test configuration so Nixlbench is no longer explicitly forced to run with GPU support disabled.
  • Tests
    • Improved the single-write test setup to detect missing UCX accelerated IB support and automatically skip the test when GPUDirect RDMA isn’t available.

@dpressle
dpressle requested a review from a team as a code owner July 22, 2026 13:18
@github-actions

Copy link
Copy Markdown

👋 Hi dpressle! Thank you for contributing to ai-dynamo/nixl.

Your PR reviewers will review your contribution then trigger the CI to test your changes.

🚀

@coderabbitai

coderabbitai Bot commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

The DL Nixlbench Jenkins step no longer forces HAS_GPU=false. SingleWriteTest now skips when backend setup records missing UCX accelerated IB support required for GPUDirect RDMA.

Changes

GPU test execution

Layer / File(s) Summary
Update DL Nixlbench GPU configuration
.ci/jenkins/lib/test-dl-matrix.yaml
The DL Nixlbench step removes its slurmEnv block that set HAS_GPU=false.
Skip unsupported GPUDirect RDMA setup
test/gtest/device_api/single_write_test.cu
SingleWriteTest::SetUp() skips when ignored logs indicate that UCX accelerated IB support is unavailable.

Estimated code review effort: 2 (Simple) | ~10 minutes

Possibly related PRs

Suggested reviewers: nirwolfer

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Description check ⚠️ Warning The description leaves the template prompts in place and does not actually fill the What/Why/How sections. Replace the placeholder template text with completed What and Why details, and add a brief How section if the change is non-trivial.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main change: re-enabling GPU tests for nixlbench on the DL cluster.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 Checkov (3.3.8)
.ci/jenkins/lib/test-dl-matrix.yaml

Traceback (most recent call last):
File "/usr/local/bin/checkov", line 2, in
from checkov.main import Checkov
ModuleNotFoundError: No module named 'checkov'


Comment @coderabbitai help to get the list of available commands.

@dpressle

Copy link
Copy Markdown
Contributor Author

/build

@svc-nixl

Copy link
Copy Markdown
Collaborator

🤖 CI Triage Agentnixl-ci-dl-gpu · commit 424c3cf5

TL;DR: The Run DL Nixlbench tests stage (ucx-master leg) failed because the UCCL backend's first VRAM test crashed at memory registration: ibv_reg_mr_iova2 failed ... Error 14 Bad address for the GPU buffer, causing registerMem failed (NIXL_ERR_BACKEND) and exit code 1. This is a UCCL/driver GPU-memory-registration failure on that specific GB200 node, not a NIXL glue-code bug — the identical test passed on the other node.

Full analysis

Summary: nixl-ci-dl-gpu #1603 failed in the Run DL Nixlbench tests stage (node 382, ucx-master leg); the UCCL backend READ VRAM→VRAM benchmark aborted during registerMem.

Root cause: UCCL's RDMA layer failed to register the GPU (VRAM) buffer: [ERROR ... uccl_regmr rdma/rdma_endpoint.h:423] Error 14 Bad address: ibv_reg_mr_iova2 failed for data at 0xfffc60000000 size 80000000 context_id 0, which propagates as uccl_backend.cpp:341 Failed to register memory with UCCL enginenixl_agent.cpp:538 registerMem failedNIXL_ERR_BACKEND, so nixlbench exits 1 and GNU parallel --halt now,fail=1 aborts the stage. EAGAIN/EFADDR (14) on ibv_reg_mr_iova2 of a CUDA VRAM buffer is an environment/driver issue — GPUDirect-RDMA (nvidia-peermem/dmabuf) registration on that node's only active NIC (mlx5_6) failed. Notably the same UCCL VRAM tests succeeded on node gb-nvl-053-compute01 (v1.22.x leg via ETCD), so the code path is fine; the failure is node-specific and non-deterministic. The distance-4/"filtered as unusable" NIC warnings show all-but-one NIC excluded, and only mlx5_6 was PORT_ACTIVE.

Implicated commit: unknown — no NIXL source change caused this; the UCCL plugin path is unchanged since PR #1428 (f8e2221, 2026-05-26) / #895 (4749b35). Failure is in the vendored UCCL RDMA layer (rdma/rdma_endpoint.h:423) / GPUDirect-RDMA on the node.

File: src/plugins/uccl/uccl_backend.cpp:341 (surfaces the error) / nixl_agent.cpp:538; underlying failure at UCCL rdma/rdma_endpoint.h:423 (uccl_regmr / ibv_reg_mr_iova2).

Suggested fix: This is an infrastructure/GPUDirect-RDMA failure on gb-nvl-057-compute05, not a code regression — retry the build (it will very likely pass on a healthy node, as the v1.22.x leg did). To make CI robust: (1) verify nvidia-peermem/dmabuf GPUDirect-RDMA is loaded and healthy on the gb200nvl72_ci nodes and that mlx5_6 supports VRAM MR registration; (2) since the failing node had only one PORT_ACTIVE NIC (mlx5_6) with all others filtered at "distance 4", check node fabric health; (3) optionally make the UCCL VRAM nixlbench cases non-fatal or add a retry so a transient ibv_reg_mr Bad address doesn't fail the whole matrix. Do not treat this as a defect in the PR under test.

Related: UCCL backend history — PR #1428 "Enable local xfer for UCCL backend", PR #895 "Add UCCL backend integration for NIXL". none directly matching this ibv_reg_mr_iova2 Bad address signature.

@svc-nixl

Copy link
Copy Markdown
Collaborator

🤖 CI Triage Agentnixl-ci-build-container-pr · commit 424c3cf5

TL;DR: The two x86_64 container "Build image" stages failed because apt-get could not download packages (pybind11-dev, perl-modules-5.38, vim-common) from Ubuntu mirrors — a transient network/infrastructure error (Connection failed / Network is unreachable), not a code defect. Retry the build once mirror connectivity is restored, and consider making the apt steps more resilient.

Full analysis

Summary: Both x86_64 image builds (nixl node 233, nixlbench node 149) aborted during Dockerfile apt-get install/upgrade steps with exit code 100 due to failed package downloads from archive.ubuntu.com/security.ubuntu.com.

Root cause: Transient network failure reaching Ubuntu package mirrors. Node 233: E: Failed to fetch http://archive.ubuntu.com/.../pybind11-dev_2.11.1-2_all.deb Connection failed [IP: 185.125.190.83 80]. Node 149: E: Failed to fetch .../perl-modules-5.38...deb Cannot initiate the connection to archive.ubuntu.com:80 ... Network is unreachable ... [IP: 91.189.91.83 80] and the same for vim-common. All the actual source compilation (UCX, libfabric) succeeded; the aarch64 builds on the same commit passed, confirming the PR code is not at fault.

Implicated commit: None — not a code regression. The failure is environmental (CI runner egress to Ubuntu mirrors was down/blocked, including IPv6 routes being unreachable).

File: Dockerfile apt steps — benchmark/nixlbench/.../Dockerfile (DOCA-host apt-get upgrade step) and the nixl container Dockerfile (RUN apt-get update && apt-get install -y --no-install-recommends pybind11-dev). Exact line not resolvable from log alone.

Suggested fix: Re-run the build; this is almost certainly a transient mirror-connectivity blip. To harden against recurrence: (1) add retry/backoff around apt-get update/install (e.g. apt-get -o Acquire::Retries=5 and a wrapper loop), (2) force IPv4 (Acquire::ForceIPv4=true) since many failures were unreachable IPv6 routes, and/or (3) point the runners at a reliable local/cached apt mirror or pull pybind11-dev via the already-present uv/pip path to reduce apt dependency.

Related: none

@svc-nixl

Copy link
Copy Markdown
Collaborator

🤖 CI Triage Agentnixl-ci-gpu · commit 424c3cf5

TL;DR: The Run Nixlbench tests stage was killed after ~16 min of total silence (exit 143) because a two-process UCCL/ETCD benchmark hung on shutdown — the last UCCL WRITE VRAM→DRAM run printed "Engine destroyed" but its process never exited, so GNU parallel blocked forever and the next iteration never started. This is a hang, not a slow test; the fix is to give nixlbench UCCL teardown a hard timeout (and fix the UCCL RDMA event-loop shutdown), not to raise the time limit.

Full analysis

Summary: nixlbench UCCL two-worker benchmark (ETCD runtime, WRITE VRAM→DRAM) hangs at process teardown, causing GNU parallel to block and the Jenkins stage to be SIGTERM-killed (exit 143).

Root cause: PR #1981 ("CI: enable GPU tests for nixlbench on DL cluster") turned on the previously-skipped $HAS_GPU UCCL/VRAM benchmark loops in .gitlab/test_nixlbench.sh (lines 95–103, 122–130). During shutdown of a UCCL run, both worker processes print "Destroying Engine…/Engine destroyed" and a dangling [WARN … event_loop rdma/epoll_client.h:207] Error/HUP on connection appears, but at least one process never actually exits. Because the runner uses parallel --line-buffer --halt now,fail=1 ::: "$cmd" "sleep 4 ; $cmd", parallel waits indefinitely for the stuck child; with set -e the script cannot proceed, producing ~16 minutes of dead air (last app log 16:15:59.732, killed 16:31:57.291) — a classic hang.

Implicated commit: PR #1981 (enable nixlbench GPU tests); underlying defect in the UCCL backend RDMA epoll-client shutdown path (rdma/epoll_client.h:207 event_loop / connection teardown).

File: .gitlab/test_nixlbench.sh:122-130 (the UCCL+ETCD GPU loop) and the UCCL plugin RDMA epoll event-loop shutdown referenced at rdma/epoll_client.h:207.

Suggested fix:

  1. Wrap each nixlbench invocation with a hard timeout so a stuck process cannot wedge the whole stage, e.g. run each command under timeout --signal=KILL 300 ... inside run_nixlbench_two_workers_asio/_etcd. This turns a silent hang into a fast, diagnosable failure.
  2. Investigate the UCCL backend teardown: the process reaches "Engine destroyed" but doesn't exit, and the RDMA epoll client logs an "Error/HUP on connection" without joining/closing the event-loop thread — this is the real bug to fix in the UCCL plugin's shutdown/join logic.
  3. As an interim, if UCCL GPU shutdown is known-flaky, consider gating just the UCCL GPU loops in CI: enable GPU tests for nixlbench on DL cluster #1981 behind a flag until the teardown hang is resolved.
    Do not raise the stage time limit — the process was hung, not making progress.

Related: PR #1981 (root trigger); PR #1963 "NIXLBENCH: Fix race condition with ASIO runtime on shutdown" (prior related shutdown-race fix, ASIO path); PR #1964 "CI: Increase cleanup job timeout" (avoid this anti-pattern for a hang).

dpressle added 2 commits July 23, 2026 12:31
For some reason we switched GPU flag off for nixlbench tests
on DL cluster.

This commit switch it back on to enable GPU tests for nixlbench.

Signed-off-by: Daniel Pressler <danielpr@nvidia.com>
When nvidia_peermem is not loaded, UCX sees IB devices but cannot use
them with GPU memory, causing all ucxDeviceApi/SingleWriteTest variants
to fail with "lane not found". The LogIgnoreGuard already suppresses the
warning; checking getIgnoredCount() after backend creation converts the
hard failure into a clean GTEST_SKIP on nodes lacking GPUDirect RDMA.

Signed-off-by: Daniel Pressler <danielpr@nvidia.com>
@dpressle
dpressle force-pushed the fix/nixlbench_test_dl_gpu branch from ea09411 to 0dfeeeb Compare July 23, 2026 09:31
@dpressle
dpressle requested a review from a team as a code owner July 23, 2026 09:31

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
.ci/jenkins/lib/test-dl-matrix.yaml (2)

186-200: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Add a command-level timeout before re-enabling UCCL GPU tests.

This change restores the UCCL path, but the reported GPU stage hangs during UCCL teardown until the outer Jenkins timeout terminates it. Add a timeout around the Nixlbench/UCCL commands, or temporarily gate this path, so a teardown hang cannot consume the full CI stage.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.ci/jenkins/lib/test-dl-matrix.yaml around lines 186 - 200, Add a
command-level timeout to the “Run DL Nixlbench tests” step, covering the
Nixlbench/UCCL testScript execution so teardown hangs terminate before the outer
Jenkins timeout; preserve the existing job configuration and timeout value
source where possible.

128-128: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Do not embed ucx_version in the Slurm job name.

ucx_version may contain a ref such as release/1.22; embedding it in jobName can produce invalid or unsafe Slurm identifiers. Use BUILD_NUMBER (or a sanitized value) for job/task/container identifiers, while retaining ucx_version only as the Docker build input.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.ci/jenkins/lib/test-dl-matrix.yaml at line 128, Update the jobName value in
the matrix job configuration to remove ucx_version and use BUILD_NUMBER or
another sanitized identifier for Slurm job, task, and container naming. Keep
ucx_version referenced only as the Docker build input.

Source: Learnings

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@test/gtest/device_api/single_write_test.cu`:
- Around line 202-204: Broaden the setup logic around getIgnoredCount() and
registerMem() so the test skips when GPUDirect RDMA memory registration is
unavailable, not only when backend creation reports a warning. Probe the
registration path or handle registerMem() failure by issuing GTEST_SKIP(), while
preserving normal assertions for other failures.

---

Outside diff comments:
In @.ci/jenkins/lib/test-dl-matrix.yaml:
- Around line 186-200: Add a command-level timeout to the “Run DL Nixlbench
tests” step, covering the Nixlbench/UCCL testScript execution so teardown hangs
terminate before the outer Jenkins timeout; preserve the existing job
configuration and timeout value source where possible.
- Line 128: Update the jobName value in the matrix job configuration to remove
ucx_version and use BUILD_NUMBER or another sanitized identifier for Slurm job,
task, and container naming. Keep ucx_version referenced only as the Docker build
input.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Enterprise

Run ID: e945cca5-d7aa-4cc1-9458-0ca7fcece0ff

📥 Commits

Reviewing files that changed from the base of the PR and between ea09411 and 0dfeeeb.

📒 Files selected for processing (2)
  • .ci/jenkins/lib/test-dl-matrix.yaml
  • test/gtest/device_api/single_write_test.cu

Comment on lines +202 to +204
if (lig_->getIgnoredCount() > 0) {
GTEST_SKIP() << "UCX accelerated IB support not found; GPUDirect RDMA unavailable";
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Locate and inspect the relevant test file sections.
git ls-files 'test/gtest/device_api/single_write_test.cu'
echo '---'
nl -ba test/gtest/device_api/single_write_test.cu | sed -n '1,280p'
echo '--- SEARCH ---'
rg -n "getIgnoredCount|LogIgnoreGuard|createBackend|GPUDirect|ibv_reg_mr_iova2|Bad address|accelerated-IB" test/gtest/device_api/single_write_test.cu test/gtest/device_api -S

Repository: ai-dynamo/nixl

Length of output: 239


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Map related symbols to understand whether the skip only covers backend creation.
rg -n "class LogIgnoreGuard|struct LogIgnoreGuard|getIgnoredCount|createBackend\(" -S .

Repository: ai-dynamo/nixl

Length of output: 10157


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Search for the specific failure mode in repo tests/comments/docs.
rg -n "ibv_reg_mr_iova2|Bad address|GPUDirect RDMA unavailable|accelerated IB support not found" -S .

Repository: ai-dynamo/nixl

Length of output: 297


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Inspect the test body and the warning guard implementation.
sed -n '150,230p' test/gtest/device_api/single_write_test.cu
echo '---'
sed -n '120,190p' test/gtest/common.h
echo '---'
sed -n '140,185p' test/gtest/common.cpp

Repository: ai-dynamo/nixl

Length of output: 5708


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Inspect the rest of the test to see where GPU memory registration happens relative to the skip.
sed -n '230,420p' test/gtest/device_api/single_write_test.cu
echo '---'
rg -n "register|MemBuffer|cudaMalloc|cudaHostAlloc|queryMem|makeDescList|getBuffer" test/gtest/device_api/single_write_test.cu test/gtest/device_api/utils.cu test/gtest/device_api -S

Repository: ai-dynamo/nixl

Length of output: 14417


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Inspect the UCX createBackend implementation and any log messages about accelerated IB / GDR registration.
rg -n "accelerated IB support was not found|accelerated IB support not found|IB device\\(s\\) were detected|ibv_reg_mr_iova2|Bad address|GPUDirect RDMA|gdr|registration" src test -S

Repository: ai-dynamo/nixl

Length of output: 15333


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Inspect the UCX helper around the VRAM registration / accelerated IB warning path.
sed -n '560,670p' src/plugins/ucx/ucx_utils.cpp
echo '---'
sed -n '120,210p' test/gtest/hw_warning_test.cpp

Repository: ai-dynamo/nixl

Length of output: 6193


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Inspect whether the device test has any later skip/guard around registration.
sed -n '420,560p' test/gtest/device_api/single_write_test.cu

Repository: ai-dynamo/nixl

Length of output: 5748


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Confirm if any other tests use the same warning regex as a skip signal.
rg -n "IB device\\(s\\) were detected, but accelerated IB support was not found|registerMem: registration failed|GPUDirect RDMA unavailable" test src -S

Repository: ai-dynamo/nixl

Length of output: 666


Broaden the skip to cover registerMem() failures
This only skips when the backend-creation warning is emitted. The test still reaches registerMem() and can fail later on GPUDirect RDMA registration, so affected nodes will fail instead of skipping. Add a probe for the registration path or skip on registerMem() failure.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@test/gtest/device_api/single_write_test.cu` around lines 202 - 204, Broaden
the setup logic around getIgnoredCount() and registerMem() so the test skips
when GPUDirect RDMA memory registration is unavailable, not only when backend
creation reports a warning. Probe the registration path or handle registerMem()
failure by issuing GTEST_SKIP(), while preserving normal assertions for other
failures.

@ColinNV

ColinNV commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

I'll add these changes to #1909.

ColinNV added a commit to ColinNV/nixl that referenced this pull request Jul 23, 2026
@dpressle dpressle closed this Jul 26, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants