TL/UCP: enable host-side SRA allreduce pipelining - #1354
wfaderhold21 wants to merge 6 commits into
Conversation
Overlap the reduce-scatter and allgather phases across fragments on the host path so fragment i's allgather (pure network) runs concurrently with fragment i+1's reduce-scatter (network + CPU reduction). Previously the host branch of the SRA-knomial pipeline heuristic disabled pipelining (n_frags=1), leaving the NIC idle during every reduce step and the CPU idle during the entire allgather. The host else-branch of get_pipeline_params() now sets conservative defaults: threshold 256KB, 512KB fragments, nfrags floor 2, pdepth 2, parallel order. Env override UCC_TL_UCP_ALLREDUCE_SRA_KN_PIPELINE still takes precedence. Correctness is unchanged: the CUDA in-place path already runs the identical fragmented schedule, and per-frag scratch is sized from max_frag_count (smaller frags -> smaller scratch). Fragment size was tuned on thor (8 nodes, host, float32 sum, forced sra_knomial, mlx5_0:1) against stock HPC-X 2.25.1 UCC: new vs hpcx (avg bus BW ratio) size 2 ranks 4 ranks 6 ranks 256 ranks 512KB 1.34x 1.37x 1.25x 1.06x 1MB 1.45x 1.30x 1.22x 1.45x 2MB 1.45x 1.29x 1.17x 1.53x 4MB 1.43x 1.25x 1.31x >1.4x 512KB frags beat the initial 256KB choice by 6-17% at >=1MB across 2-256 ranks and remove a 1-2MB regression the finer default showed at 256 ranks; below 256KB the path is byte-identical (no regression). pdepth=4 gave no benefit and hurt at 4MB, so pdepth stays 2.
|
🤖 CI Triage Agent — TL;DR: The gtest Full analysisSummary: ASAN gtest run failed 1 test — Root cause: Implicated commit: d56c68d — "TL/UCP: enable host-side SRA allreduce pipelining" (Ferrol Aderholdt) on branch File: Suggested fix: Change Related: PR #1354; prior schedule-pipeline fixes c8314d3 (#1262), 4f67436 (#1051). |
|
🤖 CI Triage Agent — TL;DR: Two new Full analysisSummary: The gtest job (shard 0) failed: 2 of 7759 tests failed — Root cause: These tests use a fault-injection harness that registers process-global hooks and counters — Implicated commit: File: test/gtest/core/test_schedule.cc:1013-1027 ( Suggested fix: Make the fault harness self-contained per test. Add a ucc_event_manager_set_subscribe_fault_cb(NULL);
ucc_schedule_pipelined_set_lock_observer(NULL);
g_fault_subscribe_fail_at = -1;
g_fault_subscribe_attempt = 0;so no fault callback survives into other tests and each test starts from a clean, deterministic global state. Alternatively, gate Related: PR #1354 ( |
|
🤖 CI Triage Agent — TL;DR: The codestyle lint failed only on the commit-title policy check: HEAD commit Full analysisSummary: The "Check commit title" step of the Root cause:
The other three commits in the PR passed ( Implicated commit: File: Suggested fix: Amend the offending commit subject to 50 characters or fewer and force-push the branch: Since the three Related: PR #1354 (openucx/ucc) — no existing issue found for this failure signature.
|
The earlier review commit reverted UCC_SCHEDULE_PIPELINED_MAX_FRAGS from 16 to 4 while keeping the tests that require depths 6, 8, and 16. With the capacity at 4, ucc_schedule_pipelined_init() silently clamped those requests to 4 fragments and returned success, so pipelined_init_depth_16_success, pipelined_depth_16_exact_lifecycle (16 inits / 32 subscriptions), the depth-8 failure-injection tests, and the depth-6 subscription-unwind test all failed. Restore the intended limit of 16. The clamp at MAX now only triggers for requests above 16, which is the behavior the clamp test and the depth-16 lifecycle test both expect.
aa14f86 to
333271f
Compare
Strip explanatory comments that duplicate commit history, code context, or test assertions, per review feedback: - src/schedule/ucc_schedule_pipelined.h: Drop the UCC_SCHEDULE_PIPELINED_MAX_FRAGS rationale block (history of the 4 -> 16 change and the clamp-vs-reject policy). The value, the clamp behavior in ucc_schedule_pipelined_init(), and the cost of the inline frags[] array are all visible in the code itself; the tuning history belongs to the commit log, not the source. - src/schedule/ucc_schedule_pipelined.c: Remove the err: unwind comment in ucc_schedule_pipelined_init(). The sequence (destruct the pipeline task first, then each built fragment and its tasks) is self-documenting, and the ordering rationale is covered by the pipelined_real_subscription_failure_* / pipelined_fragment_failure_exact_unwind tests in test_schedule.cc. - src/schedule/ucc_schedule.c, src/schedule/ucc_schedule.h: Remove the prose around the fault-injection seam (ucc_event_manager_subscribe_fault_cb / ucc_event_manager_set_subscribe_fault_cb). The setter's contract (NULL restores production behavior) is obvious from the if (cb != NULL) guard. - src/components/tl/ucp/allreduce/allreduce_sra_knomial.c: Remove the inline tuning rationale in ucc_tl_ucp_allreduce_sra_knomial_select_pipeline_params() (threshold/frag_size/n_frags/pdepth comments). Those measurements are recorded in the enabling commit message; the remaining comments in the function (tagged-collective tag collision, fail-closed topology guard, CUDA in-place fast-alloc size) explain non-obvious correctness decisions and stay. - src/components/tl/ucp/allreduce/allreduce_sra_knomial.c, src/components/tl/ucp/reduce/reduce_srg_knomial.c: Split combined two-pointer declarations into one declaration per line (style). No functional changes.
|
| static ucc_status_t (*ucc_event_manager_subscribe_fault_cb)(void); | ||
|
|
||
| void ucc_event_manager_set_subscribe_fault_cb(ucc_status_t (*cb)(void)) | ||
| { | ||
| ucc_event_manager_subscribe_fault_cb = cb; |
There was a problem hiding this comment.
These fault-injection callbacks are process-wide globals that scheduler threads read without synchronization. The tests install both callbacks but never restore them, so later unrelated schedules in the same process can still invoke test instrumentation or race with callback updates. Please keep these hooks test-scoped or synchronize them and reliably restore them after each test.
Knowledge Base Used: Runtime utilities and infrastructure
The subscribe fault cb and pipelined lock observer are process-wide globals read by schedule code on every subscribe/lock operation, but were plain pointer writes with no synchronization, and the tests installed them without restoring, leaving test instrumentation armed for later schedules in the same process. - make both hook pointers _Atomic with relaxed load/store, snapshotting to a local before invocation - restore both hooks to NULL in the test_schedule fixture TearDown - document the setters as test-only install/restore-with-NULL
Overlap the reduce-scatter and allgather phases across fragments on the host path so fragment i's allgather (pure network) runs concurrently with fragment i+1's reduce-scatter (network + CPU reduction). Previously the host branch of the SRA-knomial pipeline heuristic disabled pipelining (n_frags=1), leaving the NIC idle during every reduce step and the CPU idle during the entire allgather.
The host else-branch of get_pipeline_params() now sets conservative defaults: threshold 256KB, 512KB fragments, nfrags floor 2, pdepth 2, parallel order. Env override UCC_TL_UCP_ALLREDUCE_SRA_KN_PIPELINE still takes precedence. Correctness is unchanged: the CUDA in-place path already runs the identical fragmented schedule, and per-frag scratch is sized from max_frag_count (smaller frags -> smaller scratch).