perf: compute the COFE solver's up/down pair by a single recursion#499
Merged
Merged
Conversation
Collaborator
|
Thanks! I'll take a look at all three ~early next week :) |
Kaptch
self-requested a review
July 5, 2026 11:31
Contributor
Author
Fix.Impl.up and Fix.Impl.down were mutually recursive, so the compiled code for either hom at level k+1 recomputes both branches at every level, which is 2^k recursive calls. Computing the pair at every level by a single recursion makes that O(k). All solver proofs are unchanged up to structure eta.
Iris.Tests.COFESolverEval round-trips a value through tower level 21 at runtime and reads back a Nat payload, so the up/down homs must actually be constructed by the compiled code. The cost is checked against a pure baseline computation timed in the same interpreter, which makes the budget machine-independent: the paired recursion costs a few baseline units, while recomputing the two branches at every level costs several hundred and fails the budget deterministically instead of hanging the build. The depth and baseline size can be overridden via environment variables for experiments.
sgraf812
force-pushed
the
cofesolver-updown
branch
from
July 5, 2026 12:53
e2a1f7d to
d319365
Compare
Contributor
Author
|
Not very convinced about the "perf relative to baseline" approach due to flakiness in CI, but I suppose we can always deactivate the test when it becomes a problem. |
sgraf812
marked this pull request as ready for review
July 5, 2026 20:43
Collaborator
|
All three look good (this one is especially appreciated)! May I ask you only to remove the tests in all three? I think the clarifying comments in the code are enough to understand the rationale. After that, I can merge them asap. |
Contributor
Author
|
Great! Removed the tests. |
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.
Description
perf: compute the up/down pair by a single recursion.
Fix.Impl.upandFix.Impl.downwere mutually recursive, so the compiled code for either hom at levelkrecomputes both branches at every level, which is2^krecursive calls.updowncomputes the section/retraction pair at every level by a single recursion andup/downare its projections, making thatO(k). All solver proofs survive unchanged up to structure eta. Measured on a round-trip of a value through levelkof a tower overProdOF (HomOF (LaterOF IdOF) (LaterOF IdOF)) (constOF (LeibnizO Nat))in the interpreter: the mutual recursion costs 84ms atk = 14and quadruples every two levels (6.4s atk = 20); the paired recursion stays around a millisecond even atk = 2000. Instrumenting the functor'smapcounts2k(k+1)hom constructions with the pair against roughly4 * 2^kwithout.The regression test
Iris.Tests.COFESolverEvalguards exactly this cost: it round-trips a value through level 21 of that tower at runtime (upNthendownN) and reads back aNatthreaded through theconstOFcomponent, so the homs must actually be constructed by the compiled code. Compiled evaluation is not subject tomaxHeartbeats, so the check is a wall-clock budget calibrated against a pure baseline fold timed in the same interpreter, which makes machine speed cancel out: the paired recursion costs 1 baseline units, the mutual recursion 300 or more, and the limit is 20. A regression therefore fails deterministically in well under a minute instead of hanging the build. The file is not amoduleand is built by theIrisTestglob rather than listed inIris.Tests.Checklist
authorssection of any appropriate files