Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Thorin Inline Optimization #144

Merged
merged 41 commits into from
Nov 28, 2022
Merged
Show file tree
Hide file tree
Changes from 30 commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
ac505ae
extends priority optimizer with phase extensions
NeuralCoder3 Nov 10, 2022
b6d2240
added pass registering
NeuralCoder3 Nov 18, 2022
8af4d44
Merge branch 'master' into inline-optimize
NeuralCoder3 Nov 21, 2022
3023702
updated gtest to new communication pipeline
NeuralCoder3 Nov 21, 2022
845d47b
rename
NeuralCoder3 Nov 21, 2022
503bd00
changed type
NeuralCoder3 Nov 21, 2022
b7521fe
working example
NeuralCoder3 Nov 21, 2022
fd1d25e
begin of passes additionally to phases
NeuralCoder3 Nov 21, 2022
952c489
handling of passes (per pass phase)
NeuralCoder3 Nov 21, 2022
f26466e
toggled WARN_AS_ERROR to NO
NeuralCoder3 Nov 22, 2022
b6adb08
documentation
NeuralCoder3 Nov 22, 2022
b76f040
handle passes which depend on other passes
NeuralCoder3 Nov 22, 2022
f8398f7
moved pass instances to builder
NeuralCoder3 Nov 22, 2022
56d3169
passes to phase
NeuralCoder3 Nov 22, 2022
3e9fecb
fixed duplicate pass execution
NeuralCoder3 Nov 22, 2022
34d7372
fixed tests
NeuralCoder3 Nov 22, 2022
a930768
fixed template function position
NeuralCoder3 Nov 22, 2022
248524f
AD compilation passes
NeuralCoder3 Nov 22, 2022
e0cf676
mem passes
NeuralCoder3 Nov 22, 2022
33a0661
moved essential passes from core to compile due to mem
NeuralCoder3 Nov 22, 2022
2d623fe
test phase duplication
NeuralCoder3 Nov 22, 2022
2ae7e1e
add compile dialect to gtest
NeuralCoder3 Nov 22, 2022
58f8ab7
add compile to gtest test
NeuralCoder3 Nov 22, 2022
ab39f6d
disabled pass registering for gtest
NeuralCoder3 Nov 22, 2022
10fed7f
fixed dependencies for mem
NeuralCoder3 Nov 22, 2022
ca83ae8
more modular handling of pipelines
NeuralCoder3 Nov 22, 2022
a95c609
template for tuple conversion
NeuralCoder3 Nov 23, 2022
bb34afc
moved collect args
NeuralCoder3 Nov 23, 2022
d7734e9
normalizers
NeuralCoder3 Nov 23, 2022
852cb9b
solved valgrind memory issues (pass by reference vs pass by value poi…
NeuralCoder3 Nov 23, 2022
e7c3f0d
merged ad_ptr changes
NeuralCoder3 Nov 24, 2022
4cb5d7f
disable bootstrap optimization, default compilation
NeuralCoder3 Nov 24, 2022
c7df887
refactoring 1
NeuralCoder3 Nov 24, 2022
75ad11c
overwrite with master phase
NeuralCoder3 Nov 25, 2022
e347a86
typedef -> using
NeuralCoder3 Nov 25, 2022
714abfe
replaced map with btree
NeuralCoder3 Nov 25, 2022
48b73f2
resolved cyclic dependency
NeuralCoder3 Nov 25, 2022
834a296
workaround for Doxygen warnings
leissa Nov 26, 2022
a62cbe6
notation
NeuralCoder3 Nov 28, 2022
2b6b308
restored default compilation (partial revert of 4cb5d7f)
NeuralCoder3 Nov 28, 2022
600b275
removed non-working pass registration
NeuralCoder3 Nov 28, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions cli/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -98,16 +98,18 @@ int main(int argc, char** argv) {
}

// we always need core and mem, as long as we are not in bootstrap mode..
if (!os[H]) dialect_plugins.insert(dialect_plugins.end(), {"core", "mem"});
if (!os[H]) dialect_plugins.insert(dialect_plugins.end(), {"core", "mem", "compile"});

std::vector<Dialect> dialects;
thorin::Backends backends;
thorin::Normalizers normalizers;
thorin::Passes passes;
if (!dialect_plugins.empty()) {
for (const auto& dialect : dialect_plugins) {
dialects.push_back(Dialect::load(dialect, dialect_paths));
dialects.back().register_backends(backends);
dialects.back().register_normalizers(normalizers);
dialects.back().register_passes(passes);
}
}

Expand All @@ -130,13 +132,13 @@ int main(int argc, char** argv) {
if (os[H]) parser.bootstrap(*os[H]);

PipelineBuilder builder;
for (const auto& dialect : dialects) { dialect.register_passes(builder); }
for (const auto& dialect : dialects) { dialect.add_passes(builder); }

// clang-format off
switch (opt) {
case 0: break;
case 1: Phase::run<Cleanup>(world); break;
case 2: optimize(world, builder); break;
case 2: optimize(world, passes, builder); break;
default: errln("error: illegal optimization level '{}'", opt);
}
// clang-format on
Expand Down
40 changes: 26 additions & 14 deletions dialects/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -37,20 +37,6 @@ add_thorin_dialect(autodiff
INSTALL
)

add_thorin_dialect(core
SOURCES
core/core.cpp
core/core.h
core/normalizers.cpp
core/be/ll/ll.cpp
core/be/ll/ll.h
DEPENDS
math
mem
clos
INSTALL
)

add_thorin_dialect(clos
SOURCES
clos/clos.cpp
Expand All @@ -77,6 +63,30 @@ add_thorin_dialect(clos
INSTALL
)

add_thorin_dialect(compile
SOURCES
compile/compile.cpp
compile/compile.h
compile/normalizers.cpp
compile/passes/debug_print.cpp
compile/passes/debug_print.h
INSTALL
)

add_thorin_dialect(core
SOURCES
core/core.cpp
core/core.h
core/normalizers.cpp
core/be/ll/ll.cpp
core/be/ll/ll.h
DEPENDS
math
mem
clos
INSTALL
)

add_thorin_dialect(demo
SOURCES
demo/demo.cpp
Expand Down Expand Up @@ -118,6 +128,8 @@ add_thorin_dialect(mem
mem/passes/rw/alloc2malloc.h
mem/passes/rw/remem_elim.cpp
mem/passes/rw/remem_elim.h
DEPENDS
compile
HEADER_DEPENDS
core
INSTALL
Expand Down
6 changes: 5 additions & 1 deletion dialects/affine/affine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,16 @@

#include "thorin/dialects.h"

// #include "thorin/pass/pipelinebuilder.h"

NeuralCoder3 marked this conversation as resolved.
Show resolved Hide resolved
#include "dialects/affine/passes/lower_for.h"

using namespace thorin;

extern "C" THORIN_EXPORT thorin::DialectInfo thorin_get_dialect_info() {
return {"affine",
[](thorin::PipelineBuilder& builder) {
builder.extend_opt_phase([](thorin::PassMan& man) { man.add<thorin::affine::LowerFor>(); });
},
nullptr, nullptr};
[](Passes& passes) { register_pass<affine::lower_for_pass, affine::LowerFor>(passes); }, nullptr, nullptr};
}
8 changes: 8 additions & 0 deletions dialects/affine/affine.thorin
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,11 @@
.Cn [start: .Idx m, stop: .Idx m, step: .Idx m, init: «i: n; Ts#i»,
body: .Cn [iter: .Idx m, acc: «i: n; Ts#i», yield: .Cn [«i: n; Ts#i»]],
exit: .Cn [«i: n; Ts#i»]];
///
/// ## Compilation Passes and Phases
///
/// ### %affine.lower_for_pass
///
/// Loweres the %affine.For operation to recursive function calls.
///
.ax %affine.lower_for_pass: %compile.Pass;
6 changes: 6 additions & 0 deletions dialects/autodiff/autodiff.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,5 +35,11 @@ extern "C" THORIN_EXPORT thorin::DialectInfo thorin_get_dialect_info() {
man.add<thorin::autodiff::AutoDiffExternalCleanup>();
});
},
[](Passes& passes) {
register_pass<autodiff::ad_eval_pass, autodiff::AutoDiffEval>(passes);
register_pass<autodiff::ad_zero_pass, autodiff::AutoDiffZero>(passes);
register_pass<autodiff::ad_zero_cleanup_pass, autodiff::AutoDiffZeroCleanup>(passes);
register_pass<autodiff::ad_ext_cleanup_pass, autodiff::AutoDiffExternalCleanup>(passes);
},
nullptr, [](Normalizers& normalizers) { autodiff::register_normalizers(normalizers); }};
}
29 changes: 29 additions & 0 deletions dialects/autodiff/autodiff.thorin
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
/// ## Dependencies
///
.import mem;
.import compile;
/// For derivatives:
.import core;
///
Expand Down Expand Up @@ -42,6 +43,34 @@
.ax %autodiff.add: Π [T:*] -> [T,T] -> T, normalize_add;
.ax %autodiff.sum: Π [n:.Nat,T:*] -> «n; T» -> T, normalize_sum;
///
/// ## Compilation Passes and Phases
///
/// ### Passes
///
.ax %autodiff.ad_eval_pass: %compile.Pass;
.ax %autodiff.ad_zero_pass: %compile.Pass;
.ax %autodiff.ad_zero_cleanup_pass: %compile.Pass;
.ax %autodiff.ad_ext_cleanup_pass: %compile.Pass;
///
/// ### Phases
///
.let ad_cleanup_phase = {
%compile.phases_to_phase (⊤:.Nat)
(
(%compile.passes_to_phase 1 %autodiff.ad_zero_cleanup_pass),
(%compile.passes_to_phase 1 %autodiff.ad_ext_cleanup_pass)
)
};
.let ad_phase = {
%compile.phases_to_phase (⊤:.Nat)
(
optimization_phase,
(%compile.passes_to_phase 1 %autodiff.ad_eval_pass),
(%compile.passes_to_phase 1 %autodiff.ad_zero_pass),
ad_cleanup_phase
)
};
///
/// ## Registered translations
///
/// In this section, we define translations for axioms of other dialects.
Expand Down
2 changes: 1 addition & 1 deletion dialects/clos/clos.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -179,5 +179,5 @@ extern "C" THORIN_EXPORT DialectInfo thorin_get_dialect_info() {

builder.extend_opt_phase(base++, [](PassMan& man) { man.add<clos::LowerTypedClosWrapper>(); });
},
nullptr, [](Normalizers& normalizers) { clos::register_normalizers(normalizers); }};
nullptr, nullptr, [](Normalizers& normalizers) { clos::register_normalizers(normalizers); }};
}
128 changes: 128 additions & 0 deletions dialects/compile/compile.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
#include "dialects/compile/compile.h"

