Function sequant::eval::classify_axis¶
Defined in File legality.hpp
Function Documentation¶
-
inline LoopRole sequant::eval::classify_axis(container::svector<Index> const &carried, container::svector<Index> const &contracted_below, Index const &axis, container::svector<OccurrenceRec> const &occurrences, container::svector<Index> const &sliced, std::function<int(OccurrenceRec const&, Index const&)> const &enclosing_slot = {})¶
Classify one batch-loop axis
axisagainst one value, given the value’s own result indicescarried, the axes it contracts at its own nodecontracted_below(seecontracted_indicesin eval.hpp), and every use-siteoccurrencesof the value in the forest.The four-way decision tree:
Q1: does
carriedhold an index ofaxis'sIndexSpace(compared bybase_key(), i.e. Type not identity)?no -> Q2a: does
contracted_belowhold an index of that type (the value reduces the axis at its own node)? ->Reduction; otherwise the axis merely encloses the value without touching it ->LoopInvariant.yes -> Q2b: for every occurrence that has an enclosing loop of that axis type in its
OccurrenceRec::ectx, gather all same-type enclosing loops (there may be several nested loops of one space, each binding a distinct carried index) and check that every one of the occurrence’s own carried indices of that type is bound (via the ordinal-and-proto-awareIndex::operator==) to some enclosing loop. An occurrence may carry more than one same-space index — e.g. an outer product carrying two occ indices, each lockstep with its own nested loop, or a lockstep slot beside a free one. Every same-type carried slot lockstep with some enclosing loop, at every such occurrence ->LoopLocal; a carried slot with no matching enclosing loop at any occurrence (a free / cross-iteration read) ->LoopCarried. If no occurrence has an enclosing loop of that type at all, the axis is a plain free result index with nothing to lock it to a loop iteration ->LoopCarried.
- Parameters:
enclosing_slot – (optional) the fusion loop_slot of the enclosing loop with tree-frame label
Lat occurrenceocc(the parent occurrence’s slot for L; -1 if unknown). Lockstep with an enclosing loop is then loop-instance-aware: a same-space enclosing loop of a different fusion instance is not this value’s loop — the value is LoopCarried (an assembled escape of its own nest that the other nest reads sliced), not LoopLocal. Label equality alone would conflate the instances (e.g. a 4-occupied intermediate built per batch inside its own nest and read from a sibling nest).