thesis version

This commit is contained in:
2021-05-10 18:14:13 +02:00
commit b688da651b
191 changed files with 35833 additions and 0 deletions

28
examples/basic_edsl.cpp Normal file
View File

@ -0,0 +1,28 @@
#include <alsk/alsk.h>
#include <algorithm>
struct Gen {
int value;
int operator()() { return value++; }
};
int transform(int v, std::mt19937& rng) {
std::uniform_int_distribution<int> d(-3, 3);
return v + d(rng);
}
int main() {
auto gen = alsk::edsl::makeOperand<int(), Gen>();
auto transform = alsk::edsl::makeOperand<int(alsk::arg::R<0>, alsk::arg::RNG), FN(::transform)>();
auto selectMin = alsk::edsl::makeOperand<int(int, int), Fn<int const&(&)(int const&, int const&), std::min<int>>>();
constexpr auto body = (10*alsk::edsl::link<alsk::arg::R<1>()>(gen, transform)) ->* selectMin;
auto algo = alsk::edsl::implement<alsk::exec::StaticPool>(body);
algo.skeleton.task.task<0>() = Gen{5};
algo.executor.repeatability.upTo(8);
algo.executor.cores = 8;
auto r = algo();
std::printf("%d\n", r);
}

41
examples/basic_raw.cpp Normal file
View File

@ -0,0 +1,41 @@
#include <alsk/alsk.h>
struct Gen {
int value;
int operator()() { return value++; }
};
int transform(int v, std::mt19937& rng) {
std::uniform_int_distribution<int> d(-3, 3);
return v + d(rng);
}
/* raw interface */
using Structure =
alsk::S<alsk::FarmSel,
alsk::S<alsk::Serial, Gen, FN(transform)>,
Fn<int const&(&)(int const&, int const&), std::min<int>>
>;
using Links =
alsk::L<alsk::FarmSel, int(),
alsk::L<alsk::Serial, alsk::arg::R<1>(),
int(),
int(alsk::arg::R<0>, alsk::arg::RNG)
>,
int(int, int)
>;
using Skeleton = alsk::BuildSkeletonT<Structure, Links>;
int main() {
auto algo = alsk::implement<alsk::exec::StaticPool, Skeleton>();
algo.skeleton.n = 10;
algo.skeleton.task.task<0>() = Gen{5};
algo.executor.repeatability.upTo(8);
algo.executor.cores = 8;
auto r = algo();
std::printf("%d\n", r);
}

32
examples/dynamicpool.cpp Normal file
View File

@ -0,0 +1,32 @@
#include <alsk/alsk.h>
#include <future>
using namespace alsk::arg;
int main() {
alsk::exec::ExecutorState<alsk::exec::DynamicPool<void>> state;
state.config(4);
constexpr int n = 40;
std::array<std::future<void>, n> futures;
std::puts("begin");
for(int i = 0; i < n; ++i) {
futures[i] = state.run([i] { for(int x = 0; x < 20'000'000+5'000'000*i; ++x); });
}
std::puts("wait");
std::promise<int> p;
std::future<int> f = state.run([] { return 42; }, p);
std::printf("with value: %d\n", f.get());
for(int i = 0; i < n; ++i)
futures[i].wait();
std::puts("end");
}

52
examples/farmsel.cpp Normal file
View File

