107 lines
2.4 KiB
C++
107 lines
2.4 KiB
C++
#include <catch.hpp>
|
|
|
|
#include <atomic>
|
|
#include <alsk/alsk.h>
|
|
#include <random>
|
|
|
|
#include "common.h"
|
|
|
|
using namespace alsk;
|
|
|
|
TEST_CASE("FarmSel") {
|
|
constexpr std::size_t n = 1024;
|
|
|
|
SECTION("basic test") {
|
|
using Data = int;
|
|
|
|
using Task = std::function<Data()>;
|
|
using Accu = std::function<Data(Data const&, Data const&)>;
|
|
|
|
std::atomic_size_t countTask, countAccu;
|
|
|
|
Task task = [&]{
|
|
++countTask;
|
|
return 42;
|
|
};
|
|
Accu accu = [&](Data const& a, Data const& b) {
|
|
++countAccu;
|
|
return std::min(a, b);
|
|
};
|
|
|
|
using Skel = decltype(getSkeleton((*edsl::makeOperand<Data(), Task>()) ->* edsl::makeOperand<Data(Data, Data), Accu>()));
|
|
|
|
auto f = implement<exec::FirstLevelEqui, Skel>();
|
|
f.skeleton.n = n;
|
|
f.skeleton.task = task;
|
|
f.skeleton.select = accu;
|
|
|
|
countTask = countAccu = 0;
|
|
|
|
SECTION("cores = 1") {
|
|
f.executor.cores = 1;
|
|
|
|
Data d = f();
|
|
REQUIRE(d == 42);
|
|
REQUIRE(countTask == f.skeleton.n);
|
|
REQUIRE(countAccu == f.skeleton.n-1);
|
|
}
|
|
|
|
SECTION("cores = 2") {
|
|
f.executor.cores = 2;
|
|
|
|
Data d = f();
|
|
REQUIRE(d == 42);
|
|
REQUIRE(countTask == f.skeleton.n);
|
|
REQUIRE(countAccu == f.skeleton.n-1);
|
|
}
|
|
}
|
|
|
|
SECTION("repeatability") {
|
|
using Data = std::tuple<int, std::string>;
|
|
using RNG = std::mt19937;
|
|
|
|
using Task = std::function<Data(RNG&)>;
|
|
using Accu = std::function<Data(Data const&, Data const&)>;
|
|
|
|
std::atomic_size_t countTask, countAccu;
|
|
|
|
Task task = [&](RNG& rng) {
|
|
std::uniform_int_distribution<int> dist{0, 32};
|
|
std::uniform_int_distribution<int> text{0, n*n};
|
|
++countTask;
|
|
return Data{dist(rng), std::to_string(text(rng))};
|
|
};
|
|
Accu accu = [&](Data const& a, Data const& b) {
|
|
++countAccu;
|
|
return std::get<0>(a) < std::get<0>(b)? a:b;
|
|
};
|
|
|
|
using Struct = S<FarmSel, Task, Accu>;
|
|
using Links = L<FarmSel, Data(), Data(arg::RNG), Data(Data, Data)>;
|
|
using Skel = BuildSkeletonT<Struct, Links>;
|
|
|
|
auto f = implement<exec::FirstLevelEqui, Skel>();
|
|
f.skeleton.n = n;
|
|
f.skeleton.task = task;
|
|
f.skeleton.select = accu;
|
|
f.executor.cores = 1;
|
|
|
|
Data expected = f();
|
|
|
|
countTask = countAccu = 0;
|
|
|
|
for(std::size_t k = 1; k <= 2; k *= 2) {
|
|
SECTION("cores = "+std::to_string(k)) {
|
|
f.executor.cores = k;
|
|
|
|
f.state.context.reset();
|
|
Data d = f();
|
|
REQUIRE(std::get<0>(d) == std::get<0>(expected));
|
|
REQUIRE(std::get<1>(d) == std::get<1>(expected));
|
|
REQUIRE(countTask == f.skeleton.n);
|
|
REQUIRE(countAccu == f.skeleton.n-1);
|
|
}
|
|
}
|
|
}
|
|
}
|