Struct SlicedModeAssignment

Struct Documentation

struct SlicedModeAssignment

The per-(value, sliced-mode) -> DAG-scope-loop assignment: the coloring input fed to canonicalize_slots's NamedIndexColorMap. This is plain data keyed by the value’s own physical Index label for each mode it is sliced on — not a per-cell position map — so a relabeled CSE participant is keyed by its own label, and a symmetric value’s two occurrence-bound physical slots are both recoverable (one entry per distinct (value, Index) pair actually sliced).

Public Functions

inline DagScopeLevel const &level_of(LoopId loop_id) const
Returns:

the realized DagScopeLevel a loop_id names (the inverse of the canonical enumeration levels holds).

Public Members

container::vector<DagScopeLevel> levels

Every distinct DAG-scope loop realized anywhere in the schedule, in canonical (deterministic pre-order over the block tree) order; a value’s assigned LoopId is its position in this list. The root block itself (sentinel axis, outside every loop) is never an entry here.

container::svector<std::tuple<std::size_t, std::size_t, LoopId, std::size_t, std::size_t>> occ_facts

Consumer-attributed per-occurrence sliced-mode facts (sliced-value canonical-layout / loop-coloring design, pillar 2): each entry is (value_id, this occurrence’s own sliced-mode Index, the slicing LoopId, the consumer value_id &#8212; the use-site whose fetch of value_id binds the loop to that Index). Recorded only by the regime-2 (occurrence-driven) pass, the one pass that can attribute a stamp to a specific occurrence and hence to a specific consumer. This is the raw material the cell table builder (cell_table_builder.hpp) consumes to disambiguate the symmetric case (one value, one loop, two free modes bound by two different consumers): a consumer-blind (value, mode) map cannot express “pos0 here, pos1 there” because it folds away which occurrence bound which mode. (value_id, this occurrence’s own sliced-mode physical position &#8212; its index in occ.carried, computed in that occurrence’s own index-frame, LoopId, consumer value_id). The position (not an Index label) is what the table builder consumes, so the runtime never re-matches a label across index-frames. The fifth element is the operand’s leg at the consumer (its index in the consumer occurrence’s operand_points; npos when unknown): a value read on both legs of one consumer under different labels has facts per leg, and the table builder pairs each leg’s read with its own.

container::svector<std::tuple<std::size_t, LoopId, std::size_t, std::size_t>> occ_invariant

Explicit per-occurrence invariant facts: (value_id, LoopId, consumer value_id) triples recording that this consumer’s fetch of the value is correctly unsliced on this loop &#8212; the consumer is building that loop’s batch, but the value’s occurrence in this consumer’S frame does not carry the loop’s mode (a CSE-shared value can carry the mode in one frame and not another). Recording the negative decision lets the runtime tell “correctly invariant” apart from “no decision recorded” (a real gap), so the completeness guard fires only on the latter. Fourth element: the operand’s leg at the consumer, as in occ_facts.