MimIR
0.5-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/math/math.h
>
6
#include <
mim/plug/mem/mem.h
>
7
8
#include "
mim/plug/autodiff/autodiff.h
"
9
10
namespace
mim::plug::autodiff
{
11
12
/// Currently this normalizer does nothin.
13
/// TODO: Maybe we want to handle trivial lookup replacements here.
14
const
Def
*
normalize_ad
(
const
Def
*,
const
Def
*,
const
Def
*) {
return
{}; }
15
16
const
Def
*
normalize_AD
(
const
Def
*,
const
Def
*,
const
Def
* arg) {
17
auto
ad_ty =
autodiff_type_fun
(arg);
18
if
(ad_ty)
return
ad_ty;
19
return
{};
20
}
21
22
const
Def
*
normalize_Tangent
(
const
Def
*,
const
Def
*,
const
Def
* arg) {
return
tangent_type_fun
(arg); }
23
24
/// Currently this normalizer does nothing.
25
/// We usually want to keep zeros as long as possible to avoid unnecessary allocations.
26
/// A high-level addition with zero can be shortened directly.
27
const
Def
*
normalize_zero
(
const
Def
*,
const
Def
*,
const
Def
*) {
return
{}; }
28
29
/// Currently resolved the full addition.
30
/// There is no benefit in keeping additions around longer than necessary.
31
const
Def
*
normalize_add
(
const
Def
* type,
const
Def
* callee,
const
Def
* arg) {
32
auto
& world = type->world();
33
34
// TODO: add tuple -> tuple of adds
35
// TODO: add zero -> other
36
// TODO: unify mapping over structure with other aspects like zero
37
38
auto
T = callee->as<
App
>()->arg();
39
auto
[a, b] = arg->
projs
<2>();
40
41
if
(
Axm::isa<zero>
(a))
return
b;
42
if
(
Axm::isa<zero>
(b))
return
a;
43
// A value level match would be harder as a tuple might in reality be a var or extract
44
if
(
auto
sig = T->isa<
Sigma
>()) {
45
auto
p = sig->num_ops();
// TODO: or num_projs
46
auto
ops =
DefVec
(p, [&](
size_t
i) {
47
return
world.app(world.app(world.annex<
add
>(), sig->op(i)), {a->proj(p, i), b->proj(p, i)});
48
});
49
return
world.tuple(ops);
50
}
else
if
(
auto
arr = T->isa<
Arr
>()) {
51
// TODO: is this working for non-lit (non-tuple) or do we need a loop?
52
auto
pack = world.mut_pack(T)->set_shape(*arr->shape());
53
auto
body_type = arr->body();
54
pack->set_body(world.app(world.app(world.annex<
add
>(), body_type),
55
{world.extract(a, pack->var()), world.extract(b, pack->var())}));
56
return
pack;
57
}
else
if
(
Idx::isa
(type)) {
58
return
world.call(
core::wrap::add
, 0_n,
Defs
{a, b});
59
}
else
if
(
Axm::isa<mem::M>
(type)) {
60
// TODO: mem stays here (only resolved after direct simplification)
61
return
{};
62
}
else
if
(
Axm::isa<math::F>
(T)) {
63
return
world.call(
math::arith::add
, 0_n,
Defs
{a, b});
64
}
65
66
return
{};
67
}
68
69
const
Def
*
normalize_sum
(
const
Def
* type,
const
Def
* callee,
const
Def
* arg) {
70
auto
& world = type->world();
71
72
auto
[count, T] = callee->as<
App
>()->args<2>();
73
74
if
(
auto
lit = count->isa<
Lit
>()) {
75
auto
val = lit->get<
nat_t
>();
76
auto
args = arg->
projs
(val);
77
auto
sum
= world.app(world.annex<
zero
>(), T);
78
// This special case would also be handled by add zero
79
if
(val >= 1)
sum
= args[0];
80
for
(
size_t
i = 1; i < val; ++i)
81
sum
= world.app(world.app(world.annex<
add
>(), T), {sum, args[i]});
82
return
sum
;
83
}
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:215
mim::Arr
A (possibly paramterized) Array.
Definition
tuple.h:305
mim::Axm::isa
static auto isa(const Def *def)
Definition
axm.h:112
mim::Def
Base class for all Defs.
Definition
def.h:289
mim::Def::projs
auto projs(Projector auto f) const
Splits this Def via Def::projections into an Array (if A == std::dynamic_extent) or std::array (other...
Definition
def.h:457
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:670
mim::Lit
Definition
def.h:948
mim::Sigma
A dependent tuple type.
Definition
tuple.h:39
core.h
math.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:22
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:31
mim::plug::autodiff::autodiff_type_fun
const Def * autodiff_type_fun(const Def *)
Definition
autodiff.cpp:107
mim::plug::autodiff::normalize_AD
const Def * normalize_AD(const Def *, const Def *, const Def *arg)
Definition
normalizers.cpp:16
mim::plug::autodiff::normalize_ad
const Def * normalize_ad(const Def *, const Def *, const Def *)
Currently this normalizer does nothin.
Definition
normalizers.cpp:14
mim::plug::autodiff::tangent_type_fun
const Def * tangent_type_fun(const Def *)
Definition
autodiff.cpp:56
mim::plug::autodiff::normalize_sum
const Def * normalize_sum(const Def *type, const Def *callee, const Def *arg)
Definition
normalizers.cpp:69
mim::plug::autodiff::normalize_zero
const Def * normalize_zero(const Def *, const Def *, const Def *)
Currently this normalizer does nothing.
Definition
normalizers.cpp:27
mim::plug::autodiff::add
add
Definition
autogen.h:46
mim::plug::core::wrap::add
@ add
Definition
autogen.h:144
mim::plug::math::arith::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:96
mim::DefVec
fe::Vector< const Def * > DefVec
Definition
def.h:98
world.h
src
mim
plug
autodiff
normalizers.cpp
Generated by
1.18.0