Skip to content

AffineCFG: parallelize an accumulation taken under a condition - #3409

Merged
wsmoses merged 1 commit into
mainfrom
pb/affine-conditional-accumulation
Oct 7, 2026
Merged

wsmoses merged 1 commit into
mainfrom
pb/affine-conditional-accumulation

Conversation

@wsmoses

@wsmoses wsmoses commented Oct 7, 2026 •

Copy link
Copy Markdown
Member

affine-cfg: parallelize an accumulation taken only under a condition.

A value a loop accumulates only where a condition holds, acc = c ? acc ⊕ x : acc, through an scf.if, affine.if or select, matched no reduction: the loop yields the if or select, not the combination. Such a loop accumulates c ? x : id on every iteration, where id is the combination's identity, and that is a reduction. The identities used are exact:

combination identity
addf -0.0 (adding it leaves any sum, including -0.0, unchanged)
mulf 1.0
addi, ori, xori 0
muli 1
andi all ones
fmuladd -0.0, with the branch yielding the product (as in #3407)

This is done in the parallelization itself, as #3407 does for multiply-adds, so a loop that stays serial is left exactly as it is:

  • Detection (isLoopParallel). addConditionalReductions takes such a carried value as a reduction of its kind, without changing the IR. It applies when the value is read only by the combination and by the unchanged arm or operand.
  • Rewrite (AffineParallelizePattern). Where it parallelizes the loop, the if or select is rewritten to give x on the combining side and the identity on the other. That becomes each iteration's reduced value, and the initial value is combined with the reduction outside the loop (arith::getReductionOp). The if keeps its branches, so nothing in them runs where it did not before.

Measured with affine-cfg on the IR of the 143 raised MFEM translation units just before the last affine-cfg, against current main (with #3407): parallel dimensions go from 66,139 to 66,153 (batchitrans +6, bilininteg_mixedcurl_pa +4, bilininteg_curlcurl_pa +4), and no file loses any. Of the 160 carries of this shape, many sit in loops that stay serial for other reasons. Others feed one carried value from another's arm, such as batchitrans's product-rule recurrences.

Test: affinecfg_conditional_accumulation.mlir (full-line goldens). It fails on main.

  • @scf_if: the scf.if yields the load or -0.0, and the loop is an addf reduction.
  • @affine_if: the same under an affine.if on the iteration.
  • @select: an i32 count, select(c, acc + 1, acc), becomes an addi reduction of select(c, 1, 0).
  • @fmuladd: a multiply-add under a condition. The if yields the product.
  • @last: a value replaced under a condition (the last one taken) is no accumulation and stays carried.
  • @serial: an accumulation under a condition in a loop that is not parallel for other reasons is left exactly as it is.

Lit: every RUN line of every test against current main's binary. Nothing fails that passed there.

🤖 Generated with Claude Code

https://claude.ai/code/session_016zErYp7upmqr4NHfhod9UD

A value a loop accumulates only where a condition holds,
acc = c ? acc + x : acc through an scf.if, affine.if or select, matched no
reduction: the loop yields the if or select, not the combination. Such a
loop accumulates c ? x : id wherever, with id the combination's identity
(-0.0 for addf, so that a -0.0 sum stays one; 1.0 for mulf; 0 for
addi/ori/xori; 1 for muli; all ones for andi; a multiply-add adds its
product), which is a reduction. isLoopParallel now takes such a value as a
reduction of its kind, and AffineParallelizePattern, where it parallelizes
the loop, rewrites the if or select to give x or the identity and combines
the initial value with the reduction. The if keeps its branches, so nothing
in them runs where it did not; a loop that stays serial is left as it is.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016zErYp7upmqr4NHfhod9UD
@wsmoses wsmoses changed the title AffineCFG: accumulate unconditionally what a condition adds AffineCFG: parallelize an accumulation taken under a condition Oct 7, 2026
@wsmoses
wsmoses force-pushed the pb/affine-conditional-accumulation branch from 4b5b041 to 63a4b4b Compare October 7, 2026 00:13
@wsmoses
wsmoses merged commit 44f289b into main Oct 7, 2026
12 of 20 checks passed
@wsmoses
wsmoses deleted the pb/affine-conditional-accumulation branch October 7, 2026 00:43
@codecov

codecov Bot commented Oct 7, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 29.62%. Comparing base (9409410) to head (63a4b4b).
⚠️ Report is 30 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #3409   +/-   ##
=======================================
  Coverage   29.61%   29.62%           
=======================================
  Files         240      240           
  Lines       48460    48474   +14     
=======================================
+ Hits        14351    14359    +8     
- Misses      34109    34115    +6     

☔ 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.

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