indicatrix-dispatch 0.5.0

Sample-range scheduling for indicatrix render lanes: a shared disjoint sample cursor, per-lane rate models, a lane pool that merges chunk sums deterministically, and a whole-item batch queue. No networking and no GUI types.
Documentation

indicatrix-dispatch

Sample-range and work-item scheduling for indicatrix render lanes.

indicatrix-dispatch is the scheduler a render coordinator runs: several backends ("lanes" — a joined remote worker, the coordinator's own CPU/GPU, anything implementing WorkerLane) contribute disjoint absolute sample ranges to one image, and their per-chunk radiance sums are merged into one buffer with an exact sample count. It holds no networking, no GUI and no GPU code; it depends only on indicatrix-net (for SceneState) and glam, so both the worker binary and the desktop app can link it.

Why merging by plain addition is sound

A path sample is identified by (global_pixel_index, absolute_sample_index) and nothing else, on every backend. Any set of backends tracing disjoint sample ranges of the same scene at the same resolution therefore merges by per-pixel addition, divided by the total count. Disjointness is the whole correctness guarantee, and SampleCursor provides it by construction.

Main types

  • SampleCursor — the atomic claim point handing out disjoint sample ranges.
  • WorkerLane, ChunkResult, SampleRange — what a lane is, what it is asked to trace and what it returns.
  • RateModel, ChunkPolicy — per-lane throughput calibration and chunk sizing (ChunkPolicy::fixed for a timing-independent partition).
  • LanePool / PoolConfig — N lanes against one cursor for one image epoch, with failure reclaim, backoff, retirement, cancellation and PoolEvents.
  • Merger — the deterministic merge of chunk sums (see below).
  • ItemQueue — whole-item distribution (catalogue batches) over N lanes.
  • CancelToken — a cloneable cancellation flag.

Determinism

Chunks finish in whatever order the lanes finish them. Merger does not add them on arrival; it folds them in ascending first_sample order, parking early arrivals until the chunk at the frontier comes in. For a given partition of the range into chunks, the merged buffer is therefore bit-identical no matter which lane traced which chunk or in which order they finished. The partition itself depends on measured rates unless ChunkPolicy::fixed is used (and no lane fails); different backends are never bit-identical to each other anyway (GPU fma fusion).

Who uses it

  • apps/indicatrix-worker's coordinator (serve) — fans a viewer's render or final-image request out as a LanePool job over joined workers plus its own lane, and emits the Merger's result.
  • apps/indicatrix-cut — its live render loop's sample cursor (bridge::sample_cursor) is this crate's SampleCursor.

Testing

cargo test -p indicatrix-dispatch

Every test lives inline next to its module (sample_cursor, rate, merge, item_queue, pool); the pool tests drive fake lanes, so no network or GPU is needed.