P9 (WIP): compiled kernels (rust/simurg-core, PyO3) with bit-identical pure-Python fallback

Rust ports of the hot paths found by profiling: fused per-locus GenCall calling
and scoring, BAF/LRR, libm maps with CPython math semantics, both nearest-neighbour
searches of the normalization fit, and the BPM LocusEntry parser. Address
coverage is memoised per IDAT layout. SIMURG_PURE_PYTHON=1 forces the pure paths.
On the Pi: genotype_sample 3.4 s -> 1.1 s, 36-sample GSA run 131 s -> 46 s, BPM
read 4x faster; 36 GSA + 6 Omni2.5 GTCs and QC tables byte-identical to the pure
path; tests/unit/test_core_kernels.py checks every kernel on edge cases.
bench/profile_genotype.py, bench/scaling.py, cloud task p9 (thread scaling).
This commit is contained in:
kemal committed 2026-09-28 21:28:55 +01:00
1 parent f11b39b5a3
commit 6524a6d1b0
19 files changed
+1755 -6

No files matched your search

+19 -3
View File
@@ -90,9 +90,11 @@ def address_coverage(idat: Idat, manifest: Manifest) -> float:
return float(found.mean())
def check_coverage(idat: Idat, manifest: Manifest) -> tuple[float, list[tuple[str, str]]]:
def check_coverage(
idat: Idat, manifest: Manifest, cache: LocusMapCache | None = None
) -> tuple[float, list[tuple[str, str]]]:
"""IN-027: < 0.99 → E_IDAT_MANIFEST_MISMATCH (raised); < 1 → W_IDAT_LOW_ADDRESS_COVERAGE (returned)."""
cov = address_coverage(idat, manifest)
cov = cache.coverage(idat) if cache is not None and cache.manifest is manifest else address_coverage(idat, manifest)
notes: list[tuple[str, str]] = []
if cov < COVERAGE_ERROR:
raise SimurgError(
@@ -149,10 +151,24 @@ class LocusMapCache:
self.manifest = manifest
self.caddr = control_addresses(manifest)
self._maps: dict[bytes, LocusMap] = {}
self._coverage: dict[bytes, float] = {}
self.max_entries = max_entries
@staticmethod
def _key(idat: Idat) -> bytes:
return hashlib.blake2b(np.ascontiguousarray(idat.address_ids).tobytes(), digest_size=16).digest()
def coverage(self, idat: Idat) -> float:
"""``address_coverage`` memoised per address layout."""
key = self._key(idat)
if (cov := self._coverage.get(key)) is None:
if len(self._coverage) >= self.max_entries:
self._coverage.pop(next(iter(self._coverage)))
cov = self._coverage[key] = address_coverage(idat, self.manifest)
return cov
def get(self, idat: Idat) -> LocusMap:
key = hashlib.blake2b(np.ascontiguousarray(idat.address_ids).tobytes(), digest_size=16).digest()
key = self._key(idat)
lm = self._maps.get(key)
if lm is None:
if len(self._maps) >= self.max_entries: