gin: make per-peer request ring size env-tunable for high-QP AWS EFA#1206
Closed
dmvevents wants to merge 1 commit into
Closed
gin: make per-peer request ring size env-tunable for high-QP AWS EFA#1206dmvevents wants to merge 1 commit into
dmvevents wants to merge 1 commit into
Conversation
…QUESTS) The GIN plugin tracks outstanding putSignal requests per peer in a fixed-size ring whose slot count has been hard-coded to NCCL_OFI_MAX_REQUESTS (128). Applications that issue more than 128 concurrent putSignal operations to the same peer before an ACK is returned trip the 'Next sequence number is in use' assert and surface to the caller (CUDA launch, NCCL collective, etc.) as a plugin error. DeepEP V2 on AWS EFA with high QP counts (QP >= 5 on p5en.48xlarge H200) reproduces this reliably: the hybrid-mode auto-QP formula yields 129 QPs and the first dispatch crashes. Add a runtime parameter OFI_NCCL_GIN_MAX_REQUESTS (default 128, preserving existing behavior) that sizes the per-peer ring. The previously-fixed 'bool active_put_signal[NCCL_OFI_MAX_REQUESTS]' array becomes a std::vector<uint8_t> sized once during comm construction. The value is rounded down to the nearest power of two and clamped to the GIN_IMM_SEQ_MASK window minus 2 * GIN_ACK_INTERVAL of ACK headroom. Per-peer memory growth at the cap (1024) is 1 KiB, negligible for the scales where this is needed. Signed-off-by: Anton Alexander <dmvevents@users.noreply.github.com>
Author
|
Superseded by upstream commit 6e504db ("gin: Size active_put_signal to full sequence number space"), which landed on master 2026-04-24. That fix sizes the bitset to the full sequence-number space and eliminates the aliasing class entirely — strictly better than this PR's env-tunable ring approach (no knob, collision-free by construction). Closing. Post-mortem on why we missed the better design and follow-up CUCo/LogLearner knowledge-base improvements: https://gist.github.com/dmvevents/9c6ce80affd9938332d149f8c32da0df |
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.
Summary
Makes the GIN plugin's per-peer request ring size runtime-configurable via a
new env var
OFI_NCCL_GIN_MAX_REQUESTS, defaulting to the current compile-timevalue of 128.
Motivation
The GIN plugin tracks outstanding putSignal requests in a per-peer ring whose
slot count is hard-coded to
NCCL_OFI_MAX_REQUESTS = 128(seeinclude/rdma/gin/nccl_ofi_gin.h:111and the four% NCCL_OFI_MAX_REQUESTSusages in
src/rdma/gin/nccl_ofi_gin.cpp+include/rdma/gin/nccl_ofi_gin.h).Applications that issue more than 128 concurrent putSignal operations to the
same peer before an ACK returns trip
assert(false)atsrc/rdma/gin/nccl_ofi_gin.cpp:427withNCCL_OFI_WARN("Next sequence number is in use"). That error surfaces to callers as a plugin failure.Concrete reproducer (external project)
DeepEP V2 (
epv2-releasebranch) hybrid-mode dispatch on 2-nodep5en.48xlargeH200 EFA. V2's auto-QP formula
num_sms * 16 + 1yields 129 QPs for even smallnum_smsvalues, overrunning the ring on the first dispatch.With the cap bumped to 512 compile-time (this PR makes it env-tunable to 512
runtime), the DeepEP V2 hybrid-mode test at 128 tokens / 256 experts / topk=8
on 16 ranks (8 procs/rank x 2 pods) goes from crash to:
CUDA_ERROR_LAUNCH_FAILEDat first dispatch/sys/class/infiniband/rdmap*/ports/1/hw_counters/tx_bytesdelta)This PR and a companion PR at
deepseek-ai/DeepEP(makes V2 EFA-aware) areneeded together.
Change
OFI_NCCL_GIN_MAX_REQUESTS(size_t, default 128) declared ininclude/nccl_ofi_param.h.nccl_ofi_gin_peer_rank_info::active_put_signalchanges frombool[NCCL_OFI_MAX_REQUESTS]tostd::vector<uint8_t>, sized once per commat connect time.
% NCCL_OFI_MAX_REQUESTSmod-ring expressions now use a newgin_max_requests_member onnccl_ofi_rdma_gin_put_comm.clamped to
GIN_IMM_SEQ_MASK + 1 - 2 * GIN_ACK_INTERVALso that merged-ACKranges always fit inside the seq-num window. Invalid inputs fall back to
the default with a warning.
Next sequence number is in usewarn now prints the effectivegin_max_requests_and tells the user which env var to raise.NCCL_OFI_MAX_REQUESTSis unchanged — the sendrecv and rdma transports stillcap at 128, preserving backward compatibility on existing call paths.
Default preserved
Default is 128 — exactly the existing compile-time value. Users on CX7 or
small-scale jobs see zero behavior change.
Memory cost
Per-peer, per-comm: 1 byte per slot. At the default of 128, 128 bytes per peer
(same as before:
bool+ packing was 128 bytes). At the max (1024), 1 KiB perpeer. Negligible at the scales where this is needed.
Testing
2.30.4 via
./autogen.sh && ./configure --with-libfabric=/opt/amazon/efa --with-cuda=/usr/local/cuda && make -j. Build clean.libnccl-net-ofi.sostill exportsncclGinPlugin_v13(verified vianm -D).OFI_NCCL_GIN_MAX_REQUESTS=512:DeepEP V2 hybrid-mode test
test_ep.py --num-processes 8 --num-tokens 128 --num-experts 256 --num-topk 8 --num-sms 3 --num-qps 12 --num-allocated-qps 12 EP_EFA_MAX_QPS=12completes cleanly, D+C p50 615us, 6.13 GB real RDMAverified via EFA HW counter delta.
Why not increase the compile-time constant?
Because the CX7 fleet and most existing deployments stay well under 128
outstanding putSignals per peer, and larger fabrics want the knob only when
needed. A runtime param keeps small-scale jobs lean and surfaces the tuning
choice explicitly.
DCO
Signed off.