Module Sarek_worklist.Host

Host-side queue management and the level-synchronous driver.

val (mod) : int -> int -> int
type int32_vector = (int32, Stdlib.Bigarray.int32_elt) Spoc_core.Vector.t
type t = {
  1. ctrl : int32_vector;
  2. slots : int32_vector;
  3. capacity : int;
}
val create : capacity:int -> t

Allocate a queue with a ring of capacity int32 slots. Counters start at zero; call seed before running.

val get_ctrl : t -> int -> int
val set_ctrl : t -> int -> int -> unit
val seed : t -> int32 array -> unit

Seed the initial frontier with items (int32 node/index descriptors): writes them to the front of the ring and sets HEAD=0, TAIL=OUTSTANDING= |items|, OVERFLOW=0.

val head : t -> int
val tail : t -> int
val outstanding : t -> int
val overflow : t -> int

Nonzero if any push found the ring full during a run.

val slot : t -> int -> int

Item currently stored at ring position i mod capacity.

val drive : t -> launch:(level_base:int -> snapshot_tail:int -> unit) -> max_levels:int -> int

Level-synchronous driver. Each level processes the frontier window from level_base up to snapshot_tail (the current TAIL) and any children the workers push extend TAIL for the next level. Calls launch ~level_base ~snapshot_tail (which must run one frontier kernel over that window AND sync the device so TAIL reads back), until a level adds no work (TAIL did not grow) or max_levels is reached. Returns the number of levels launched.

The driver passes the window as SCALAR arguments and only ever READS the device counters (never writes them back): the frontier kernel distributes the window by grid-stride, so there is no shared claim counter to reset and nothing to upload between launches. This is what makes the multi- launch loop coherent under Sarek's CPU/GPU/Both vector residency (a host write to a Both-resident vector would not re-upload).