MimIR
MimIR is my Intermediate Representation
Loading...
Searching...
No Matches
eval.h
Go to the documentation of this file.
1#pragma once
2
3#include <mim/def.h>
4#include <mim/phase.h>
5
7
8/// This phase is the heart of AD.
9/// We replace an `autodiff fun` call with the differentiated function.
10class Eval : public RWPhase {
11public:
12 using RWPhase::RWPhase;
13
14 /// Detect autodiff calls.
15 const Def* rewrite_imm_App(const App*) final;
16
17 /// Acts on toplevel autodiff on closed terms:
18 /// * Replaces lambdas, operators with the appropriate derivatives.
19 /// * Creates new lambda, calls associate variables, init maps, calls augment.
20 const Def* derive(const Def*);
21 const Def* derive_(const Def*);
22
23 /// Applies to (open) expressions in a functional context.
24 /// Returns the rewritten expressions and augments the partial and modular pullbacks.
25 /// The rewrite is identity on the term up to renaming of variables.
26 /// Otherwise, only pullbacks are added.
27 /// To do so, some calls (e.g. axms) are replaced by their derivatives.
28 /// This transformation can be seen as an augmentation with a dual computation that generates the derivatives.
29 const Def* augment(const Def*, Lam*, Lam*);
30 const Def* augment_(const Def*, Lam*, Lam*);
31 /// helper functions for augment
32 const Def* augment_var(const Var*, Lam*, Lam*);
33 const Def* augment_lam(Lam*, Lam*, Lam*);
34 const Def* augment_extract(const Extract*, Lam*, Lam*);
35 const Def* augment_app(const App*, Lam*, Lam*);
36 const Def* augment_lit(const Lit*, Lam*, Lam*);
37 const Def* augment_tuple(const Tuple*, Lam*, Lam*);
38 const Def* augment_pack(const Pack* pack, Lam* f, Lam* f_diff);
39 /// The partial pullback of @p aug in the closed function @p f.
40 const Def* pullback(const Def* aug, Lam* f);
41
42private:
43 /// derive()/augment() run entirely in the new world: the `autodiff.ad` argument is rewritten first, and the
44 /// derivative is built from that copy. This alias resolves the world() calls in the augment machinery accordingly.
45 World& world() { return new_world(); }
46
47 /// Transforms closed terms (lambda, operator) to derived expressions.
48 /// `f => f' = λ x. (f x, f*_x)`
49 /// src Def -> dst Def
50 Def2Def derived;
51 /// Associates expressions (not necessarily closed) in a functional context to their derivatived counterpart.
52 /// src Def -> dst Def
53 Def2Def augmented;
54
55 /// dst Def -> dst Def
56 Def2Def partial_pullback;
57
58 /// Shadows the structure of containers for additional auxiliary pullbacks.
59 /// A very advanced optimization might be able to recover shadow pullbacks from the partial pullbacks.
60 /// Example: The shadow pullback of a tuple is a tuple of pullbacks.
61 /// Shadow pullbacks are not modular (composable with other pullbacks).
62 /// The structure pullback only preserves structure shallowly:
63 /// A n-times nested tuple has a tuple of "normal" pullbacks as shadow pullback.
64 /// Each inner nested tuples should have their own structure pullback by construction.
65 /// ```
66 /// e : [B0, [B11, B12], B2]
67 /// e* : [B0, [B11, B12], B2] -> A
68 /// e*S: [B0 -> A, [B11, B12] -> A, B2 -> A]
69 /// ```
70 /// short theory of shadow pb:
71 /// ```
72 /// t: [B0, ..., Bn]
73 /// t*: [B0, ..., Bn] -> A
74 /// t*_S: [B0 -> A, ..., Bn -> A]
75 /// b = t#i : Bi
76 /// b* : Bi -> A
77 /// b* = t*_S #i (if exists)
78 /// ```
79 /// This is equivalent to:
80 /// `\lambda (s:Bi). t*_S (insert s at i in (zero [B0, ..., Bn]))`
81 /// dst Def -> dst Def
82 Def2Def shadow_pullback;
83};
84
85} // namespace mim::plug::autodiff::phase
Base class for all Defs.
Definition def.h:289
Extracts from a Sigma or Array-typed Extract::tuple the element at position Extract::index.
Definition tuple.h:360
A function.
Definition lam.h:91
A (possibly paramterized) Tuple.
Definition tuple.h:332
World & new_world()
Create new Defs into this.
Definition phase.h:379
RWPhase(World &world, std::string name, Analysis *analysis=nullptr)
Definition phase.h:334
Data constructor for a Sigma.
Definition tuple.h:84
A variable introduced by a binder (mutable).
Definition def.h:857
The World represents the whole program and manages creation of MimIR nodes (Defs).
Definition world.h:43
This phase is the heart of AD.
Definition eval.h:10
const Def * augment_app(const App *, Lam *, Lam *)
Definition eval.cpp:314
const Def * augment_extract(const Extract *, Lam *, Lam *)
Definition eval.cpp:216
const Def * augment_lit(const Lit *, Lam *, Lam *)
Definition eval.cpp:148
const Def * rewrite_imm_App(const App *) final
Detect autodiff calls.
Definition eval.cpp:68
const Def * derive(const Def *)
Acts on toplevel autodiff on closed terms:
Definition eval.cpp:63
const Def * augment_lam(Lam *, Lam *, Lam *)
Definition eval.cpp:166
RWPhase(World &world, std::string name, Analysis *analysis=nullptr)
Definition phase.h:334
const Def * augment_tuple(const Tuple *, Lam *, Lam *)
Definition eval.cpp:249
const Def * augment_var(const Var *, Lam *, Lam *)
helper functions for augment
Definition eval.cpp:160
const Def * augment(const Def *, Lam *, Lam *)
Applies to (open) expressions in a functional context.
Definition eval.cpp:58
const Def * augment_pack(const Pack *pack, Lam *f, Lam *f_diff)
Definition eval.cpp:279
const Def * pullback(const Def *aug, Lam *f)
The partial pullback of aug in the closed function f.
Definition eval.cpp:154
const Def * derive_(const Def *)
Additionally to the derivation, the pullback is registered and the maps are initialized.
Definition eval.cpp:92
const Def * augment_(const Def *, Lam *, Lam *)
Rewrites the given definition in a lambda environment.
Definition eval.cpp:391
DefMap< const Def * > Def2Def
Definition def.h:95