@ -0,0 +1,52 @@
#include <algorithm>
#include <alsk/alsk.h>
constexpr unsigned benchN = 32;
constexpr int benchMin = -250;
constexpr int benchMax = +250;
constexpr unsigned benchVSize = 1'000'000;
/**
* Functions
*/
namespace bench {
using C = std::vector<int>;
struct Task {
std::size_t size;
auto operator()(int min, int max) {
C v(size);
std::generate_n(std::begin(v), size, [&, i=0]() mutable { return (++i)%(max-min+1) + min; });
return v;
};
};
C select(C const& a, C const& b) {
C::value_type sumA = std::accumulate(std::begin(a), std::end(a), C::value_type{});
C::value_type sumB = std::accumulate(std::begin(b), std::end(b), C::value_type{});
return sumA < sumB? a : b;
}
}
using namespace alsk::arg;
using tmp::Pack;
using SkelFarmSel = alsk::FarmSel<
R<1>(int, int),
Pack<bench::Task, bench::C(P<0>, P<1>)>,
Pack<decltype(&bench::select), bench::C(bench::C const&, bench::C const&)>
>;
int main() {
auto farmSel = alsk::implement<alsk::exec::Sequential, SkelFarmSel>();
farmSel.skeleton.task = bench::Task{benchVSize};
farmSel.skeleton.select = bench::select;
farmSel.skeleton.n = benchN;
auto volatile r = farmSel(benchMin, benchMax);
}

170
examples/repeatability.cpp Normal file
View File

@ -0,0 +1,170 @@
#include <cstdio>
#include <numeric>
#include <random>
#include <thread>
#include <alsk/alsk.h>
template<typename S>
using Executor = alsk::exec::StaticThread<S>;
namespace {
using RNG = std::mt19937;
using namespace alsk;
int task(RNG& rng) {
std::uniform_int_distribution<int> dist(-100, 100);
int a = dist(rng);
std::this_thread::sleep_for(std::chrono::milliseconds(50));
int b = dist(rng);
return a - b;
}
int sel(int a, int b) { return a + b; }
constexpr auto oSel = alsk::edsl::link<int(int, int), FN(sel)>();
} // namespace
void testA0() {
constexpr unsigned n = 20;
auto farm = [] {
RNG rng;
std::array<int, n> ri;
{
std::array<std::thread, n> ti;
for (unsigned i = 0; i < n; ++i)
ti[i] = std::thread{[&r = ri[i]](RNG& rng) { r = task(rng); },
std::ref(rng)};
for (unsigned i = 0; i < n; ++i)
ti[i].join();
}
return std::accumulate(std::begin(ri), std::end(ri), 0, sel);
};
std::printf("taskA0 [n=%u]\n", n);
for(unsigned i = 0; i < 8; ++i)
std::printf(" [x=%u] %5d\n", i, farm());
}
void testA1() {
auto eFarm = alsk::edsl::link<int(RNG&)>(
(20*alsk::edsl::link<int(arg::P<0>), FN(task)>()) ->* oSel
);
auto farm = alsk::edsl::implement<Executor>(eFarm);
std::printf("testA1 [n=%lu]\n", farm.skeleton.n);
for(unsigned k = 1; k <= 8; ++k) {
RNG rng{};
farm.executor.cores = k;
std::printf(" [k=%u] %5d\n", k, farm(rng));
}
}
void testA2() {
auto eFarm = alsk::edsl::link<int()>(
(20*alsk::edsl::link<int(arg::RNG), FN(task)>()) ->* oSel
);
auto farm = alsk::edsl::implement<Executor>(eFarm);
farm.executor.repeatability.upTo(8);
std::printf("testA2 [n=%lu, r=%lu]\n", farm.skeleton.n, farm.state.context.maxId());
for(unsigned k = 1; k <= 8; ++k) {
farm.executor.cores = k;
std::printf(" [k=%u] %5d\n", k, farm());
farm.state.context.reset();
}
}
void testA3() {
constexpr auto oTask = alsk::edsl::link<int(arg::RNG), FN(task)>();
auto eFarm = alsk::edsl::link<int()>(
(11*alsk::edsl::link<arg::R<1>()>(oTask & oTask)) ->* oSel
);
auto farm = alsk::edsl::implement<Executor>(eFarm);
farm.executor.repeatability.upTo(8);
std::printf("testA3 [n=%lu, r=%lu]\n", farm.skeleton.n, farm.state.context.maxId());
for(unsigned k = 1; k <= 8; ++k) {
farm.executor.cores = k;
std::printf(" [k=%u] %5d\n", k, farm());
farm.state.context.reset();
}
}
void testB0() {
constexpr unsigned n0 = 10, n1 = 8;
auto farm = [] {
RNG rng;
std::array<int, n0> ri;
{
auto localTask = [&rng] {
std::array<int, n1> rj;
std::array<std::thread, n1> tj;
for (unsigned j = 0; j < n1; ++j)
tj[j] = std::thread{[&r = rj[j]](RNG& rng) { r = task(rng); },
std::ref(rng)};
for (unsigned j = 0; j < n1; ++j)
tj[j].join();
return std::accumulate(std::begin(rj), std::end(rj), 0, sel);
};
std::array<std::thread, n0> ti;
for (unsigned i = 0; i < n0; ++i)
ti[i] = std::thread{[&r = ri[i], &localTask] { r = localTask(); }};
for (unsigned i = 0; i < n0; ++i)
ti[i].join();
}
return std::accumulate(std::begin(ri), std::end(ri), 0, sel);
};
std::printf("taskB0 [n0=%u, n1=%u]\n", n0, n1);
for(unsigned i = 0; i < 4; ++i)
std::printf(" [x=%u] %5d\n", i, farm());
}
void testB1() {
auto eFarm = alsk::edsl::link<int()>(
(10*alsk::edsl::link<arg::R<1>()>(
alsk::edsl::link<int(arg::RNG), FN(task)>() &
(8*alsk::edsl::link<int(arg::RNG), FN(task)>()) ->* oSel
)) ->* oSel
);
auto farm = alsk::edsl::implement<Executor>(eFarm);
farm.executor.repeatability.upTo(8);
std::printf("testB1 [n0=%lu, n1=%lu, r=%lu]\n", farm.skeleton.n, farm.skeleton.task.task<1>().n, farm.state.context.maxId());
for(unsigned k = 1; k <= 8; ++k) {
farm.executor.cores = k;
std::printf(" [k=%u] %5d\n", k, farm());
farm.state.context.reset();
}
}
int main() {
testA0();
testA1();
testA2();
testA3();
testB0();
testB1();
}

