Skip to content

EnzymeHLOOpt: ScatterIndicesAreUnique reads a constant without copying - #3439

Merged
wsmoses merged 1 commit into
mainfrom
pb/scatter-unique-flat
Oct 8, 2026
Merged

wsmoses merged 1 commit into
mainfrom
pb/scatter-unique-flat

Conversation

@wsmoses

@wsmoses wsmoses commented Oct 8, 2026

Copy link
Copy Markdown
Member

ScatterIndicesAreUnique's constant-indices path built every index tuple through a recursive lambda copying a SmallVector per element, then a std::set of vectors — and since a scatter whose indices are not distinct makes the pattern fail, the whole enumeration ran again on every visit of that scatter by the greedy driver. It also read shape[indexVectorDim] for scalar indices (index_vector_dim == rank), one past the end.

On MFEM's ex1 (star mesh, order 3, PA) one exec-time module (PADiffusionSetup's, six scatters with a splat index constant of 20480x32x32x1) spent 56 s in it — the bulk of the 44 s run was this one optimization (perf: 50% of all samples in the pattern's SmallVector churn); the module now takes 0.1 s through the runtime pattern list.

Now: a splat is distinct iff there is one scatter point; otherwise the values are read once into a flat array, the tuples laid out point by point (the index-vector dimension handled whether real or implicit), and distinctness is a sort plus an adjacent compare.

Test scatter_indices_unique_constant.mlir: distinct, repeated, two-component tuples along the leading dimension, scalar indices (full-line goldens). On a 200k-element random permutation the verdicts match the old code.

🤖 Generated with Claude Code

https://claude.ai/code/session_016zErYp7upmqr4NHfhod9UD

The check that a scatter's constant indices are all distinct built every
index tuple through a recursive copy of a SmallVector per element and a
set of vectors, and ran again on every visit of a scatter whose indices
are not distinct: on a splat index of 21M elements it took 56 s per
module, most of ex1's run. A splat is distinct only as one point; others
are read once into flat tuples and sorted.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016zErYp7upmqr4NHfhod9UD
@codecov

codecov Bot commented Oct 8, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 29.96%. Comparing base (2d3ff23) to head (50e9dfb).
⚠️ Report is 5 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #3439      +/-   ##
==========================================
+ Coverage   29.63%   29.96%   +0.33%     
==========================================
  Files         240      240              
  Lines       48496    48546      +50     
==========================================
+ Hits        14371    14548     +177     
+ Misses      34125    33998     -127     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@wsmoses

wsmoses commented Oct 8, 2026

Copy link
Copy Markdown
Member Author

MFEM GPU unit suite (74 tests) with the runtime built from Enzyme-JAX main + #3437 #3439 #3440 #3441 #3442 and Reactant.jl #3423 + #3425, over objects from main + the open affine-cfg PRs (#3436 #3438 among them): 74/74 (sweep final55, 2026-10-08 17:38).

ex1 (Poisson, order 3, PA, PCG to 1e-12), timed solves in one process (JIT excluded), native CUDA for reference:

  • star (185k dofs, 400 iterations): 0.64 s (native 0.047 s) — the morning's state ran ~70 iterations per 600 s
  • fichera (802k dofs, 270 iterations): 1.08 s (native 0.14 s)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant