Repository navigation
Rogue SPR: score single-leaf candidates from parent split overlaps - #223
Open
ms609-agent wants to merge 2 commits into
Open
ms609-agent wants to merge 2 commits into
ms609-agent wants to merge 2 commits into
Conversation
Most single-leaf candidates (96% on random pairs) need no further reduction and share no split once the leaf is removed. Their trees are then the parent trees less one split each, so the MCI cost matrix follows from the parent overlaps minus the leaf's membership (SingleDrop, mutual_clustering_bounded_counts()), skipping KeepAndReduce(), GetSplits() and FirstMatchingSplit(). Eligibility replays reduce_trees()' cherry, root and chain tests on ledgers with the leaf removed. The bounded fill also writes each cell as sum f(n_q) + row + column terms with f(k) = k lg k tabled, instead of four lookups and multiplications. Popcount was measured not to be the fill's cost. Min-of-9 vs main: 30 tips -56%, 80 -61%, 150 -60%; 15/30-move pairs -53%/-55%; depth 2 -3%. Argmin sets match the rebuild path on 13,833 score vectors; vs main only exact ties broken by rounding noise differ. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The reduction predicate replays reduce_trees(), which expects trees rooted on leaf 1; other rootings fall back to rebuilding each candidate. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Performance benchmark results
|
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #223 +/- ##
==========================================
+ Coverage 97.57% 97.67% +0.10%
==========================================
Files 60 60
Lines 6056 6328 +272
==========================================
+ Hits 5909 6181 +272
Misses 147 147 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
This branch has not been deployed
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.
Speeds up
spr_rogue_scores()(#174) by scoring most single-leaf candidates straight from the parent pair's split overlaps.What I measured first
Before changing anything I instrumented a release build (rdtsc). The cost-matrix fill took 35% of runtime at 80 tips and 54% at 150. KeepAndReduce, GetSplits and FirstMatchingSplit together took 46% and 31%.
Popcount is not what makes the fill slow. In a standalone kernel with 1–3 64-bit bins, replacing the popcount with a lookup of parent counts saves about 1 cycle in 14.5 per cell. The time goes on the per-cell log arithmetic. So making the quadrant counts O(1), on its own, would not have helped. The gains come from two other places:
Σ_q f(n_q) + row_term + col_term, wheref(k) = k log₂ kcomes from a table and the row and column terms are computed once per row and column. In the kernel this drops a cell from 14.5 to 8.5 cycles, and costs agree to within 1 unit.SingleDrop,mutual_clustering_bounded_counts()). This applies to 96% of candidates on random pairs and 84% on 15-move pairs. It covers any leaf other than leaf 1 whose removal (a) makes nothing reducible and (b) makes no pair of splits identical. For those, the child cost matrix is the parent overlaps minus the leaf's membership, so KeepAndReduce, GetSplits, FirstMatchingSplit and the price hash are all skipped.reduce_trees()are re-run on parent ledgers with the leaf removed.Benchmarks
Two clean release installs (main, and this branch), run as interleaved separate
Rscriptprocesses, min of 9. I did not usecompare-ab.R. SPR checksums were identical across builds.Depth 2 gains little because pair candidates still rebuild their trees.
The cell formula on its own gave −6% to −16% at 80 and 150 tips; skipping the rebuild accounts for the rest.
Correctness
SingleDrop: I replayed 11,064spr_rogue_scores()calls (13,833 score vectors, 2.9 M candidates; 8–160 leaves, random and near-identical pairs, depths 1 and 2). Argmin sets were identical in every vector, and scores differed by at most 2.8e-14.KeepAndReduce()(no extra leaf dropped, no shared split) on all 589,686 single-leaf candidates.SPRDist()results changed, on an 8-leaf pair with such a tie.tolerance = 0checks of.BoundedCID()againstClusteringInfoDist()are relaxed to 1e-12.Tests
lap()fallback is marked#nocov; it runs only above about 16k leaves.spelling::spell_check_package()is clean.Findings are recorded in
.AGENTS/memory/Optimizations.mdanddev/rogue_mci_bound_findings.md.🤖 Generated with Claude Code