thesis version
This commit is contained in:
28
examples/basic_edsl.cpp
Normal file
28
examples/basic_edsl.cpp
Normal 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
41
examples/basic_raw.cpp
Normal 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
32
examples/dynamicpool.cpp
Normal 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
52
examples/farmsel.cpp
Normal 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
170
examples/repeatability.cpp
Normal 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
15
examples/serial.cpp
Normal 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);
|
||||
}
|
26
examples/serial_itersel.cpp
Normal file
26
examples/serial_itersel.cpp
Normal 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
105
examples/tests.cpp
Normal 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();
|
||||
}
|
Reference in New Issue
Block a user