Skip to content

bench: replay a rustar-aligner shaped segmented build from a fixture - #14

Merged
rob-p merged 2 commits into
COMBINE-lab:mainfrom
BenjaminDEMAILLE:bench/rustar-segmented-harness
Aug 14, 2026
Merged

bench: replay a rustar-aligner shaped segmented build from a fixture#14
rob-p merged 2 commits into
COMBINE-lab:mainfrom
BenjaminDEMAILLE:bench/rustar-segmented-harness

Conversation

@BenjaminDEMAILLE

@BenjaminDEMAILLE BenjaminDEMAILLE commented Aug 13, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds a standalone replay of the rustar-aligner-shaped segmented suffix-array build, so caps-sa changes can be screened on the production workload before they become optimization PRs.

This is deliberately a benchmark/documentation PR only: it changes no library API or construction algorithm. PR #15 is stacked on this harness and contains the packed-prefix optimization.

What the harness preserves

examples/rustar_segmented_bench.rs replays the call shape made by rustar-aligner's sa_build::dispatch_caps_sa_segmented:

  • the complete 2 * n_genome encoded u8 text (A..T = 0..=3, N = 4, spacer = 5), including the annotation-derived junction append;
  • SegmentedText::from_ends over ruSTAR's spacer-run boundaries;
  • STAR's spacer-as-largest boundary convention and ascending-position tie-break;
  • the ACGT-start streaming filter through build_ext_mem_for_filter_with;
  • u64 output positions on production-scale inputs.

It reports build wall time, emitted-position count, and a 128-bit order-sensitive checksum. Matching counts and checksums are a strong regression signal, not a mathematical proof of equality; release validation should compare streams exactly or use a direct suffix comparator on a smaller fixture.

Reproducible fixture format

The harness consumes:

  • text.bin: the encoded text handed to caps-sa;
  • ends.u64: strictly increasing cumulative segment ends in little-endian u64, ending at text.bin's length.

bench/README.md now documents the precise dump point in dispatch_caps_sa_segmented, a minimal dump snippet, the fixture invariants, and the command for a pinned 32-core replay. This keeps the fixture tied to the selected rustar-aligner revision, FASTA, GTF, sjdbOverhang, parsing, junction deduplication, padding, and forward/reverse-complement layout.

The CLI now rejects missing option values, unknown flags, zero thread counts, and zero repetitions with a usage message. It also checks that the fixture is non-empty and uses ruSTAR's encoded alphabet.

Why this workload matters

On the original chr21 + GENCODE fixture (95,847,502 symbols, 9,952 segments, 82,167,238 retained suffixes), 972,463,189 observed LCP calls had this result-length distribution:

LCP result Calls Share
0–15 bytes 955,953,546 98.302%
16–31 5,908,048 0.608%
32–63 3,971,082 0.408%
64–127 2,363,153 0.243%
128–255 620,692 0.064%
256–1023 711,260 0.073%
1 KiB–16 KiB 1,662,629 0.171%
16 KiB+ 1,272,779 0.131%

This is materially different from raw FASTA: N-starting positions are filtered before sorting, while segment limits stop comparisons at chromosome and splice-flank boundaries. Optimizations with per-call overhead therefore need to justify that cost on the overwhelmingly short-comparison common case.

Validation

  • 80 debug and 80 release tests pass across all targets.
  • Formatting and Clippy pass with warnings denied.
  • Rustdoc and doctests pass with warnings denied.
  • cargo package --locked --offline --allow-dirty builds and verifies the packaged crate.
  • Help and malformed-option CLI paths behave as documented.
  • GitHub CI covers stable Linux, stable macOS/NEON, MSRV 1.89, formatting, Clippy, and rustdoc.

rustar-aligner's `sa_build` is the workload that decides whether a change
to this crate is worth having, and it does not look like a flat-text
build: N-starting suffixes are never sorted, and the `LimitProvider`
stops every comparison at a chromosome or junction-flank boundary. On a
chr21-shaped fixture 98.3% of LCP calls resolve inside 16 bytes.
Measuring a candidate on raw FASTA instead is how an optimization that
regresses this workload gets proposed.

This example replays the exact call shape `dispatch_caps_sa_segmented`
makes (the spacer-bearing `u8` text verbatim, `SegmentedText::from_ends`
over the spacer-run ends, STAR's boundary order, and the ACGT-only
streaming filter through `build_ext_mem_for_filter_with`) from a fixture
directory holding `text.bin` and `ends.u64`.

It reports the caps-sa build wall time, the emitted entry count, and an
order-sensitive checksum of the emitted position stream, so an A/B is
correctness-gated by construction: identical checksum, identical suffix
array.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@rob-p
rob-p merged commit 81478f0 into COMBINE-lab:main Aug 14, 2026
5 checks passed
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.

2 participants