Fix LL dispatch RC QP assert for all-P2P topologies - #695
Conversation
Require num_rc_per_pe only when at least one non-self peer is not P2P-reachable. NVSHMEM 3.6 can leave RC QPs at zero when IBGDA is unavailable; single-host / all-local jobs already fall back to P2P and should not fail the unconditional assert. Co-authored-by: Cursor <cursoragent@cursor.com>
| bool needs_ibgda = false; | ||
| for (int dst_rank = 0; dst_rank < num_ranks; ++dst_rank) { | ||
| if (dst_rank != rank and | ||
| nvshmemi_get_p2p_ptr( | ||
| reinterpret_cast<uint64_t>(rdma_recv_count), rank, dst_rank) == 0) { | ||
| needs_ibgda = true; | ||
| break; | ||
| } | ||
| } | ||
| EP_DEVICE_ASSERT(not needs_ibgda or | ||
| ibgda_get_state()->num_rc_per_pe >= num_local_experts); |
There was a problem hiding this comment.
🟡 warning: The gate is dispatch-only. The sibling barrier/clean_low_latency_buffer and combine kernels in the same file also depend on RC QPs for non-P2P peers (e.g. via ibgda_quiet/nvshmemi_ibgda_put_nbi_warp/nvshmemi_ibgda_amo_nonfetch_add) without analogous per-peer P2P gating. With num_rc_per_pe == 0, a non-P2P/mixed run passing this assert (because the dispatcher only requires full RC capacity, same as before) can still crash in those kernels. Confirm this MR is intentionally shipping alongside the referenced PRs #134/#488 and won't be merged alone relying on num_rc_per_pe == 0.
🤖 v4
| if (dst_rank != rank and | ||
| nvshmemi_get_p2p_ptr( | ||
| reinterpret_cast<uint64_t>(rdma_recv_count), rank, dst_rank) == 0) { | ||
| needs_ibgda = true; | ||
| break; | ||
| } |
There was a problem hiding this comment.
🟡 warning: The per-peer probe/self-exclusion relies on subtle invariants that are only implicit: self (dst_rank == rank) is excluded because nvshmemi_get_p2p_ptr maps self to the local pointer (always nonzero), and a single representative heap address rdma_recv_count is used to probe reachability. A zero peer_heap_base_p2p means no P2P (RC mandatory), a nonzero one means NVLink P2P. If any local symmetric buffer used by the real send/count/recv paths is ever not in the same heap (or the self-mapping changes), the gate would be wrong. Consider documenting those invariants or deriving the flag from the actual buffers/state.
🤖 v4
| } | ||
| } | ||
| EP_DEVICE_ASSERT(not needs_ibgda or | ||
| ibgda_get_state()->num_rc_per_pe >= num_local_experts); |
There was a problem hiding this comment.
🔵 suggestion: The P2P scan loop is executed on the single-thread path (warp_id == num_warps - 1, sm_id == 0) but not restricted to a single lane, so every lane of that warp redundantly walks the full num_ranks loop and calls nvshmemi_get_p2p_ptr per peer. This is functionally correct (the assert is uniform across the warp) but does O(num_ranks) redundant work per lane. Consider guarding the scan with lane_id == 0 and broadcasting needs_ibgda, or documenting that the redundancy is intentional and negligible.
🤖 v3
| // IBGDA transport is unavailable; all-local jobs still work because | ||
| // every send/count path below already falls back to the P2P pointer. | ||
| bool needs_ibgda = false; | ||
| for (int dst_rank = 0; dst_rank < num_ranks; ++dst_rank) { |
There was a problem hiding this comment.
🔵 suggestion: The reachability scan probes only rdma_recv_count. If any other buffer used on the IBGDA path (e.g. rdma_recv_x / rdma_x send targets) could have different P2P reachability than rdma_recv_count, this single-buffer probe might not capture all IBGDA needs. In practice these buffers share the same NVSHMEM symmetric heap and peer topology, so a single representative probe is sufficient — consider adding a brief comment making that assumption explicit for future readers.
🤖 v3
🤖 ds-review-bot Code Reviewv6The conditional QP assertion accurately matches the existing P2P fallback paths without introducing an observable regression. v4The LL dispatch asserts v3The change correctly gates the RC QP requirement in the legacy low-latency Files reviewed: 1 |
Summary
Low-latency dispatch currently asserts
num_rc_per_pe >= num_local_expertsunconditionally on SM 0. With NVSHMEM 3.6, optional IBGDA may leavenum_rc_per_pe == 0even when every remote rank is directly reachable through P2P. That poisons single-host / all-local jobs (e.g. B200) even though every send/count path already falls back to the P2P pointer whennvshmemi_get_p2p_ptr(...) != 0.Gate the RC QP requirement on per-peer P2P reachability: require RC QPs only if at least one non-self peer has no P2P pointer.
Related reports: #134, #488 (same
num_rc_per_pefamily; this PR specifically covers the LL dispatch all-P2P case).Change
In
csrc/kernels/legacy/internode_ll.cudispatch:nvshmemi_get_p2p_ptr(rdma_recv_count, rank, dst_rank)num_rc_per_pe >= num_local_expertsonly whenneeds_ibgdais trueTest plan
num_rc_per_pe == 0) succeeds when all peers are P2P-reachableMade with Cursor