MimIR
MimIR is my Intermediate Representation
Loading...
Searching...
No Matches
reassoc.h
Go to the documentation of this file.
1#pragma once
2
3#include <optional>
4
5#include <mim/phase.h>
6
8
9/// One node of a bracketing: `i … j` splits after `s`.
10/// Spelling the fields out keeps `size_t` out of the type - it is *not* mim::u64 everywhere.
11struct Split {
12 u64 i, s, j;
13};
14
15/// A bracketing of a matrix chain, innermost node first.
16using Splits = fe::Vector<Split>;
17
18/// Reassociates chains of tensor.product_2d with the classic matrix-chain-order dynamic program,
19/// so that a chain is evaluated with the least number of vector-lane slots.
20///
21/// Extents need not be literal: a cost is kept as a polynomial in the symbolic extents, ordered by
22/// coefficient-wise `≤`.
23/// Since extents are `Nat`s and hence non-negative, that order proves `≤` under *every* instantiation -
24/// but it is only a *partial* order, so a chain can have several bracketings that each win for some
25/// instantiation (a batch dimension favouring a different one when small than when large).
26/// Up to Reassoc::max_dispatch_ matrices those survivors are emitted side by side behind a runtime
27/// comparison of their costs; a longer chain is only reassociated where one bracketing provably wins.
28class Reassoc : public RWPhase {
29public:
32
33private:
34 static constexpr u64 Default_max_dispatch = 4;
35 static constexpr u64 Default_vec = 8;
36
37 /// One `tensor.product_2d` of a chain: `«m, k» · «k, l»`.
38 struct Link {
39 const App* app;
40 const Def* m;
41 const Def* k;
42 const Def* l;
43 };
44
45 void start() override;
46 const Def* rewrite_imm_App(const App*) final;
47
48 const Def* reassoc(const App*);
49 std::optional<Link> isa_link(const Def* def, const Def* ring) const;
50
51 /// Appends the chain's leaves to @p mats, each leaf's *row* extent to @p dims, and the bracketing as
52 /// written to @p orig; the caller appends the chain's trailing column extent and its own split.
53 void flatten(const Def* def, const Def* ring, const Def* rows, DefVec& mats, DefVec& dims, Splits& orig);
54
55 /// Rebuilds `mats[i … j]` in the new world, parenthesized according to @p split (indexed `i * n + j`).
56 const Def* build(const Def* head, Defs mats, Defs dims, fe::View<u64> split, u64 i, u64 j);
57
58 /// Emits every bracketing in @p cands as a thunk and selects the cheapest one by comparing their costs
59 /// at run time.
60 const Def* dispatch(const Def* head, const Def* res_ty, Defs mats, Defs dims, fe::View<Splits> cands);
61
62 /// The number of lane slots @p splits costs, as a `Nat` expression in the new world.
63 const Def* cost_expr(Defs mats, Defs dims, const Splits& splits);
64
65 /// Old-world consumer count per `product_2d` app, attributed through tuple wrappers.
66 DefMap<u64> consumers_;
67
68 /// Longest chain whose bracketings are enumerated - and, failing a unique winner, dispatched over.
69 /// The number of bracketings is `Catalan(n − 1)`, so this cannot grow much.
70 /// Set with `-X tensor:reassoc-max=<n>`; below `3` nothing is ever dispatched.
71 u64 max_dispatch_ = Default_max_dispatch;
72
73 /// Lanes of the vector loop, which `dot_schedule` runs over each product's trailing extent - or,
74 /// for a transposed operand, `dot_schedule_kvec` over its contraction.
75 /// A literal extent is charged rounded up to a whole number of these, so a bracketing whose
76 /// intermediates are too narrow to fill a vector pays for the lanes it leaves idle.
77 /// Set with `-X tensor:reassoc-vec=<n>`; `1` counts plain scalar multiplications again.
78 u64 vec_ = Default_vec;
79};
80
81} // namespace mim::plug::tensor::phase
Base class for all Defs.
Definition def.h:273
flags_t annex() const
Definition phase.h:81
RWPhase(World &world, std::string name, Analysis *analysis=nullptr)
Definition phase.h:431
World & world()=delete
Hides both and forbids direct access.
The World represents the whole program and manages creation of MimIR nodes (Defs).
Definition world.h:40
Reassoc(World &world, flags_t annex)
Definition reassoc.h:30
const Def * rewrite_imm_App(const App *) final
Definition reassoc.cpp:381
void start() override
Actual entry.
Definition reassoc.cpp:214
fe::Vector< Split > Splits
A bracketing of a matrix chain, innermost node first.
Definition reassoc.h:16
One node of a bracketing: i … j splits after s.
Definition reassoc.h:11
u64 flags_t
Definition types.h:39
fe::View< const Def * > Defs
Definition def.h:91
GIDMap< const Def *, To > DefMap
Definition def.h:88
fe::Vector< const Def * > DefVec
Definition def.h:93
uint64_t u64
Definition types.h:27