Struct OccurrenceRec

Struct Documentation

struct OccurrenceRec

One use-site of a value, kept alongside the folded ValueCell.

These are what compute_dag_boulevard's conflict-aware union-find runs over: physical loops are connected components of occurrences, and a value’s identity is derived from them (as-built design section 5.2, doc/dev/specs/2026-09-12-batched-array-dag-eval-as-built.md). Each record carries its occurrence’s physical binding of a relabeled mode plus its own carried / home / liveness / enclosing nest.

These are the per-NodeRec fields compute_dag_boulevard computes during its post-order walk and retains through grouping, beside the per-value union/min/max: (a) two occurrences that bind a relabeled mode to different physical labels (the g.C legs’ i_3 vs i_4) are told apart by their carried; (b) each split cell’s replication factor is a product over the levels it is homed-within-but-does-not-carry, read from its subset-local ectx (enclosing loops) minus carried.

Public Members

std::size_t point

this occurrence’s production static point

std::size_t consumer_point

its structural consumer (parent) point

container::svector<Index> carried

this occurrence’s canon_indices

container::svector<Index> home

home_scope (plain modes)

detail::BatchContext ectx

enclosing loops (excludes this node’s own)

container::svector<std::size_t> ectx_opener_point

The static point of the occurrence (in the same tree) that opened each ectx entry, parallel to ectx: names the loop instance each entry is, so the boulevard can read the DP’s nesting order off the occurrences (RichSchedule::loop_order).

container::svector<std::size_t> operand_points

Static points of this occurrence’s operand occurrences, left then right (empty on a leaf). An operand’s leg is its index here; the sliced-mode seam attributes its facts per leg, so one value read on both legs of a node under different labels (a self-product of a shared intermediate) gets two distinct slicings.

container::svector<std::pair<Index, BatchModeType>> opens

The loops this occurrence’s node opens, with their kind (Contracted: a mode this node contracts in batches; External: a carried mode whose physical loop is introduced here). Carried into RichSchedule::loop_kind once the loop slots are numbered.

container::svector<int> loop_slot

Loop identity: per carried position, the loop_slot of the batch loop that slices it (which member of its same-space group), or -1 where the position is not a batched (loop-sliced) mode. Assigned by the union-find over producer->consumer slot connectivity in compute_dag_boulevard (as-built design section 5.2; this file’s header comment carries the path). Parallel to carried.

container::svector<std::pair<Index, int>> reduced_slot

Loop identity for the modes this occurrence’s value contracts (reduces) in batches at its own node: assigned either by uniting a producing operand’s home-sliced carried-mode node with a synthetic reduction node (the reduction loop and the operand’s slice loop are one physical loop and must share loop_slot), or &#8212; when no operand is home-sliced on the mode &#8212; by seeding that synthetic node directly (see contracted_batched below). A reduced mode has no carried position, so its slot is recorded here as (mode, loop_slot). Read by ordered_schedule's fusion_slot when it places a Reduction escape; a Reduction mode that still resolves to no slot here is a hard error there (build_ordered_schedule throws in its escape-placement loop), not a slot-0 default.

container::svector<Index> contracted_batched

Modes this occurrence’s value contracts in batches at its own node (the legality build_site_of contracted test, mirrored &#8212; see NodeRec::contracted_batched). A mode here owns a loop identity even when no operand of the contraction is itself home-sliced on it (an all-input reduction): the union-find below seeds a component for every entry here that classify_axis would actually call Reduction (no carried index of the same space as the mode), instead of relying solely on a home-sliced child to create one; an entry beside a same-space carried index is classify_axis LoopLocal/LoopCarried, not Reduction, and is left to the ordinary carried-position path.