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