Function sequant::eval::classify_axis

Function Documentation

inline LoopRole sequant::eval::classify_axis(container::svector_base<Index> const &carried, container::svector_base<Index> const &contracted_below, Index const &axis, container::svector_base<OccurrenceRec> const &occurrences, std::function<container::svector<LoopInstance>(OccurrenceRec const&)> const &enclosing_instances, container::svector<OccurrenceAxisRole> *per_occurrence = nullptr)

Classify one batch-loop axis axis against one value, given the value’s own result indices carried, the axes it contracts at its own node contracted_below (see contracted_indices in eval_expr.hpp), and every use-site occurrences of the value in the forest.

Two questions, the second answered per occurrence:

  • Q1: is axis one of carried (by Index identity)?

    • no -> does contracted_below hold it (the value reduces the axis at its own node)? -> Reduction; otherwise the axis merely encloses the value without touching it -> LoopInvariant.

    • yes -> Q2: for every occurrence, is the loop instance that slices axis's carried position (the occurrence’s own loop_slot at that position) among the instances enclosing the occurrence (enclosing_instances)? Enclosed -> the occurrence reads the value inside its own loop, per batch (OccurrenceRole::Lockstep); not enclosed -> the occurrence reads it where that loop is not running: the value opens the loop itself, or the reader sits after it, or in a sibling nest – in every case the reader needs the assembled value (OccurrenceRole::Assembled). The value’s role is LoopLocal if any occurrence is enclosed and LoopCarried otherwise (also with no occurrences at all). The per-occurrence verdicts are appended to per_occurrence when given; a LoopLocal value with Assembled occurrences is built inside its loop for the former and additionally escapes assembled for the latter (build_ordered_schedule).

Positions, not labels, align the occurrences: every occurrence’s carried list is positionally aligned with carried (each occurrence’s frame relabels the same slots), so axis's position in carried is the one read at every occurrence. Loop identity is the recorded one (OccurrenceRec::loop_slot and the openers’ stamps). An occurrence that is not aligned, or a batched position with no stamp, is a defect of the record and throws.