|
1 | | -# Rosalind: Efficient, deterministic genomics with O(√t) memory for ordinary hardware |
| 1 | +# Rosalind |
2 | 2 |
|
3 | | -**Rosalind** is a Rust engine for genome alignment, streaming variant calling, and custom bioinformatics analytics that runs on commodity or edge hardware. It achieves **O(√t)** working memory, deterministic replay, and drop-in extensibility for new pipelines (Rust plugins or Python bindings). Traditional pipelines often assume tens of gigabytes of RAM, well-provisioned data centers, and uninterrupted connectivity; Rosalind is designed for the opposite: hospital workstations, clinic laptops, field kits, and classrooms. |
| 3 | +**Deterministic, streaming genomics with O(√t) memory. Whole-genome runs in <100 MB RAM.** |
| 4 | + |
| 5 | +**Rosalind** is a Rust engine for genome alignment, streaming variant calling, and custom bioinformatics analytics that runs on commodity or edge hardware. It achieves **O(√t)** working memory, deterministic replay, and drop-in extensibility for new pipelines (Rust plugins or Python bindings). Traditional pipelines often assume 50-100+ gigabytes of RAM, well-provisioned data centers, and uninterrupted connectivity; Rosalind is designed for the opposite: hospital workstations, clinic laptops, field kits, and classrooms. |
4 | 6 |
|
5 | 7 | --- |
6 | 8 |
|
|
9 | 11 | - **Rosalind’s answer**: split workloads into √t blocks, reuse a rolling boundary between blocks, and evaluate a height-compressed tree so memory stays in L1/L2 cache while preserving deterministic results. The entire pipeline fits in well under 100 MB even for whole genomes. |
10 | 12 | - **How you use it**: run the CLI, embed the Rust APIs, or extend via plugins/Python to build bespoke genomics workflows—ideal for quick-turnaround clinical diagnostics, outbreak monitoring, or courses where students explore real data on laptops. |
11 | 13 |
|
| 14 | +See [At a Glance](#at-a-glance), [How It Compares](#how-it-compares), and [What O(√t) memory means](#what-o√t-memory-means-and-what-t-is) for deeper context. |
| 15 | + |
| 16 | +--- |
| 17 | + |
| 18 | +## At a Glance |
| 19 | +- **O(√t) working memory** – whole-genome runs stay under ~100 MB without lossy approximations. |
| 20 | +- **End-to-end deterministic** – outputs are bit-for-bit identical across runs and partition choices. |
| 21 | +- **Full-history equivalent** – recomputation keeps results identical to unbounded-memory evaluations. |
| 22 | +- **Streaming SAM/BAM/VCF** – standards-compliant outputs without materializing huge intermediates. |
| 23 | +- **Edge-ready deployment** – runs on 8–16 GB laptops/desktops so PHI stays on-site. |
| 24 | +- **Composable extensions** – plugins/Python bindings inherit the same memory and determinism guarantees. |
| 25 | + |
12 | 26 | --- |
13 | 27 |
|
14 | 28 | ## Why Rosalind Matters |
|
29 | 43 | - **Full-history equivalence**: results match an unbounded-history evaluation; the space savings come from recomputation, not information loss. |
30 | 44 |
|
31 | 45 | ### What O(√t) memory means (and what 't' is) |
32 | | -- 't' denotes the total units of work (time steps) the pipeline performs. In practice it grows roughly with total bases processed: number of reads × read length, plus modest indexing/merge overhead proportional to the reference. |
33 | | -- Peak resident memory grows with the square root of t, not linearly. If you double the total data processed, peak memory rises by about √2 ≈ 1.41×, not 2×. |
34 | | -- The bound holds because Rosalind keeps only the current block buffer of size Θ(√t), a rolling boundary, and a height‑compressed merge stack of O(log t); older block state is recomputed when needed, not stored. |
35 | | -- Practically: whole‑genome runs stay under ~100 MB on commodity laptops while matching the outputs of an unbounded‑history evaluation. |
| 46 | +- `t` ≈ total bases processed. For 30× human whole-genome sequencing: coverage `C ≈ 30`, genome size `G ≈ 3.1×10⁹`, so `t ≈ C × G ≈ 9.3×10¹⁰`. |
| 47 | +- `√t ≈ 3.0×10⁵`, which sets the block buffer size. The height-compressed merge stack is `log₂(t) ≈ 36` levels—negligible compared with the block. |
| 48 | +- Working set ≈ `(α + β) · √t + γ`. With α ≈ 64–128 B per active position, whole-genome runs sit around 30–80 MB; even conservative assumptions keep the bound <100 MB. |
| 49 | +- The bound holds because only the current block, rolling boundary, and compact merge stack reside in memory; older state is recomputed on demand. |
| 50 | +- The FM-index/reference can be memory-mapped, so the O(√t) claim concerns Rosalind’s dynamic working set relative to dataset size. |
36 | 51 |
|
37 | 52 | --- |
38 | 53 |
|
39 | 54 | ## Why This Is Different |
40 | | -- End-to-end determinism: bit-for-bit identical outputs across runs for the same inputs and parameters; ideal for clinical audits, SOP lock-down, and incident investigation. |
41 | | -- Strict, test-enforced memory bound: whole-genome runs fit in well under 100 MB; CI tests fail if the O(√t) bound regresses. |
42 | | -- True streaming from reads → variants: no need to materialize large intermediates; reduces IO/storage pressure and time-to-first-result. |
43 | | -- Composable extensions that inherit guarantees: plugins and Python bindings share the same compressed evaluator and workspace pool, preserving memory bounds and determinism. |
44 | | -- Standards without heavyweight infra: interoperable SAM/BAM/VCF emission while retaining streaming and memory advantages. |
45 | | -- Cache-resident execution: keeping state in L1/L2 minimizes cache misses and paging on modest hardware, improving real-world throughput outside of large servers. |
| 55 | +- **Partition-invariant determinism** – bit-for-bit identical outputs across runs, regardless of block size or partitioning; ideal for clinical audits, SOP lock-down, and incident investigation. |
| 56 | +- **Strict, test-enforced O(√t) memory** – whole-genome runs fit in well under 100 MB; CI gates fail if the bound regresses. |
| 57 | +- **Full-history equivalence** – recomputation (not truncation) guarantees identical results to an unbounded-memory evaluation. |
| 58 | +- **True streaming reads → variants** – no need to materialize large intermediates; reduces IO/storage pressure and time-to-first-result. |
| 59 | +- **Standards without heavyweight infra** – interoperable SAM/BAM/VCF emission while retaining streaming and memory advantages. |
| 60 | +- **Cache-resident execution** – keeping state in L1/L2 minimizes cache misses and paging on modest hardware, improving real-world throughput outside of large servers. |
| 61 | +- **Composable extensions that inherit guarantees** – plugins and Python bindings share the same compressed evaluator and workspace pool, preserving memory bounds and determinism. |
46 | 62 |
|
47 | 63 | ### Clinical Relevance |
48 | | -- Runs on 8–16 GB hospital desktops and field laptops; no cloud transfer of PHI required. |
49 | | -- Reproducibility by design simplifies validation, accreditation, and audit trails. |
50 | | -- Predictable resource envelope reduces OOM failures and manual reruns on shared workstations. |
51 | | -- Edge-friendly operation tolerates intermittent connectivity and minimizes temp-file churn. |
| 64 | +- Keeps PHI on-site—runs comfortably on 8–16 GB hospital desktops and field laptops without cloud transfer. |
| 65 | +- Bit-for-bit reproducibility simplifies CAP/CLIA audits, SOP lock-down, and incident review. |
| 66 | +- Predictable <100 MB working set avoids OOMs and keeps shared schedulers/workstations stable. |
| 67 | +- Streaming-friendly operation tolerates intermittent connectivity and minimizes temp-file churn in the field. |
| 68 | + |
| 69 | +--- |
| 70 | + |
| 71 | +## How It Compares |
| 72 | +| Capability | Rosalind | Typical Stack | |
| 73 | +| --- | --- | --- | |
| 74 | +| Peak RAM (WGS) | `<100 MB` working set; no multi-GB temp files | `1–16+ GB` RAM plus large intermediates | |
| 75 | +| Determinism | Bit-for-bit identical outputs; partition invariant | Often varies with thread ordering or sharding | |
| 76 | +| Partition invariance | Validated in CI across block sizes | Repartitioning can alter outputs | |
| 77 | +| Streaming outputs | Reads → SAM/BAM → VCF without materializing huge files | Batch stages typically require full intermediates | |
| 78 | +| Standards | SAM/BAM/VCF with streaming-friendly pipeline | Standards supported, but streaming often limited | |
| 79 | +| On-prem edge viability | Runs on 8–16 GB laptops; PHI stays on-site | Assumes high-RAM servers or cloud resources | |
| 80 | +| Guardrails/tests | CI enforces O(√t), determinism, property tests | Unit tests common; resource/determinism guards rare | |
52 | 81 |
|
53 | 82 | --- |
54 | 83 |
|
@@ -232,6 +261,12 @@ The example plugin emits per-base coverage suitable for expression quantificatio |
232 | 261 | | `cargo test --test fm_index_props` | Property tests that validate FM-index rank/total invariants against naive counting. | |
233 | 262 | | `cargo test --test golden_vcf` | Snapshot test for stable VCF rendering; refresh with `ROSALIND_UPDATE_SNAPSHOTS=1`. | |
234 | 263 |
|
| 264 | +### Reproducibility & Validation |
| 265 | +- `cargo test --test determinism` — locks down partition-invariant, bit-for-bit outputs for auditability and SOPs. |
| 266 | +- `cargo test --test fm_index_props` — property-based checks for FM-index rank/total invariants. |
| 267 | +- `ROSALIND_UPDATE_SNAPSHOTS=1 cargo test` — refreshes golden VCF/SAM outputs when expected results change; the default run verifies no drift. |
| 268 | +- Together with CI enforcement of the O(√t) bound, these tests provide a defensible validation story for regulated or clinical environments. |
| 269 | + |
235 | 270 | Optional: enable an RSS regression check with `--features rss` if you want to monitor process RSS in addition to logical counters. |
236 | 271 |
|
237 | 272 | ### Benchmarks & Snapshots |
|
0 commit comments