MimIR
MimIR is my Intermediate Representation
Loading...
Searching...
No Matches
lower.cpp
Go to the documentation of this file.
2
3#include <ranges>
4
5#include <mim/def.h>
6#include <mim/lam.h>
7
9
11
12const Def* Lower::fastest_axis_2(const App* app, const Def* rank) {
13 auto& w = new_world();
14 auto b = rewrite(app->arg()->proj(2, 1));
15 return w.app(w.app(w.annex<tensor::fastest_axis>(), b->type()), {rank, b});
16}
17
18const Def* Lower::lower_via_impl(const App* app, const Def* impl_annex) {
19 auto& w = new_world();
20
21 // The curry chain, innermost App first — hence re-applied in reverse.
22 auto args = DefVec();
23 for (const App* h = app; h; h = h->callee()->isa<App>())
24 args.emplace_back(rewrite(h->arg()));
25
26 // The `_impl` is a `lam`, so applying it triggers beta-reduction. Each `_impl`
27 // body references the `_impl` variants of its dependencies directly, so the
28 // chain bottoms out at the low-level axioms (`map_reduce`, …) in one go.
29 auto impl = impl_annex;
30 for (auto a : args | std::views::reverse)
31 impl = w.app(impl, a);
32 return impl;
33}
34
35const Def* Lower::rewrite_imm_App(const App* app) {
36 auto& w = new_world();
37
38 if (Axm::isa<tensor::broadcast_in_dim>(app)) return lower_via_impl(app, w.annex<tensor::broadcast_in_dim_impl>());
39 if (Axm::isa<tensor::transpose>(app)) return lower_via_impl(app, w.annex<tensor::transpose_impl>());
40 if (Axm::isa<tensor::transpose_2d>(app)) return lower_via_impl(app, w.annex<tensor::transpose_2d_impl>());
41 if (Axm::isa<tensor::map>(app)) return lower_via_impl(app, w.annex<tensor::map_impl>());
42 if (Axm::isa<tensor::unary>(app)) return lower_via_impl(app, w.annex<tensor::unary_impl>());
43 if (Axm::isa<tensor::binary>(app)) return lower_via_impl(app, w.annex<tensor::binary_impl>());
44 if (Axm::isa<tensor::select>(app)) return lower_via_impl(app, w.annex<tensor::select_impl>());
45 if (Axm::isa<tensor::repeat>(app)) return lower_via_impl(app, w.annex<tensor::repeat_impl>());
46 if (Axm::isa<tensor::reshape>(app)) return lower_via_impl(app, w.annex<tensor::reshape_impl>());
47 if (Axm::isa<tensor::slice>(app)) return lower_via_impl(app, w.annex<tensor::slice_impl>());
48 if (Axm::isa<tensor::flip>(app)) return lower_via_impl(app, w.annex<tensor::flip_impl>());
49 if (Axm::isa<tensor::conv>(app)) return lower_via_impl(app, w.annex<tensor::conv_impl>());
50 if (Axm::isa<tensor::pool>(app)) return lower_via_impl(app, w.annex<tensor::pool_impl>());
51
52 // The dot family's `_impl`s take a leading `fastest_2` with no axiom counterpart — the
53 // `tensor.fastest_axis` reflection of the right operand, pre-applied here at the staging
54 // point where that operand is concrete (see tensor.dot_product_impl for the decision).
56 return lower_via_impl(app, w.app(w.annex<tensor::product_2d_impl>(), fastest_axis_2(app, w.lit_nat(2))));
57 if (Axm::isa<tensor::bmm>(app))
58 return lower_via_impl(app, w.app(w.annex<tensor::bmm_impl>(), fastest_axis_2(app, w.lit_nat(3))));
60 // The curry chain, outermost app first: [a, b] {s1 s2} [c1, c2, b1, b2] {nc nb} {r1 r2};
61 // the right operand's rank is {r1 r2}#1.
62 auto groups = app->callee()->as<App>()->callee()->as<App>()->callee()->as<App>();
63 auto r2 = groups->callee()->as<App>()->arg()->proj(2, 1);
64 return lower_via_impl(app, w.app(w.annex<tensor::dot_product_impl>(), fastest_axis_2(app, rewrite(r2))));
65 }
66
67 return RWPhase::rewrite_imm_App(app);
68}
69
70} // namespace mim::plug::tensor::phase
const Def * callee() const
Definition lam.h:275
static auto isa(const Def *def)
Definition axm.h:112
Base class for all Defs.
Definition def.h:273
const Def * proj(nat_t a, nat_t i) const
Similar to World::extract while assuming an arity of a, but also works on Sigmas and Arrays.
Definition def.cpp:623
const fe::Vector< std::string > & args()
Command-line arguments passed to this Phase's plugin via -X <plugin>:<arg>.
Definition phase.cpp:23
World & new_world()
Create new Defs into this.
Definition phase.h:452
virtual const Def * rewrite(const Def *)
Definition rewrite.cpp:55
const Def * rewrite_imm_App(const App *) final
Definition lower.cpp:35
fe::Vector< const Def * > DefVec
Definition def.h:93