#include #include #include #include #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; using Accu = std::function; 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()) ->* edsl::makeOperand())); auto f = implement(); 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; using RNG = std::mt19937; using Task = std::function; using Accu = std::function; std::atomic_size_t countTask, countAccu; Task task = [&](RNG& rng) { std::uniform_int_distribution dist{0, 32}; std::uniform_int_distribution 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; using Links = L; using Skel = BuildSkeletonT; auto f = implement(); 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); } } } }