Perf: overlap DeepSeek V4 MoE combine wait with the scatter - #820
Merged
zhangqi-chen merged 1 commit intoJul 23, 2026
Conversation
📝 WalkthroughWalkthroughThe MoE dispatch and combine task graph now uses independent synchronization windows, folded payload-arrival notifications, revised wait thresholds, early-resolving tasks, and updated dependency anchors. ChangesMoE synchronization
Estimated code review effort: 3 (Moderate) | ~20 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
zhangqi-chen
force-pushed
the
perf/overlap-moe-combine-wait-with-the-scatter
branch
3 times, most recently
from
July 23, 2026 06:02
e81c8ff to
f436c61
Compare
Apply the dispatch-side handshake restructure (hw-native-sys#783) to combine, and drop two dependency edges the auto tensormap already provides. Combine: - Fold the `combine_arrived` notify into the scatter blocks. Each of the N_LOCAL blocks signals every peer after its own puts, so the wait now expects `N_LOCAL * moe_epoch`. This takes one task launch off the cross-rank critical path. The [1, D] puts are single-shot TPUTs, which drain themselves before the notify issues. - Make `combine_wait` wait-only and detach it from the scatter, so it spins on the peers' counters while our own scatter runs. It anchors on `exp_w2_act` by reading recv_y_flat, the same view the scatter reads: a wait with no dependency at all is dispatched the moment the scheduler reaches it and then spins holding a core group, which starves the scatters it waits on. Reading the 3-D recv_y instead fails to compile once the expert count changes -- it is an exp_w2_act cube output whose inferred layout is nz, while the outlined scalar-read kernel declares nd. - Restore the plain `pl.spmd` reduce. `pl.spmd_submit` + the `@pl.jit` `shared_routed` method existed only to pass `pl.no_dep(routed_y_buf)`, and that opt-out is now wrong: with `combine_wait` off the scatter, the local RAW edge on routed_y_buf is the only thing ordering the reduce after this rank's own `dst == my_rank` puts. Drops the constant-false specialization branch and the `self.` noqa with it. Dispatch: - Drop the explicit `_push_tid` edge on `dispatch_gather`. dep-gen shows `dispatch_push -> dispatch_gather` already carries tensormap edges on recv_x / recv_aux / recv_route, so the explicit edge was redundant. Measured on a2a3, EP=2, ptoas 0.48, same two cards, `--enable-l2-swimlane=1`, on the rank that does not stall in the barrier: combine end -> shared_routed start goes from 7.4us to -7.8us (the reduce pre-stages onto a core and starts before the scatter's last block retires), and the tail from exp_w2_act end to hc_post end from 37.4us to 32.5us per MoE layer. Also trims the verbose rationale comments through dispatch and combine.
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
Applies the dispatch-side handshake restructure (#783) to combine, and drops two dependency edges the auto tensormap already provides.
Combine
combine_arrivednotify into the scatter blocks: each of theN_LOCALblocks signals every peer after its own puts, and the wait now expectsN_LOCAL * moe_epoch. Takes one task launch off the cross-rank critical path. The[1, D]puts are single-shot TPUTs, which drain themselves before the notify issues.combine_waitwait-only and detach it from the scatter so it spins on the peers' counters while this rank's scatter runs. It anchors onexp_w2_actby readingrecv_y_flat, the same view the scatter reads — a wait with no dependency at all is dispatched as soon as the scheduler reaches it and then spins holding a core group, starving the scatters it waits on. Reading the 3-Drecv_yinstead fails to compile once the expert count changes: it is anexp_w2_actcube output whose inferred layout isnz, while the outlined scalar-read kernel declaresnd.pl.spmdreduce.pl.spmd_submit+ the@pl.jitshared_routedmethod existed only to passpl.no_dep(routed_y_buf), and that opt-out is now wrong: withcombine_waitoff the scatter, the local RAW edge onrouted_y_bufis the only thing ordering the reduce after this rank's owndst == my_rankputs. The constant-false specialization branch and theself.noqa go with it.Dispatch
_push_tidedge ondispatch_gather:dispatch_push -> dispatch_gatheralready carries tensormap edges onrecv_x/recv_aux/recv_route.Measured on a2a3, EP=2, ptoas 0.48, same two cards,
--enable-l2-swimlane=1, on the rank that does not stall in the barrier: combine end ->shared_routedstart goes from 7.4us to -7.8us (the reduce pre-stages onto a core and starts before the scatter's last block retires), and the tail fromexp_w2_actend tohc_postend from 37.4us to 32.5us per MoE layer.Also trims the verbose rationale comments through dispatch and combine.