Repository navigation
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #3444 +/- ##
==========================================
- Coverage 29.73% 29.73% -0.01%
==========================================
Files 241 241
Lines 48677 48655 -22
==========================================
- Hits 14476 14468 -8
+ Misses 34201 34187 -14 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
wsmoses
force-pushed
the
pb/gather-scatter-forward
branch
2 times, most recently
from
October 9, 2026 04:49
970825c to
5b4968c
Compare
wsmoses
force-pushed
the
pb/gather-scatter-forward
branch
from
October 9, 2026 14:01
5b4968c to
3a72514
Compare
wsmoses
force-pushed
the
pb/gather-scatter-forward
branch
2 times, most recently
from
October 9, 2026 22:11
a950e52 to
f0eb022
Compare
wsmoses
force-pushed
the
pb/gather-scatter-forward
branch
from
October 12, 2026 03:03
f0eb022 to
f69c225
Compare
…constant indices A kernel's per-lane scratch (mfem's shared-memory sm[3][125] in the 3D PA diffusion apply) is stored through by index tensors the raising knows and loaded back the same way, and once the lanes are batched both become a scatter and a gather on a tensor the lane owns: 18 scatters and 63 gathers per element, each a pass over the scratch, where native code keeps the values in registers and shared memory. Where every index is constant and the scatters overwrite one element per index, what each read reads is known: the update of the last scatter in the chain writing it, or the chain's input. GatherScatterConstantForward makes a gather at constant indices of such a chain the gathers of those updates directly (the unwritten positions read from the input by the same gather), selected together where there are several sources; ScatterChainConstantToGather does the same for the top of a chain read any other way (whole, through a pad). A scatter writing a position twice ends a chain: which update wins is not defined. On that kernel's body (after constant folding of the index arithmetic, which the exec list does not do: stablehlo-aggressive-folder does) the scatters go from 18 to 5, the five left being the stores to the output. Registered as gather_scatter_constant_forward in the scatter group and the runtime list. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016zErYp7upmqr4NHfhod9UD
wsmoses
force-pushed
the
pb/gather-scatter-forward
branch
from
October 12, 2026 19:39
f69c225 to
c8e00a6
Compare
Member
Author
|
Closing: measured strictly worse with the exec runtime's main list only (no separate folding rounds). BK6PARTIAL/2 takes 403 ms with these patterns against 64.6 ms without them, BK6PARTIAL/4 159 vs 30.3 ms, and ceed BP3/2/96 115 vs 84.0 ms. The general primitive suggested in review, a gather that reads nothing a scatter writes reading the scatter's input, is #3490. |
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.
A kernel's per-lane scratch (mfem's shared-memory
sm[3][125]in the 3D PA diffusion apply,PADiffusionApply3D) is stored through by index tensors the raising knows and loaded back the same way; once the lanes are batched, both become astablehlo.scatterand astablehlo.gatheron a tensor the lane owns — 18 scatters and 63 gathers per element in that kernel's exec-time module, each a pass over the scratch, where native code keeps the values in registers and shared memory. On fichera (p=3, 802k dofs) the XLA iteration runs 144 kernels against native's 13, and that kernel is most of it (fourinput_scatter_fusions ~130 µs each, a 198 µs transpose).Where every index is constant and the scatters overwrite one element per index (the
setindexcombiner), what each read reads is known: the update of the last scatter in the chain writing it, or the chain's input.GatherScatterConstantForward: a gather at constant indices (one element per index tuple) of such a chain becomes gathers of those updates directly, the unwritten positions read from the chain's input by the same gather, selected together by constant masks where there are several sources.ScatterChainConstantToGather: the top of a chain read any other way (whole, through a pad) becomes the same over the whole operand, the input where unwritten. A lone scatter into a value that is not a constant is left alone: it updates in place, where the select would read its whole input (e.g. 4 writes into a 100-element argument).On that kernel's body (
EXEC_DUMPof the fichera run, replayed with the runtime's list), the scatters go from 18 to 5, the five left being the stores to the output E-vector — once the index arithmetic is folded: the lanes' index tensors areor/add/pad/compare/selectover constants, which the exec list never folds (add_simplifyand friends only strip zeros), so the pattern sees nothing withoutstablehlo-aggressive-folderrun first. The runtime side (adding that folder to the exec pipeline) is a Reactant.jl change, measured next.MFEM GPU suite with it (and #3445, the folding rounds): 74/74 (sweep final63, 2026-10-09).
Test
gather_scatter_constant_forward.mlir: a permutation read, a read of unwritten positions, a two-scatter chain with an overwrite, a chain read whole, a scatter writing twice (unchanged). Registered asgather_scatter_constant_forwardin the scatter group and the runtime list.Rebased onto main with #3442/#3440/#3445. Main's tests that this changes are regolded:
divscatter,autobatching/elementwise_loop_multiindex(a lone scatter into a constant zero becomesselect(mask, gather, 0)), andraising/raise_lane_private_scratch(@lane_memref's scratch is forwarded;@lane_atomic's zero-initialized first store folds away).gather_scatter_constant_forward.mlir:@wholenow writes into a constant; the new@whole_in_placechecks that a scatter into an argument stays a scatter.Rebased on main 73603ba (2026-10-12).
bilininteg_vecdiffusion_pa.cpp, this PR'sScatterChainConstantToGatherproduced IR on which two main patterns,DUSDUSSubsumingandSliceOfDynamicUpdate, traded slices forever. One function'senzyme-hlo-optnever finished (> 10 min). EnzymeHLOOpt: DUSDUSSubsuming moves slices only when it replaces the DUS #3470, now merged, fixes that cycle; with it, the same input takes 15 s.//test:neuralgcm_testruns out of memory on our 32 GB GPUs, as it does on main.🤖 Generated with Claude Code
https://claude.ai/code/session_016zErYp7upmqr4NHfhod9UD