#include <thorin/config.h>
#include <thorin/dialects.h>
#include <thorin/pass/pass.h>

#include "thorin/pass/fp/beta_red.h"
#include "thorin/pass/fp/eta_exp.h"
#include "thorin/pass/fp/eta_red.h"
#include "thorin/pass/fp/tail_rec_elim.h"
#include "thorin/pass/pipelinebuilder.h"
#include "thorin/pass/rw/lam_spec.h"
#include "thorin/pass/rw/partial_eval.h"
#include "thorin/pass/rw/ret_wrap.h"
#include "thorin/pass/rw/scalarize.h"

#include "dialects/compile/autogen.h"
#include "dialects/compile/passes/debug_print.h"

using namespace thorin;

void addPhases(DefVec& phases, World& world, Passes& passes, PipelineBuilder& builder) {
for (auto phase : phases) {
NeuralCoder3 marked this conversation as resolved.
Show resolved Hide resolved
auto [phase_def, phase_args] = collect_args(phase);
world.DLOG("phase: {}", phase_def);
if (auto phase_ax = phase_def->isa<Axiom>()) {
auto flag = phase_ax->flags();
if (passes.contains(flag)) {
auto phase_fun = passes[flag];
phase_fun(world, builder, phase);
} else {
world.WLOG("phase '{}' not found", phase_ax->name());
}
} else {
world.WLOG("phase '{}' is not an axiom", phase_def);
}
}
}

