Repository navigation
dnascope-pangenome: NUMA alignment lanes, faster indel2cnv, vg haplotypes alongside bwa - #41
Merged
DonFreed merged 4 commits intoOct 28, 2026
Conversation
DNAscope already splits bwa into one job per NUMA node (halved until each piece has at most 64 CPUs) on large hosts. dnascope-pangenome ran bwa and minimap2 as single jobs across every node. With FASTQ input it now uses the same rule: - BwaExtractStage builds one bwa-extract job per lane: `fqidx extract -F j/N` feeds `bwa mem -p`, and bwa and `pgutil extract` are pinned to the lane's CPUs with taskset. Each lane writes sample-bwa-<j>.bam and sample-bwa-<j>.fq.gz. - One mm2-lift job per lane reads that lane's extracted reads, pinned to the same CPUs, and waits only for its own bwa lane. - Both dedup stages read every lane's output. Job names are unchanged, so job metrics still group the lanes as one step. - A hidden --no_split_alignment keeps the single jobs. BAM/CRAM input and hosts with 32 or fewer cores are unchanged. `fqidx extract` rejects -K below 10,000,000, while the pangenome bwa uses -K 2,000,000, so split runs use -K 10,000,000 for both. Unsplit runs keep 2,000,000. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
indel2cnv sorts the candidate variants by length, longest first, so the expensive ones are dispatched early. It then grouped them into batches of 5 and called starmap with its default chunksize, which is about len(batches) / (4 * workers). The first chunk therefore held the longest variants of the whole run and went to a single worker, which finished long after the others went idle. Each task is now one variant, with chunksize=1. Results are collected in the same order as before, so the output does not change. On HG002 35x (HPRC v2.0), indel2cnv took 420 -> 68 s on 64 vCPUs and 156 -> 49 s on 192 vCPUs, and the CNV VCF body was identical in both cases. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
vg-haplotypes only needs the k-mer counts, so it is meant to overlap bwa on hosts with enough memory. It did not: the job reserved every core, so the scheduler held it until bwa released its threads, whatever its dependencies said. When the host has room for vg haplotypes (100 GB) plus each bwa lane (32 GB), the job now reserves no threads, as kmc already does, and runs next to bwa. Otherwise it depends on every bwa lane, as before. This replaces the fixed 70 GB check. On HG002 35x with 4 lanes on a 192-vCPU, 384 GB host, the pipeline took 30:10 -> 26:24, with indel2cnv's change included. The output VCF body was unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
DonFreed
requested changes
Oct 28, 2026
DonFreed
left a comment
Contributor
There was a problem hiding this comment.
@haodongchen back to you for some minor changes. Let's keep job names unique and use the same -K for split and unsplit jobs.
Review follow-up: - Job names are unique again: split runs name their lanes bwa-extract-<j> and mm2-lift-<j>, while unsplit runs keep bwa-extract and mm2-lift. - dnascope-pangenome aligns with -K 10,000,000 whether or not it splits, so its results no longer depend on how many NUMA lanes the host has. `fqidx extract` needs at least that, which is why split runs already used it. BwaExtractStage takes the -K as an option, so hybrid-pangenome keeps its current 2,000,000. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Contributor
|
Thanks! |
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.
Three changes to
dnascope-pangenomethat shorten its runtime on large hosts. Each is its own commit with its own tests, so they can be reviewed or reverted separately. A fourth commit makes the review's changes to the first.1. One alignment lane per NUMA node
DNAscope already splits bwa into one job per NUMA node on large hosts.
dnascope-pangenomenow does the same with FASTQ input, and does it for minimap2 too. It uses DNAscope's rule,split_alignment(): NUMA nodes, halved until each piece has at most 64 CPUs.fqidx extract -F j/Nfeedsbwa mem -p, andtasksetpins bwa andpgutil extractto the lane's CPUs.bwa-extract-<j>andmm2-lift-<j>. Unsplit runs keepbwa-extractandmm2-lift.--no_split_alignmentkeeps the single jobs.-K:fqidx extractrejects-Kbelow 10,000,000, sodnascope-pangenomenow aligns with-K 10000000whether or not it splits, and its results don't depend on the host's NUMA layout. This changes the alignments slightly from the previous default of 2,000,000.hybrid-pangenomeshares the stage and keeps 2,000,000.2. Give indel2cnv's workers one variant at a time
indel2cnv sorts the candidate variants longest first. It then grouped them into batches of 5 and passed them to
starmapwith the default chunksize, which is aboutlen(batches) / (4 * workers). So the first chunk held the most expensive variants of the whole run, and they all went to a single worker. That worker kept running long after the others went idle.Each task is now one variant, with
chunksize=1. Results come back in the same order, so the output is unchanged.3. Run vg haplotypes alongside bwa when both fit in memory
vg-haplotypes needs only the k-mer counts. The current code expects it to overlap bwa when memory allows, but it never did: the job reserved every core, so the scheduler held it until bwa finished, whatever its dependencies said.
Now, if the host has room for vg-haplotypes (100 GB) plus 32 GB per bwa lane, the job reserves no threads, as kmc already does, and runs next to bwa. Otherwise it depends on every bwa lane, as before. This replaces the fixed 70 GB check.
The 100 GB budget covers measured peaks on the HPRC v2.0 and v2.1 graphs: about 60 GB with vg 1.73.0 and 1.78.0, and about 92 GB with a vg build that samples in parallel. The 32 GB per lane leaves headroom over bwa-extract's measured 19 GB peak.
Results
HG002 Illumina 35x, HPRC v2.0, FASTQ to small-variant, SV and CNV calls, on AWS on-demand instances.
The first two rows add lanes only. In the last two rows, before and after used the same vg build, so only changes 2 and 3 differ.
Accuracy against GIAB v4.2.1 (Aardvark, genotype match):
-K 10000000, the setting every run now uses.Tests
New unit tests:
test_pangenome_numa_lanes.py, run on a mocked 2-node, 192-CPU hosttest_pangenome_vg_scheduling.pyflake8, mypy and the full test suite pass at every commit, and black passes on every file this PR touches.
sentieon_cli/archive.pyfails black andtest_job_log_capture.py::test_output_proc_sub_stderr_is_capturedfails about 1% of the time, both already ondev(2 failures in 200 runs ondev, 3 in 200 on this branch). This PR touches neither.Not run end-to-end:
🤖 Generated with Claude Code