Skip to content

Report when finalize waits on live CUDA graphs - #2570

Open
0z5a wants to merge 1 commit into
NVIDIA:devfrom
0z5a:finalize-wait-graph-refs
Open

0z5a wants to merge 1 commit into
NVIDIA:devfrom
0z5a:finalize-wait-graph-refs

Conversation

@0z5a

@0z5a 0z5a commented Nov 7, 2026

Copy link
Copy Markdown

Description

ncclCommFinalize waits in commDestroySync() until every CUDA graph that captured an operation on the communicator is destroyed. If such a graph stays alive, finalize blocks and prints nothing. #2568 hit this through PyTorch's destroy_process_group, with graphs kept by torch.compile(mode="reduce-overhead").

With this change, each waiting rank prints one WARN after 5 s:

NCCL WARN comm 0x... rank 0: finalize cannot complete until the CUDA graphs that captured operations on this communicator are destroyed (captured operations still referenced: 1)

The wait itself does not change: finalize still returns once the graphs are destroyed.

Related Issues

Implements the logging part of #2568. It does not add periodic messages, or the optional timeout or env var.

Changes & Impact

src/init.cc, commDestroySync():

  • For the first 5 s the loop polls the callback queue without blocking and yields. Graph destructors run asynchronously, so a short wait is normal and prints nothing.
  • If captured operations are still referenced after 5 s, it prints the WARN once and returns to the existing blocking wait.
  • The count is comm->localPersistentRefs, the number of captured plans, not the number of graphs.
  • When no captured operation is referenced, the loop body never runs.
  • The finalizing thread spins for up to 5 s in that wait, where it used to sleep. This only happens while a graph still references the communicator.
  • The message is a WARN rather than an ATTN because NCCL_DEBUG=WARN does not print ATTN.
  • An application that calls ncclCommDestroy without ncclCommFinalize reaches this wait under NOWARN(..., NCCL_DESTROY), so there the message is logged as INFO under the DESTROY subsystem.
  • Based on dev. master has the same loop, but this diff does not apply there directly because the surrounding lines differ.

Validation

dev b00866b vs this change. One aarch64 host with a GH200 GPU, two processes on that GPU (NCCL_MULTI_RANK_GPU_ENABLE=1), bootstrap through NCCL_COMM_ID, NCCL_DEBUG=WARN. The probe captures an ncclAllReduce in a CUDA graph, replays it, then calls ncclCommFinalize. One run per row.

build graph at finalize finalize returned after WARN lines (both ranks)
dev alive, destroyed by another thread after 12 s 12.01 s 0
dev destroyed before finalize 0.00 s 0
dev never captured 0.00 s 0
this PR alive, destroyed by another thread after 12 s 12.01 s 2, one per rank
this PR destroyed before finalize 0.00 s 0
this PR never captured 0.00 s 0

The "never captured" row for this PR ran on a revision with the same logic and different message text. The other two rows for this PR ran on the final commit.

Not exercised: a graph destroyed during the first 5 s of the wait, the ncclCommDestroy-only path, and nonblocking communicators.

Performance Impact

None on collectives. Only the finalize path changes.

Problem: commDestroySync() blocks until every CUDA graph that captured an
operation on the communicator is destroyed. If a graph stays alive,
ncclCommFinalize never returns and prints nothing, so nothing points the
user at the graph.

Solution: poll without blocking for the first 5 s, because graph
destructors run asynchronously and a short wait is normal. If captured
operations are still referenced after that, print one WARN and return to
the blocking wait.

Signed-off-by: 0z5a <[email protected]>
Co-Authored-By: Claude Opus 5.5 <[email protected]>
@besnardjb

Copy link
Copy Markdown
Contributor

/mirror dev

@besnardjb

Copy link
Copy Markdown
Contributor

Thanks @0z5a! moving to internal review.

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.

2 participants