void addPasses(World& world, PipelineBuilder& builder, Passes& passes, DefVec& pass_list) {
// Concept: We create a convention that passes register in the pipeline using append_**in**_last.
NeuralCoder3 marked this conversation as resolved.
Show resolved Hide resolved
// This pass then calls the registered passes in the order they were registered in the last phase.

// We create a new dummy phase in which the passes should be inserted.
builder.append_phase_end([](Pipeline&) {});

for (auto pass : pass_list) {
auto [pass_def, pass_args] = collect_args(pass);
world.DLOG("pass: {}", pass_def);
if (auto pass_ax = pass_def->isa<Axiom>()) {
auto flag = pass_ax->flags();
if (passes.contains(flag)) {
auto pass_fun = passes[flag];
pass_fun(world, builder, pass);
} else {
world.WLOG("pass '{}' not found", pass_ax->name());
}
} else {
world.WLOG("pass '{}' is not an axiom", pass_def);
}
}
}

extern "C" THORIN_EXPORT thorin::DialectInfo thorin_get_dialect_info() {
return {"compile", nullptr,
[](Passes& passes) {
auto debug_phase_flag = flags_t(Axiom::Base<thorin::compile::debug_phase>);
passes[debug_phase_flag] = [](World& world, PipelineBuilder& builder, const Def* app) {
world.DLOG("Generate debug_phase: {}", app);
int level = (int)(app->as<App>()->arg(0)->as<Lit>()->get<u64>());
world.DLOG(" Level: {}", level);
// TODO: add a debug pass to the pipeline
builder.append_pass_after_end([=](PassMan& man) {
man.add<thorin::compile::DebugPrint>(level);
// man.add<thorin::compile::DebugPrint>(level);
// man.add<thorin::compile::DebugPrint>(42);
});
};

auto pass_phase_flag = flags_t(Axiom::Base<thorin::compile::pass_phase>);
passes[pass_phase_flag] = [&](World& world, PipelineBuilder& builder, const Def* app) {
auto [ax, pass_list] = collect_args(app->as<App>()->arg());
addPasses(world, builder, passes, pass_list);
};

auto combined_phase_flag = flags_t(Axiom::Base<thorin::compile::combined_phase>);
passes[combined_phase_flag] = [&](World& world, PipelineBuilder& builder, const Def* app) {
auto [ax, phase_list] = collect_args(app->as<App>()->arg());
addPhases(phase_list, world, passes, builder);
};

passes[flags_t(Axiom::Base<thorin::compile::passes_to_phase>)] =
[&](World& world, PipelineBuilder& builder, const Def* app) {
auto pass_array = app->as<App>()->arg()->projs();
DefVec pass_list;
for (auto pass : pass_array) { pass_list.push_back(pass); }
addPasses(world, builder, passes, pass_list);
};

passes[flags_t(Axiom::Base<thorin::compile::phases_to_phase>)] =
[&](World& world, PipelineBuilder& builder, const Def* app) {
auto phase_array = app->as<App>()->arg()->projs();
DefVec phase_list;
for (auto phase : phase_array) { phase_list.push_back(phase); }
addPhases(phase_list, world, passes, builder);
};

passes[flags_t(Axiom::Base<thorin::compile::pipe>)] = [&](World& world, PipelineBuilder& builder,
const Def* app) {
auto [ax, phases] = collect_args(app);
addPhases(phases, world, passes, builder);
};

register_pass<compile::partial_eval_pass, PartialEval>(passes);
register_pass<compile::beta_red_pass, BetaRed>(passes);
register_pass<compile::eta_red_pass, EtaRed>(passes);

register_pass<compile::scalerize_no_arg_pass, Scalerize>(passes);
register_pass<compile::tail_rec_elim_no_arg_pass, TailRecElim>(passes);
register_pass<compile::lam_spec_pass, LamSpec>(passes);
register_pass<compile::ret_wrap_pass, RetWrap>(passes);

register_pass_with_arg<compile::eta_exp_pass, EtaExp, EtaRed>(passes);
register_pass_with_arg<compile::scalerize_pass, Scalerize, EtaExp>(passes);
register_pass_with_arg<compile::tail_rec_elim_pass, TailRecElim, EtaRed>(passes);
},
nullptr, [](Normalizers& normalizers) { compile::register_normalizers(normalizers); }};
}
7 changes: 7 additions & 0 deletions dialects/compile/compile.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#pragma once

#include <thorin/world.h>

#include "dialects/compile/autogen.h"

namespace thorin::compile {} // namespace thorin::compile
NeuralCoder3 marked this conversation as resolved.
Show resolved Hide resolved
Loading