MimIR
0.4-dev
MimIR is my Intermediate Representation
Toggle main menu visibility
Loading...
Searching...
No Matches
normalizers.cpp
Go to the documentation of this file.
1
#include <
mim/axm.h
>
2
#include <
mim/world.h
>
3
4
#include <
mim/plug/core/core.h
>
5
#include <
mim/plug/mem/mem.h
>
6
7
#include "
mim/plug/autodiff/autodiff.h
"
8
9
namespace
mim::plug::autodiff
{
10
11
/// Currently this normalizer does nothin.
12
/// TODO: Maybe we want to handle trivial lookup replacements here.
13
const
Def
*
normalize_ad
(
const
Def
*,
const
Def
*,
const
Def
*) {
return
{}; }
14
15
const
Def
*
normalize_AD
(
const
Def
*,
const
Def
*,
const
Def
* arg) {
16
auto
ad_ty =
autodiff_type_fun
(arg);
17
if
(ad_ty)
return
ad_ty;
18
return
{};
19
}
20
21
const
Def
*
normalize_Tangent
(
const
Def
*,
const
Def
*,
const
Def
* arg) {
return
tangent_type_fun
(arg); }
22
23
/// Currently this normalizer does nothing.
24
/// We usually want to keep zeros as long as possible to avoid unnecessary allocations.
25
/// A high-level addition with zero can be shortened directly.
26
const
Def
*
normalize_zero
(
const
Def
*,
const
Def
*,
const
Def
*) {
return
{}; }
27
28
/// Currently resolved the full addition.
29
/// There is no benefit in keeping additions around longer than necessary.
30
const
Def
*
normalize_add
(
const
Def
* type,
const
Def
* callee,
const
Def
* arg) {
31
auto
& world = type->world();
32
33
// TODO: add tuple -> tuple of adds
34
// TODO: add zero -> other
35
// TODO: unify mapping over structure with other aspects like zero
36
37
auto
T = callee->as<
App
>()->arg();
38
auto
[a, b] = arg->
projs
<2>();
39
40
if
(
Axm::isa<zero>
(a))
return
b;
41
if
(
Axm::isa<zero>
(b))
return
a;
42
// A value level match would be harder as a tuple might in reality be a var or extract
43
if
(
auto
sig = T->isa<
Sigma
>()) {
44
auto
p = sig->num_ops();
// TODO: or num_projs
45
auto
ops =
DefVec
(p, [&](
size_t
i) {
46
return
world.app(world.app(world.annex<
add
>(), sig->op(i)), {a->proj(i), b->proj(i)});
47
});
48
return
world.tuple(ops);
49
}
else
if
(
auto
arr = T->isa<
Arr
>()) {
50
// TODO: is this working for non-lit (non-tuple) or do we need a loop?
51
auto
pack = world.mut_pack(T);
52
auto
body_type = arr->body();
53
pack->set(world.app(world.app(world.annex<
add
>(), body_type),
54
{world.extract(a, pack->var()), world.extract(b, pack->var())}));
55
return
pack;
56
}
else
if
(
Idx::isa
(type)) {
57
return
world.call(
core::wrap::add
, 0_n,
Defs
{a, b});
58
}
else
if
(
Axm::isa<mem::M>
(type)) {
59
// TODO: mem stays here (only resolved after direct simplification)
60
return
{};
61
}
else
if
(T->isa<
App
>()) {
62
assert(0 &&
"not handled"
);
63
}
64
65
return
{};
66
}
67
68
const
Def
*
normalize_sum
(
const
Def
* type,
const
Def
* callee,
const
Def
* arg) {
69
auto
& world = type->world();
70
71
auto
[count, T] = callee->as<
App
>()->args<2>();
72
73
if
(
auto
lit = count->isa<
Lit
>()) {
74
auto
val = lit->get<
nat_t
>();
75
auto
args = arg->
projs
(val);
76
auto
sum
= world.app(world.annex<
zero
>(), T);
77
// This special case would also be handled by add zero
78
if
(val >= 1)
sum
= args[0];
79
for
(
size_t
i = 1; i < val; ++i)
80
sum
= world.app(world.app(world.annex<
add
>(), T), {sum, args[i]});
81
return
sum
;
82
}
83
assert(0);
84
return
{};
85
}
86
87
MIM_autodiff_NORMALIZER_IMPL
88
89
}
// namespace mim::plug::autodiff
MIM_autodiff_NORMALIZER_IMPL
#define MIM_autodiff_NORMALIZER_IMPL
Definition
autogen.h:86
autodiff.h
axm.h
mim::App
Definition
lam.h:224
mim::Arr
A (possibly paramterized) Array.
Definition
tuple.h:110
mim::Axm::isa
static auto isa(const Def *def)
Definition
axm.h:112
mim::Def
Base class for all Defs.
Definition
def.h:273
mim::Def::projs
auto projs(F f) const
Splits this Def via Def::projections into an Array (if A == std::dynamic_extent) or std::array (other...
Definition
def.h:440
mim::Idx::isa
static const Def * isa(const Def *def)
Checks if def is a Idx s and returns s or nullptr otherwise.
Definition
def.cpp:645
mim::Lit
Definition
def.h:913
mim::Sigma
A dependent tuple type.
Definition
tuple.h:23
core.h
mem.h
mim::plug::autodiff
The automatic differentiation Plugin
Definition
autodiff.h:7
mim::plug::autodiff::normalize_Tangent
const Def * normalize_Tangent(const Def *, const Def *, const Def *arg)
Definition
normalizers.cpp:21
mim::plug::autodiff::zero
zero
Definition
autogen.h:38
mim::plug::autodiff::sum
sum
Definition
autogen.h:54
mim::plug::autodiff::normalize_add
const Def * normalize_add(const Def *type, const Def *callee, const Def *arg)
Currently resolved the full addition.
Definition
normalizers.cpp:30
mim::plug::autodiff::autodiff_type_fun
const Def * autodiff_type_fun(const Def *)
Definition
autodiff.cpp:105
mim::plug::autodiff::normalize_AD
const Def * normalize_AD(const Def *, const Def *, const Def *arg)
Definition
normalizers.cpp:15
mim::plug::autodiff::normalize_ad
const Def * normalize_ad(const Def *, const Def *, const Def *)
Currently this normalizer does nothin.
Definition
normalizers.cpp:13
mim::plug::autodiff::tangent_type_fun
const Def * tangent_type_fun(const Def *)
Definition
autodiff.cpp:54
mim::plug::autodiff::normalize_sum
const Def * normalize_sum(const Def *type, const Def *callee, const Def *arg)
Definition
normalizers.cpp:68
mim::plug::autodiff::normalize_zero
const Def * normalize_zero(const Def *, const Def *, const Def *)
Currently this normalizer does nothing.
Definition
normalizers.cpp:26
mim::plug::autodiff::add
add
Definition
autogen.h:46
mim::plug::core::wrap::add
@ add
Definition
autogen.h:138
mim::nat_t
u64 nat_t
Definition
types.h:37
mim::Defs
fe::View< const Def * > Defs
Definition
def.h:91
mim::DefVec
fe::Vector< const Def * > DefVec
Definition
def.h:93
world.h
src
mim
plug
autodiff
normalizers.cpp
Generated by
1.18.0