Function sequant::eval::detail::fork_subchain

Function Documentation

inline ForkedSubchain sequant::eval::detail::fork_subchain(container::vector<Step> const &steps, std::function<bool(std::size_t)> const &in_consumer)

Fork an already-built inner sub-chain (an ordered list of Step) into a predicate-false copy and a predicate-true copy, used once per pass at a nest holding a forced-split axis (build_ordered_schedule): for pass k, in_consumer(value_id) is pass_of(value_id) == k, so the predicate-true side is exactly that pass’s own steps out of the nest’s full pending sub-chain (its predicate-false side, everything else, is picked up by a later call for a different k).

A BuildStep goes wholly to one side by in_consumer of its value. A nested ScopeBlock (an inner loop) is recursively forked; each side that has surviving steps or surviving escape outputs is rebuilt as a per-side copy of the loop (same axis / ordinal / kind) carrying only that side’s steps and the escape outputs whose value lands on that side; a side with neither is dropped (an empty loop is never emitted). Note: a loop can be all-escape &#8212; no BuildStep, only scatter outputs contracted at the output step &#8212;

so “no surviving steps” does not imply “no

outputs to strand”; such a side must still be emitted for its outputs, else a whole nested loop is silently dropped.

The relative order of the surviving steps is preserved. The input list is already topologically valid (every ScopeBlock was built through ordered_schedule_topo_sort_steps), and a subsequence of a valid order is itself valid, so no re-sort is needed and no per-step meta is recomputed. This makes the fork a pure structural transform of the Step tree.