alsk/examples/repeatability.cpp

171 lines
3.8 KiB
C++

#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();
}