fix: avoid indefinite hang in gin gdaki init - #2318
Conversation
ncclGinIbAllGather could spin forever if the RDMA fabric between neighbouring ranks is not connected. For example, if ring-neighbor NICs sit on disjoint rails, the receiver's CTS write never lands on senders, and the loop has no timeout, no abort flag, and no error CQE to break it. Jobs hung silently in ncclDevCommCreate until killed externally. We add a per-ring-step deadline, NCCL_GIN_IB_ALLGATHER_TIMEOUT_SEC (default 180s, <=0 disables), checked in both the post and completion loops. On expiry, WARN with ring-neighbor info and return ncclRemoteError through existing cleanup paths so callers fail fast. This also bounds all GIN IB collectives layered on the ring allgather (including allToAll, rkey exchanges, and P2P barrier). Signed-off-by: dromniscience <dromniscience@gmail.com>
b941a9d to
4ebd8a6
Compare
|
Hi @dromniscience Thanks for the PR. I want to make sure we fully understand the problem before implementing a solution. I'm a bit stuck in a few places:
|
|
Thanks for the timely reply! The linked issue mentions the exact hanging issue I experienced. The issue surfaces in a disconnected rail network topology. Without Regarding your questions:
|
|
I agree with your analysis and I agree that we should fix the silent hang. I'm not super convinced about the timeout, for a few reasons:
I think we can fix this with the error-then-abort pattern. What do you think? This would require 2 changes (1) we need to poll for CQEs even if the sender does not yet have a request and (2) we need to abort if abort is called This is much larger scope than adding a timeout. If you want to give it a shot, it's appreciated, but otherwise we can add it to our queue. |
|
Understood. I agree that the error-then-abort pattern is a better fix, and it's a broader change that may affect other parts of the code. I may use this temporary solution myself, and am grateful to be notified when the problem is fixed in a future release. |
Description
Fix indefinite hang in GIN GDAKI init when ring-neighbor NICs are unreachable
Problem:
ncclGinIbAllGatherspins forever if the RDMA fabric between neighboringranks is disconnected (e.g., NICs on disjoint rails). The receiver's CTS write never
lands, and the loop has no timeout, error CQE, or abort flag, so jobs hang silently in
ncclDevCommCreateuntil killed externally.Solution: This PR adds a per-ring-step deadline checked in both the post and completion
loops, gated by
NCCL_GIN_IB_ALLGATHER_TIMEOUT_SEC(default 180s, <=0 disables).On expiry, it issues a WARN with ring-neighbor rank info and returns
ncclRemoteErrorthrough existing cleanup paths. This works for all IB collectives duringdevComm setup since they call this allgather underneath (allToAll, rkey exchanges, P2P barrier).
Related Issues
None
Changes & Impact
No change of any public or internal NCCL APIs
Changes:
NCCL_PARAM(GinIbAllGatherTimeoutSec, "GIN_IB_ALLGATHER_TIMEOUT_SEC", 180)ncclGinIbAllGatherCheckDeadline()helperncclGinIbAllGather()NCCL_GIN_IB_ALLGATHER_TIMEOUT_SEC=0to disable this checkPerformance Impact
clockNano()is called once per ncclNetIb.isend/irecv inncclGinIbAllGather()- negligible