MimIR
0.5-dev
MimIR is my Intermediate Representation
Toggle main menu visibility
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
7
namespace
mim::plug::tensor::phase
{
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.
11
/// A transposed node @p t is computed as the product of its operands' transposes, `(Rᵀ · Lᵀ)ᵀ`.
12
struct
Split
{
13
u64
i
,
s
,
j
;
14
bool
t
=
false
;
15
};
16
17
/// A bracketing of a matrix chain, innermost node first.
18
using
Splits
= fe::Vector<Split>;
19
20
/// A chain operand; the chain reads its transpose if @p t.
21
struct
Leaf
{
22
const
Def
*
def
;
23
bool
t
;
24
};
25
26
using
Leaves
= fe::Vector<Leaf>;
27
28
/// Reassociates chains of tensor.product_2d with the classic matrix-chain-order dynamic program,
29
/// so that a chain is evaluated with the least number of vector-lane slots.
30
///
31
/// Extents need not be literal: a cost is kept as a polynomial in the symbolic extents, ordered by
32
/// coefficient-wise `≤`.
33
/// Since extents are `Nat`s and hence non-negative, that order proves `≤` under *every* instantiation -
34
/// but it is only a *partial* order, so a chain can have several bracketings that each win for some
35
/// instantiation (a batch dimension favouring a different one when small than when large).
36
/// Up to Reassoc::max_dispatch_ matrices those survivors are emitted side by side behind a runtime
37
/// comparison of their costs; a longer chain is only reassociated where one bracketing provably wins.
38
class
Reassoc
:
public
RWPhase
{
39
public
:
40
using
RWPhase::RWPhase
;
41
42
private
:
43
static
constexpr
u64
Default_max_dispatch = 4;
44
static
constexpr
u64
Default_vec = 8;
45
46
/// One `tensor.product_2d` of a chain: `«m, k» · «k, l»`.
47
struct
Link {
48
const
App
* app;
49
const
Def
* m;
50
const
Def
* k;
51
const
Def
* l;
52
};
53
54
void
start
()
override
;
55
const
Def
*
rewrite_imm_App
(
const
App
*)
final
;
56
57
const
Def
* reassoc(
const
App
*);
58
std::optional<Link> isa_link(
const
Def
* def,
const
Def
* ring)
const
;
59
60
/// Appends the chain's leaves to @p mats, each leaf's *row* extent to @p dims, and the bracketing as
61
/// written to @p orig; the caller appends the chain's trailing column extent and its own split.
62
void
flatten(
const
Def
* def,
const
Def
* ring,
const
Def
* rows,
bool
t,
Leaves
& mats,
DefVec
& dims,
Splits
& orig);
63
64
/// Rebuilds `mats[i … j]` in the new world, parenthesized according to @p split (indexed `i * n + j`).
65
const
Def
* build(
const
Def
* head, fe::View<Leaf> mats,
Defs
dims, fe::View<u64> split,
u64
i,
u64
j);
66
67
/// Emits every bracketing in @p cands as a thunk and selects the cheapest one by comparing their costs
68
/// at run time.
69
const
Def
* dispatch(
const
Def
* head,
const
Def
* res_ty, fe::View<Leaf> mats,
Defs
dims, fe::View<Splits> cands);
70
71
/// The number of lane slots @p splits costs, as a `Nat` expression in the new world.
72
const
Def
* cost_expr(fe::View<Leaf> mats,
Defs
dims,
const
Splits
& splits);
73
74
/// Old-world consumer count per `product_2d` and 2-D transpose app, attributed through tuple wrappers.
75
DefMap<u64>
consumers_;
76
77
/// Longest chain whose bracketings are enumerated - and, failing a unique winner, dispatched over.
78
/// The number of bracketings is `Catalan(n − 1)`, so this cannot grow much.
79
/// Set with `-X tensor:reassoc-max=<n>`; below `3` nothing is ever dispatched.
80
u64
max_dispatch_ = Default_max_dispatch;
81
82
/// Lanes of the vector loop, which `dot_schedule` runs over each product's trailing extent - or,
83
/// for a transposed operand, `dot_schedule_kvec` over its contraction.
84
/// A literal extent is charged rounded up to a whole number of these, so a bracketing whose
85
/// intermediates are too narrow to fill a vector pays for the lanes it leaves idle.
86
/// Taken from `tensor.vec_width`, i.e. `-X tensor:vec-width=<n>`.
87
u64
vec_ = Default_vec;
88
};
89
90
}
// namespace mim::plug::tensor::phase
mim::App
Definition
lam.h:215
mim::Def
Base class for all Defs.
Definition
def.h:289
mim::RWPhase::RWPhase
RWPhase(World &world, std::string name, Analysis *analysis=nullptr)
Definition
phase.h:334
mim::plug::tensor::phase::Reassoc
Reassociates chains of tensor.product_2d with the classic matrix-chain-order dynamic program,...
Definition
reassoc.h:38
mim::plug::tensor::phase::Reassoc::rewrite_imm_App
const Def * rewrite_imm_App(const App *) final
Definition
reassoc.cpp:376
mim::plug::tensor::phase::Reassoc::start
void start() override
Actual entry.
Definition
reassoc.cpp:207
mim::plug::tensor::phase::Reassoc::RWPhase
RWPhase(World &world, std::string name, Analysis *analysis=nullptr)
Definition
phase.h:334
mim::plug::tensor::phase
Definition
constraints.h:5
mim::plug::tensor::phase::Split::t
bool t
Definition
reassoc.h:14
mim::plug::tensor::phase::Split::j
u64 j
Definition
reassoc.h:13
mim::plug::tensor::phase::Splits
fe::Vector< Split > Splits
A bracketing of a matrix chain, innermost node first.
Definition
reassoc.h:18
mim::plug::tensor::phase::Leaf::t
bool t
Definition
reassoc.h:23
mim::plug::tensor::phase::Leaves
fe::Vector< Leaf > Leaves
Definition
reassoc.h:26
mim::plug::tensor::phase::Leaf::def
const Def * def
Definition
reassoc.h:22
mim::plug::tensor::phase::Split::i
u64 i
Definition
reassoc.h:13
mim::plug::tensor::phase::Split::s
u64 s
Definition
reassoc.h:13
mim::plug::tensor::phase::Leaf
A chain operand; the chain reads its transpose if t.
Definition
reassoc.h:21
mim::plug::tensor::phase::Split
One node of a bracketing: i … j splits after s.
Definition
reassoc.h:12
mim::Defs
fe::View< const Def * > Defs
Definition
def.h:96
mim::DefMap
GIDMap< const Def *, To > DefMap
Definition
def.h:93
mim::DefVec
fe::Vector< const Def * > DefVec
Definition
def.h:98
mim::u64
uint64_t u64
Definition
types.h:27
phase.h
include
mim
plug
tensor
phase
reassoc.h
Generated by
1.18.0