Einsum-ish building blocks #
Typed einsum wrappers (fast, total) #
These are non-Option equivalents for the most common einsum contractions in ML code.
They are intended to be used directly (no string parsing), and serve as the fast-path targets for
einsum?.
Einsum pattern used in attention: bhid,bhjd -> bhij (batched Q·Kᵀ per head).
Instances For
Einsum pattern used in attention: bhij,bhjd -> bhid (batched Attn·V per head).
Instances For
General einsum (PyTorch-style subscripts; runtime-checked) #
Decidable instance for Shape.wellFormed, used by the dynamic einsum lowering.
Instances For
Local decidability instance for Shape.wellFormed (used by the dynamic einsum lowering).
Instances For
One operand’s subscript, split around an optional ellipsis.
For example, parsing "ab...cd" yields:
Index letters before the ellipsis.
Index letters after the ellipsis, empty when there is none.
- hasEll : Bool
Whether an ellipsis was present. Without this flag
"ab"and"ab..."would parse to the same pair of lists, and they mean different things once batch axes are matched up.
Instances For
Instances For
Remove ASCII whitespace to simplify the hand-rolled parser.
Instances For
Parsed einsum equation: input subscripts and an optional explicit output subscript.
One subscript per operand, in the order they appear left of
->.Explicit output subscript, or
nonefor the implicit form, where the output axes are the letters appearing exactly once, in alphabetical order (the NumPy convention).
Instances For
Detect whether a list of labels contains any duplicates (order-preserving scan).
Instances For
Convert a permutation of axes into a sequence of adjacent swaps.
This validates that perm has length r and only mentions axes below r, then delegates to the
IR lowering strategy NN.IR.Graph.swapDepthsForPerm: a general permutation is represented as a
list of swap depths, and swaps are implemented with swapAdjacentAtDepth.
Instances For
Expand an input operand’s labels to a full label list matching the operand’s rank.
If the subscript contains an ellipsis, this inserts fresh Label.ell labels so that the total
label count matches Spec.Shape.rank s.
Instances For
Small association-list helpers #
To keep this file dependency-light, we represent maps as association lists and use small helpers
instead of Std.HashMap.
Occurrence counts for labels, represented as an association list.
Instances For
Number of occurrences of a label. An absent label has count zero.
Instances For
Increment a label’s count (inserting it if absent).
Instances For
Map each label to its concrete dimension size (association list).
Instances For
Infer a consistent label-to-dimension map from operand label lists and operand shapes.
This implements standard einsum broadcast rules: if a label is seen with both d and 1, we keep
d; if two non-1 sizes disagree, we error.
Instances For
Apply a permutation expressed as adjacent swap depths to an existentially-shaped tensor.
This is the runtime “apply swaps” primitive used by both .permute and the dynamic einsum output
reordering.
Instances For
Apply adjacent swaps while retaining the resulting shape in the return type.
Instances For
Compute a permutation that maps src to tgt when duplicates are present.
This is used for the “diagonal embedding” case when output labels contain repeats: we temporarily expand the output with extra axes, then permute back to the requested (possibly-duplicated) order.
Instances For
Recursive worker for the diagonal mask, carrying the indices seen so far on axes p and q.
Both axes are counted down as the recursion walks dims, so 0 means "this axis"; when the
recursion bottoms out the two remembered indices decide the entry.
Instances For
Diagonal mask specification with fresh index-tracking state.
Instances For
Specialize diagMaskSpec to a concrete Shape.
Instances For
Permutation list that moves axis to the last position (keeping relative order of others).