15
examples/serial.cpp Normal file
View File

@ -0,0 +1,15 @@
#include <alsk/alsk.h>
using namespace alsk::arg;
using Skel = alsk::Serial<
R<2>(int, int, int),
tmp::Pack<std::plus<int>, int(P<0>, P<1>)>,
tmp::Pack<std::plus<int>, int(R<0>, P<2>)>,
tmp::Pack<std::multiplies<int>, int(R<0>, R<1>)>
>;
int main() {
auto task = alsk::implement<alsk::exec::Sequential, Skel>();
return task(4, 2, 3);
}

View File

@ -0,0 +1,26 @@
#include <alsk/alsk.h>
int produce(int a, int b) {
return rand()%(a|b);
}
using namespace alsk;
using namespace alsk::arg;
constexpr auto add = edsl::link<int(P<0>, P<1>), std::plus<int>>();
constexpr auto mul = edsl::link<int(R<1>, P<2>), std::multiplies<int>>();
constexpr auto min = edsl::link<int(int, int), Fn<int const&(&)(int const&, int const&), std::min<int>>>();
constexpr auto prod = edsl::link<int(int, P<1>), FN(produce)>();
using Skel = decltype(getSkeleton(
edsl::link<R<2>(int, int, int)>(
add &
edsl::link<int(R<0>, P<1>)>(seq(3 * prod) ->* min) &
mul
)
));
int main() {
auto task = alsk::implement<exec::Sequential, Skel>();
std::printf("%d\n", task(10, 20, 5));
}

105
examples/tests.cpp Normal file
View File

