Add multi-GPU training smoke tests with cross-socket xfail - #6946
Draft
hujc7 wants to merge 3 commits into
Draft
Conversation
The multi-GPU workflow parametrizes each test over one device per shard, which cannot express a job that owns two GPUs at once. Nothing in CI therefore exercised multi-GPU rendering, and NVBUG#6565122 -- a heap corruption in Kit's Isaac Sim RTX renderer that only fires when the two GPUs span a cross-socket boundary -- shipped uncaught. Add smoke tests that launch real two-rank training runs and choose their GPU pair by interconnect class rather than taking whatever cuda:0,cuda:1 happens to be. On a two-socket 8-GPU host the default pick is a same-switch pair, so a fixed choice would never exercise the failing path. Each class is handled on its own terms: same-switch is strict and is the regression guard, cross-socket is expected-fail for the two Kit-renderer stacks and strict for the kitless newton_mjwarp,ovrtx stack, and the unmeasured PXB/PHB/NODE classes skip rather than assert either verdict. A physics-only case runs on any two visible devices so the step is never vacuous when every camera case skips. The expected-failure marker is applied only after the documented signature is confirmed, so an OOM or an argument error on a cross-socket pair is not recorded as the known crash.
The smoke step ran docker with no volume mount, so `cd /workspace/isaaclab` landed in the image's baked-in copy rather than the PR checkout. pytest collected 0 items and the step failed with 'file or directory not found'. Mount $PWD and run as the host user, matching what multi_gpu_host_launcher.sh already does for the sharded runs. Without --user the container writes root-owned files into the runner workspace. Also surface a ::warning:: when the runner's GPU topology cannot exercise a case, so a run that skips the NVBUG#6565122 coverage does not read as a normal green run.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
The multi-GPU workflow parametrizes each test over one device per shard, which cannot express a job that owns two GPUs at once. Nothing in CI exercised multi-GPU rendering, and NVBUG#6565122 — a heap corruption in Kit's Isaac Sim RTX renderer that only fires when the two GPUs span a cross-socket boundary — shipped uncaught.
What
Smoke tests that launch real two-rank training runs and choose their GPU pair by interconnect class, parsed from
nvidia-smi topo -m. On a two-socket 8-GPU host the defaultcuda:0,cuda:1is a same-switch pair, so a fixed pick would never exercise the failing path.PIX/NVLpairSYSpairnewton_mjwarp,ovrtxThe unmeasured classes (
PXB,PHB,NODE) skip with a reason rather than assert either verdict — every measurement behind this is at the two extremes.Design notes
cudainterop+ exit 139), so an OOM or an argument error on a cross-socket pair is not recorded as the known crash.Training time:in the output, not just exit 0 — an OOM exits 0 through the launcher.killpg, since killing only the wrapper leaves rank workers holding GPU memory.gpu_pairs_by_topology()fails closed — missingnvidia-smi, non-zero exit, unparsable or truncated matrix, a row outside the header, or a MIG host all yield "skip", never "no boundary present".Testing
test_gpu_topology.py— 11 unit tests, fixtures are verbatim output from three real hosts (2-socket 4v4, 1v3 with a NIC column, single-socketPHB/NODE, NVLink). Runs anywhere, including single-GPU CI.--entrypoint bashthat would have made the CI step run zero tests while reporting green.