fix(closed_loop): bind ONNX providers to the rank's CUDA device - #399
Merged
Merged
Conversation
HansRobo
force-pushed
the
fix/onnx-rank-device
branch
2 times, most recently
from
September 7, 2026 09:50
daaa8eb to
2f86396
Compare
The CLI selects cuda:{local_rank}, but ONNX Runtime reads no device from
torch and defaults to GPU 0, so every rank of a distributed ONNX evaluation
piles onto the first visible GPU. Pass the requested index to the CUDA and
TensorRT provider options; an unindexed "cuda" follows torch's current
device. CPU-only sessions and the TensorRT cache options are unchanged.
The provider tests grew a third fake session to cover this, so fold all
three onto one fake and one helper, and assert whole option dicts per
provider rather than a single key, which also catches stray options.
HansRobo
force-pushed
the
fix/onnx-rank-device
branch
from
September 8, 2026 01:32
2f86396 to
22913ab
Compare
Merged
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.
Problem
ONNX Runtime takes no device from torch. The CLI selects
cuda:{local_rank}, but every rank's ORT session opens on GPU 0.Live CUDA contexts per pid, 4 ranks on 4 H100s, same node and same onnx, two arms differing only by the 7 lines below:
Without the fix
With the fix
Every non-zero rank held a second context on GPU 0 — its ORT session — while its own GPU carried only the torch context. GPU 0 served all four ranks while GPUs 1-3 sat in a collective-wait kernel: 0% memory bandwidth, ~120 W against a 700 W TDP.
Effect on closed-loop lap
run_all_groups_closed_loop.pyover 11 routes x 2 object modes, 4 ranks on one node, ONNX planner. Both arms ran back to back in one allocation on the same tree; onlyscenario_generation/simulate.pydiffered.Per-route speedup tracks route length, from 0.92x on a 20-second route to 2.84x on the longest (6604 steps). Short routes are dominated by setup and I/O; long ones by inference, which is what serialised onto GPU 0. It is 1.7x rather than 4x because GPU 0 was not saturated — inference is roughly half the critical path, the rest is CPU-side simulation.
Results are unchanged: the per-mode
groups.jsonof both arms are byte-identical. The cross-mode aggregate differs in the last 1-2 ULP (mean_route_completion...171 vs ...173), which is summation order, not behaviour.Fix
Pass the requested index to the CUDA and TensorRT provider options; an unindexed
cudafollowstorch.cuda.current_device(). Seven lines. CPU-only sessions and the TensorRT cache options are unchanged.Notes
cuda:0(index 0 is a real GPU, not "unset"), unindexedcuda, andcuda:1with TensorRT (nonzero index, cache options preserved). The deletions are the three fake ORT sessions already intest_onnx_provider.pyfolded onto one helper.device="cuda"(no index) on a host without CUDA,torch.cuda.current_device()now raises before the session opens, replacing_require_accelerator's actionable message with a raw torch error. Left as-is: the eval CLI always passescuda:{local_rank}, which never reaches that path.Reference: https://onnxruntime.ai/docs/execution-providers/CUDA-ExecutionProvider.html#device_id