Place indirect contractions once per assignment - #5438
Open
pbrubeck wants to merge 3 commits into
Open
Conversation
Tabulating an indirect contraction leaves the result behind a ComponentTensor view of a temporary that code generation has already emitted. Read that temporary through the view's own indices instead of materialising the view as a second array. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01M6QZ26z2p9o7sYzxZXV1B3
`tabulate_indirect_contractions` was called at the tail of `optimise_monomial_sum`, which sum factorisation calls recursively, so it re-walked the same subtrees once per level of recursion. Apply it once to each finished assignment instead, which keeps plan costing aware of the tabulation without the repeated traversal. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01M6QZ26z2p9o7sYzxZXV1B3
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01M6QZ26z2p9o7sYzxZXV1B3
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.
TLDR
This is the TSFC half of firedrakeproject/fiat#286. It places the indirect
contraction pass once per finished assignment, and lowers the view it
leaves behind without copying it.
Stacked on #5362, which carries the TSFC halves of fiat#284 and fiat#281.
Needs firedrakeproject/fiat#286.
What this does
Place the pass once per assignment (
tsfc/spectral.py,tsfc/coffee_mode.py).tabulate_indirect_contractionsrewrites a contraction that reads a tablethrough a map into one tabulation over the table's rows, followed by a gather.
It used to run at the tail of
gem.coffee.optimise_monomial_sum, whichsum_factorisecalls recursively, so it re-walked the same subtrees once perlevel of recursion: 754 calls over 75,497 nodes for a Johnson--Mercier matrix
in 3D.
It now runs once on each finished assignment, in
_factoriseand inoptimise_expressions. Placing it there also keeps it inside plan costing, sothe two plans #5362 compares are costed with the tabulation applied.
Lower the view without a copy (
tsfc/loopy.py).The rewrite leaves its result behind a
ComponentTensorview of a temporarythat code generation has already emitted. Indexing that view used to
materialise a second array and copy into it.
_expression_indexednow readsthe existing temporary through the view's own indices.
Effect
Flops are unchanged; this is placement, not a new rewrite. TSFC compile time
falls 1.4-2.4x on the zany elements, and the copy the view lowering removes is
one array per tabulated contraction.
The rewrite itself is what recovers the Johnson--Mercier and Argyris actions
that #5362 alone regresses -- see the tables there. Without this PR the pass is
present in GEM but never reaches a whole assignment.
Benchmarks
Measured 2026-09-08 against today's
main, with the whole stack installed(fiat#282 -> #284 -> #281 -> #286 paired with the two firedrake PRs). Minimum of
25 timed assemblies, three interleaved repetitions. NCE degree 3 on a prism is
the control: the stack cannot touch it, and it is flat, so the harness is
honest.
Action
Bilinear form
The assembled action vectors agree with
mainto 12 digits on Johnson--Mercierand Guzman--Neilan in 2D and 3D, so the Guzman--Neilan win is real work and not
dropped work.
Generated code
The stack replaces unrolled scalar arithmetic with tables and loops, so it moves
storage out of working temporaries and into read-only tables. Working
temporaries are the ones that matter, and they fall.
AI assistance
Claude Code was used for the split, the benchmarking and this description. The
human contributor remains responsible for understanding, validating and
maintaining the changes.
🤖 Generated with Claude Code
https://claude.ai/code/session_01A1NNAv95LANgpBX61ozPE2