hspZ v0.0.4

H. Parallel execution

Split work units or whole reference bins across workers, overlap order-neutral preparation, and replay arbitrary GPU completions deterministically.

Parallelism changes who runs a WorkUnit and when it finishes. It does not change the plan, within-unit hit stream, or the ordinal order observed by the emitter.

H.1 — Assign whole bins or unit slicesStep 1 of 5

WHAT GOES IN: Planned reference bins and work units, the worker count, and the class of every device the run uses. WHAT HAPPENS: On matching dedicated devices, count quotas give each worker whole bins first, then contiguous query slices; otherwise the longest bins go to the currently lightest worker. Ties break deterministically. WHAT COMES OUT: One ordered list of visits per worker, each a reference bin and a slice of its query bins. INVARIANT: Every WorkUnit has exactly one owner; a bin split across workers costs an extra reference build, never a different unit.

Readable journey

Step 1

H.1 — Assign whole bins or unit slices

what goes in
Planned reference bins and work units, the worker count, and the class of every device the run uses.
what happens
On matching dedicated devices, count quotas give each worker whole bins first, then contiguous query slices; otherwise the longest bins go to the currently lightest worker. Ties break deterministically.
what comes out
One ordered list of visits per worker, each a reference bin and a slice of its query bins.
invariant
Every WorkUnit has exactly one owner; a bin split across workers costs an extra reference build, never a different unit.
  1. Plan → Partition policy: bins, units, device classes
  2. Partition policy → Worker 0: bin + query-slice visits
  3. Partition policy → Worker 1: bin + query-slice visits
Step 2

H.2 — Build reference-scoped state once per visit

what goes in
One worker's next visit: a reference bin and its records, or that bin's arrays in an `hspZ index`.
what happens
The worker packs the bin and builds its stable SeedTable, or loads both from the index, then creates an Engine and uploads reference-scoped buffers.
what comes out
One initialized GPU engine ready for every query bin of the visit.
invariant
Builds plus index loads, engine creations, and reference uploads each equal the visit count, which is the bin count under whole-bin ownership.
  1. Worker → Bin packer: next visit's reference bin
  2. Bin packer → SeedTable: packed reference bases
  3. SeedTable → GPU Engine: stable index + positions
  4. GPU Engine → Worker: reference-ready engine
Step 3

H.3 — Reuse the engine across query work

what goes in
One reference-ready Engine and the visit's query bins (every planned query bin under whole-bin ownership).
what happens
Each query bin is packed, reverse-complemented, split into intervals and batches, then run on both requested strands.
what comes out
One completed Pass for each reference-bin × query-bin WorkUnit.
invariant
WorkUnits execute in the plan's query-bin order within each visit; with `--query-list`, jobs follow list order inside each bin.
  1. Query bins → Interval batches: pack + forward/reverse intervals
  2. Interval batches → GPU Engine: ordered seed batches
  3. GPU Engine → UnitOutput: plus/minus accepted HSPs
Step 4

H.4 — Overlap only order-neutral work

what goes in
The current GPU batch and the next query-seed or reference-bin preparation.
what happens
Seed upload and the next visit's reference build or index load can overlap current kernels; host dependencies still synchronize at count boundaries.
what comes out
Less exposed host/copy time without changing the batch sequence.
invariant
Overlap never reorders MAX_HITS chunks, survivor compaction, or returned HSP vectors.
  1. Current GPU batch → Next seed upload: overlap independent DMA
  2. Current GPU batch → Next reference build or load: overlap independent CPU work
  3. Current GPU batch → Required host boundary: block sums or survivor counts
  4. Required host boundary → Current GPU batch: ordered continuation
Step 5

H.5 — Replay results by ordinal

what goes in
UnitOutputs arriving from workers in arbitrary completion order.
what happens
The coordinator buffers results by WorkUnit ordinal and releases only the next expected unit to the emitter (one per job with `--query-list`); a duplicate or out-of-plan unit is an error.
what comes out
Deterministic partition history, filenames, tar entry order, and output bytes.
invariant
GPU completion order is never observable in the emitted segment set.
  1. Worker 1 → Ordinal buffer: unit 3 completes
  2. Worker 0 → Ordinal buffer: unit 2 completes
  3. Ordinal buffer → Emitter: release unit 2
  4. Ordinal buffer → Emitter: release unit 3