Skip to content

Fix kmermatcher memory size allocation OOM.#1117

Open
bbuschkaemper wants to merge 1 commit into
soedinglab:masterfrom
bbuschkaemper:fix-kmermatcher-memory-limit
Open

Fix kmermatcher memory size allocation OOM.#1117
bbuschkaemper wants to merge 1 commit into
soedinglab:masterfrom
bbuschkaemper:fix-kmermatcher-memory-limit

Conversation

@bbuschkaemper

Copy link
Copy Markdown
Contributor

The split memory limit doesn't account for 64-bit types, causing OOM failure.

Summary

This fixes an OOM failure in the kmermatcher on 64-bit builds on large dbs. Since kmermatcher ids are DBKeyType, the per-kmer memory footprint increases in 64-bit mode. The current split sizing could allocate the main kmer arrays almost exactly up to --split-memory-limit, leaving no room for fixed allocations, per-thread scratch buffers, allocator overhead, etc.

The calculation now:

  • Computes exact main per-kmer memory including optional write buffer
  • Reserves fixed memory for seqkey_to_len and per-thread kmer generation buffers
  • Adds 10% headroom to remaining split budget (I added this as precaution, should we change it?)
  • Prevents count-table budget underflow when fixed memory already consumes the limit

Validation

Our clustering of the Uniprac db with ca. 1B sequences crashed at the kmermatcher step. With this fix, the run completes successfully. The old split calculation selected 2 splits but sized each split too close to our 900G memory limit, causing OOM with additional allocations.

Copilot AI review requested due to automatic review settings July 6, 2026 08:31

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adjusts kmermatcher split sizing to better account for 64-bit per-kmer memory footprint and fixed/per-thread allocations, reducing the likelihood of OOM on large databases when --split-memory-limit is tight.

Changes:

  • Introduces saturating arithmetic and helper routines to compute split budgets with fixed-memory reservations and headroom.
  • Reworks main and count-table split calculations to use a computed “available budget” instead of sizing right up to the raw memory limit.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

size_t mainBytesPerKmer = sizeof(KmerPosition<T, includeAdjacency, IncludeSeqLen>) +
(par.needWriteBuffer ? sizeof(KmerPosition<T, false, IncludeSeqLen>) : 0);
size_t totalSizeNeeded = saturatingMul(totalKmers, mainBytesPerKmer);
size_t totalKmersPerSplit = entriesFittingMemoryBudget(mainSplitMemoryBudget, mainBytesPerKmer);
Comment thread src/linclust/kmermatcher.cpp
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