Skip to content

perf(filter): single-pass scalar consensus-tag extraction (-9% CPU) - #969

Merged
nh13 merged 1 commit into
mainfrom
nh/filter-single-pass-tags
Sep 17, 2026
Merged

nh13 merged 1 commit into
mainfrom
nh/filter-single-pass-tags

Conversation

@nh13

@nh13 nh13 commented Sep 16, 2026 •

Copy link
Copy Markdown
Member

Summary

The read-level consensus filter walked a record's aux block ~9 times per record, each find_*_tag restarting at offset 0:

  • is_duplex_consensus reads aD + bD
  • filter_read reads cD + cE
  • filter_duplex_read re-reads cD + cE, then aD/aM/bD/bM/aE/bE

aD/bD were scanned up to 3× per record, so the cost was O(tags · aux_len) per record. Profiling the duplex pipeline showed find_tag_position as a hot spot (8.35% self-time in standalone filter).

This introduces ConsensusScalarTags::from_aux() — a single O(aux_len) walk that collects all eight scalar consensus tags in one pass, mirroring the existing extract_aux_string_tags pattern (and in the same spirit as #964's single-pass zipper walks). New allocation-free filter_read_tags / filter_duplex_read_tags operate on the struct; the AB/BA tier comparison is factored into a shared duplex_tier_result() so the per-tag and single-pass paths cannot drift. The filter command hot path builds the struct once per record and routes classification + both filter decisions through it.

Performance (measured, c8g.8xlarge / 32 vCPU Graviton4, t16)

Standalone fgumi filter over a 9,998,652-read duplex consensus BAM, 3 reps:

wall CPU
base 6.11 s 89.2 s
this PR 5.59 s 80.9 s
delta −8.5% −9.3%

perf self-time for find_tag_position: 8.35% → 3.36% (~60% of the tag-scan cost removed; the residual is the per-base array tags in mask_duplex_bases, intentionally untouched).

Correctness

Byte-identical to the per-tag path — output unchanged (kept 9,998,652 every run):

  • consensus_scalar_tags_match_find asserts the single-pass struct + _tags filters equal the per-tag find_* results across 7 tag combinations (simplex, full duplex, aM/bM fallback, missing pairs, absent-cD, interleaved/out-of-order tags).
  • 91 filter unit + 48 filter integration + the command-level check_filters_raw tests pass; clippy clean.

Notes

The same single-pass technique does not apply to the duplex/simplex/codec callers: those hot paths read exactly one tag per record (MI in strand partitioning, RX per source read), so there is no multi-tag re-scan to collapse. This PR is scoped to filter, where the redundancy actually was.

Risk: output changes — none; unsafe changes — none, with no CLAUDE.md allowlist update required; memory, queue, and thread/backpressure policy changes — none.

Fix: parse the eight scalar consensus tags once per record and reuse them for classification and filtering.

  • Added ConsensusScalarTags::from_aux() with matching first-occurrence, presence, and malformed-aux semantics.
  • Added allocation-free filter_read_tags() and filter_duplex_read_tags().
  • Reused parsed tags in the filter command.
  • Added shared duplex tier evaluation.
  • Added parity tests for missing, malformed, duplicated, and out-of-order tags.
  • Reported benchmarks show 8.5% lower wall time and 9.3% lower CPU time.
  • Reported unit, integration, command-level, and clippy checks pass.

@nh13
nh13 deployed to github-actions September 16, 2026 16:28 — with GitHub Actions Active
@coderabbitai

coderabbitai Bot commented Sep 16, 2026 •

Copy link
Copy Markdown

Review Change StackReview Change Stack

Note

Reviews paused

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Essentials

Run ID: 68fe6e46-113a-4c7b-8051-ab9ff1239b9a

📥 Commits

Reviewing files that changed from the base of the PR and between b46bc79 and 1bcf5de.

📒 Files selected for processing (1)
  • crates/fgumi-consensus/src/filter.rs

Included review availability: 0 reviews are currently available. Your included PR review attempts over the past 7 days set your current allowance at 1 review per hour.


Walkthrough

The change adds single-pass consensus tag parsing and reuses parsed tags during simplex and duplex filtering. Existing threshold, error, masking, classification, and no-call outcomes remain covered by parity and boundary tests.

Changes

Consensus tag filtering

Layer / File(s) Summary
Parsed tag filtering
crates/fgumi-consensus/src/filter.rs
ConsensusScalarTags parses target scalar tags once. Parsed simplex and duplex filters preserve existing threshold, fallback, error, and result behavior. Shared duplex tier evaluation now returns FilterResult directly.
Filter command integration
src/lib/commands/filter.rs
The filter command parses tags for classification and passes them to simplex and duplex checks after read mutations.
Parity and boundary validation
crates/fgumi-consensus/src/filter.rs, src/lib/commands/filter.rs
Tests cover malformed, missing, duplicated, mistyped, and reordered tags. No-call fraction and count boundaries remain unchanged.

Priority: ⬇️ Low

Estimated code review effort: 3 (Moderate) | ~25 minutes

Change: Refactor

Merge Risk: ⚪ Minimal · up to 1bcf5

No identified behavior change currently presents a merge-blocking risk.

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Title check ⚠️ Warning The title uses valid Conventional Commit type and scope and accurately describes the change, but the description is a noun phrase rather than a lowercase imperative. Change the description to lowercase imperative form, for example: "perf(filter): extract scalar consensus tags in a single pass (-9% CPU)".
✅ Passed checks (2 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
  • Fix all pre-merge checks with AI

Comment @coderabbitai help to get the list of available commands.

@nh13

nh13 commented Sep 16, 2026

Copy link
Copy Markdown
Member Author

@coderabbitai pause

@coderabbitai

coderabbitai Bot commented Sep 16, 2026

Copy link
Copy Markdown
✅ Action performed

Reviews paused.

@codecov

codecov Bot commented Sep 16, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 97.64706% with 4 lines in your changes missing coverage. Please review.
✅ Project coverage is 96.08%. Comparing base (ffe914a) to head (1bcf5de).
⚠️ Report is 7 commits behind head on main.

Files with missing lines Patch % Lines
crates/fgumi-consensus/src/filter.rs 97.38% 4 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #969      +/-   ##
==========================================
- Coverage   96.09%   96.08%   -0.02%     
==========================================
  Files         292      292              
  Lines      145174   145691     +517     
==========================================
+ Hits       139510   139986     +476     
- Misses       5664     5705      +41     

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

@nh13
nh13 force-pushed the nh/filter-single-pass-tags branch from 34e2548 to b46bc79 Compare September 16, 2026 19:08
@nh13
nh13 deployed to github-actions September 16, 2026 19:08 — with GitHub Actions Active
@nh13

nh13 commented Sep 17, 2026

Copy link
Copy Markdown
Member Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Sep 17, 2026 •

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

The read-level consensus filter walked a record's aux block ~9 times per
record: is_duplex_consensus reads aD+bD, filter_read reads cD+cE, and
filter_duplex_read re-reads cD+cE then aD/aM/bD/bM/aE/bE (aD/bD scanned up to
3x). Each find_*_tag restarts at offset 0, so cost was O(tags * aux_len)/record
— the find_tag_position hot spot in the duplex-pipeline profile.

Add ConsensusScalarTags::from_aux(): one O(aux_len) walk decoding each target
scalar tag's value at its first occurrence, mirroring the existing
extract_aux_string_tags single-pass pattern. New allocation-free
filter_read_tags / filter_duplex_read_tags operate on it; the duplex tier
comparison is factored into a shared duplex_tier_result() so the per-tag and
single-pass paths cannot drift. The filter command hot path builds the struct
once per record and routes through the _tags variants.

Match the per-tag path exactly, including on malformed aux: a per-tag `seen`
bitset locks each slot to its first occurrence regardless of decode outcome
(mirroring find_tag_position) and records aD/bD presence independently of a
successful integer decode, so is_duplex() matches is_duplex_consensus()'s
type-agnostic presence check rather than diverging on a present-but-mistyped or
duplicated tag. consensus_scalar_tags_match_find (well-formed combos) and
consensus_scalar_tags_match_find_malformed (mistyped/duplicate aux) pin the
equivalence; filter unit + consensus tests pass, clippy pedantic clean.
@nh13
nh13 force-pushed the nh/filter-single-pass-tags branch from b46bc79 to 1bcf5de Compare September 17, 2026 16:03
@nh13
nh13 deployed to github-actions September 17, 2026 16:03 — with GitHub Actions Active
@nh13

nh13 commented Sep 17, 2026

Copy link
Copy Markdown
Member Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Sep 17, 2026 •

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@nh13
nh13 added this pull request to the merge queue Sep 17, 2026
Merged via the queue into main with commit d23da3d Sep 17, 2026
17 checks passed
@nh13
nh13 deleted the nh/filter-single-pass-tags branch September 17, 2026 22:49
@nh13 nh13 mentioned this pull request Sep 17, 2026

This branch was successfully deployed

1 active deployment
github-actions — 1bcf5def Deployed Sep 17, 2026 by nh13 via coverage #4547
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