@ -0,0 +1,105 @@
#include <alsk/alsk.h>
#include <algorithm>
#include <iostream>
#include <numeric>
#include <vector>
using namespace alsk::arg;
using namespace alsk::edsl;
void example0(int count) {
struct Do { int operator()(int x) { std::puts("Do"); return x+1; } };
struct Then { void operator()(int v) { std::printf("Then {%d}\n", v); } };
struct Done { int operator()(int x, int y) { std::puts("Done"); return x*y; } };
auto aDo = makeOperand<int(P<0>), Do>();
auto aThen = makeOperand<Then>();
auto aDone = makeOperand<Done>();
auto in = link<R<2>(int)>(
aDo &
link<void(R<0>)>(
4 * link<void(P<0>)>(aThen)
) &
link<int(P<0>, R<0>)>(aDone)
);
auto a = link<void(int)>(count * link<R<2>(P<0>)>(in));
auto f = implement<alsk::exec::Sequential>(a);
f(7);
auto fIn = implement<alsk::exec::Sequential>(in);
std::printf("result: %d\n", fIn(5));
}
void example1() {
// TODO? not really stateful here
struct Generate { int value; int operator()(int b) { return ++value+b; } }; auto generate = makeOperand<Generate>();
struct Transform0 { int operator()(int x) { return x+1; } }; auto transform0 = makeOperand<Transform0>();
struct Transform1 { int operator()(int x) { return x-2; } }; auto transform1 = makeOperand<Transform1>();
struct Produce { int operator()(int x, int y) { return x*y; } }; auto produce = makeOperand<Produce>();
struct Select {
int mod;
int operator()(int a, int b) { if(a%mod == b%mod) return a<b? a : b; return (a%mod > b%mod)? a : b; }
};
auto select = makeOperand<int(int, int), Select>();
auto innerTask = link<R<3>(int)>(
link<int(P<0>)>(generate) &
link<int(R<0>)>(transform0) &
link<int(R<0>)>(transform1) &
link<int(R<2>, R<1>)>(produce)
);
auto task = link<int(int)>(10 * link<R<3>(P<0>)>(innerTask)) ->* select;
auto f = implement<alsk::exec::StaticPool>(task);
f.skeleton.select.mod = 5;
std::printf("results: {");
for(int i = 4; i < 9; ++i) std::printf("%d, ", f(i));
std::puts("}");
}
std::mutex m;
void use(unsigned int n) { unsigned long long volatile v{}; for(unsigned int i{}; i < n; ++i) for(unsigned int j{}; j < 500; ++j) ++v; }
void example2() {
struct Info { void operator()(std::size_t id) {
std::lock_guard<std::mutex> lg{m};
std::cerr << std::this_thread::get_id() << ' ' << id << std::endl;
} }; //auto info = makeOperand<void(CtxId), Info>();
struct Generate { int v; int operator()(std::mt19937& g) { return v+g(); } }; auto generate = makeOperand<Generate>();
struct Transform0 { int operator()(int x) { use(1000); return x+1; } }; auto transform0 = makeOperand<Transform0>();
struct Transform1 { int operator()(int x) { use(1000); return x-2; } }; auto transform1 = makeOperand<Transform1>();
struct Produce { int operator()(int x, int y) { return x*y; } }; auto produce = makeOperand<Produce>();
struct Select {
int mod;
int operator()(int a, int b) { if(a%mod == b%mod) return a<b? a : b; return (a%mod > b%mod)? a : b; }
};
auto select = makeOperand<int(int, int), Select>();
auto innerSeq = link<R<3>(int)>(
link<int(RNG)>(generate) &
link<int(R<0>)>(transform0) &
link<int(R<0>)>(transform1) &
link<int(R<2>, R<1>)>(produce)
);
auto innerTask0 = link<int(int)>(16 * link<R<3>(P<0>)>(innerSeq)) ->* select;
auto innerTask = &link<int(int)>(30 * link<int(int)>(innerTask0)) ->* select;
auto task = link<void(int)>(2 * link<int(P<0>)>(innerTask));
auto f = implement<alsk::exec::StaticThread>(task);
f.executor.cores = 4;
f.executor.repeatability.upTo(f.executor.cores);
f.skeleton.task.select.mod = 12;
f.skeleton.task.task.select.mod = 17;
for(int i = 4; i < 9; ++i) f(i);
}
int main(int argc, char**) {
example0(argc);
example2();
}