Preserve independent MM-group calls and support larger code sets - #709
Open
SuhasSrinivasan wants to merge 3 commits into
Open
Conversation
SuhasSrinivasan
force-pushed
the
codex/publication-pileup-independent-large-motifs
branch
from
August 11, 2026 00:31
b6c3184 to
9fb9aea
Compare
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.
Review status: Author-reviewed and ready for ONT review.
Addresses #675 and the MM-code cardinality portion of #676.
Summary
This PR fixes two related limitations in the optimized pileup MM-tag scanner:
SmallVec<[ModCodeState; 16]>, preserving inline storage for the existing common case while accepting valid tags with more than 16 code states.The pileup motif-mask limit previously included in this PR has been removed and consolidated into PR #702 with the other motif ownership and validation changes.
Severity
High — scientific correctness and reliable completion.
The progression defect can silently lose or misassign accepted modification calls while
pileupexits successfully. The fixed-capacity representation can panic on a valid MM tag containing more than 16 code states.Root cause and fix
The optimized scanner shared one sequence cursor across MM groups. A group could become zero while a different group selected the current position; the old emission and advancement loops then treated both groups as ready.
Each
ModCodeStatenow has anexplicit_at_positionflag. A scan clears the existing flags, marks only the states explicitly ready at the selected position, and advances only those states. Keeping the flag in the state uses existing struct padding and requires no per-position allocation.The same state consolidation removes the 16-slot assertion. Up to 16 states remain inline and allocation-free. A 17th state spills once during adapter construction; later growth is amortized. The hot-loop complexity remains linear in read length and active code-state count.
Reproduction and expected behavior
For a two-base
CCread withMM:C+m?,0;C+h?,1;andML:[200,250]:For valid tags with 17 code states:
Testing
Tested exact head:
9fb9aea763aa1b78ac1172fa6d6734e7955ccc70.5cecc3fwith only q0/h, then passes on this head with exactly q0/m and q1/h.cargo test --offline --locked -p mod_kit base_mods_adapter_tests --lib -- --nocapture: 13 passed, 0 failed. This includes forward/reverse cursors, ML stride, one multi-code group, many one-code groups, ChEBI codes, 16-inline/17-spilled states, and independent same-base progression.cargo test --offline --locked -p modkit --test test_pileup -- --nocapture: 17 passed, 10 ignored, 0 failed.cargo test --offline --locked --workspace --all-targets --no-fail-fast -- --test-threads=1: 185 passed, 14 ignored, 0 failed.rustfmt --checkandgit diff --check: passed. Whole-workspace formatting still reports unrelated pre-existing formatting differences in untouched files.a85202b69e79e708656e71858e4243cb1cc51e22a44bb9f65650a23dacb407fa. The scanner production source is byte-identical between that benchmarked carrier and this head. This supports no material regression for the normal inline path; it is not presented as a benchmark of the >16 spilled path.Output and compatibility
smallvec; the version already resolves transitively in the tested dependency set.Non-goals
Reviewer guide
modkit/tests/test_pileup.rs.explicit_at_positionand the advance condition inbase_mods_adapter.rs.SmallVec<ModCodeState>conversion, especially forward/reverse MM and ML cursor movement.Author checklist