#include #include #include "common.h" using namespace alsk; namespace { using Vector = Measure>; using Struct = S, Add>, MultC, Sqrt, S, S, Add, Div>, Tupler >; using Links = L(double, double, double), L(arg::P<0>, arg::P<1>, arg::P<2>), // a, b, c double(arg::P<1>, arg::P<1>), // b*b double(arg::P<0>, arg::P<2>), // a*c double(arg::R<1>), // a*c*# double(arg::R<0>, arg::R<2>) // b*b + a*c*# = D >, double(arg::P<0>), // a*# double(arg::R<0>), // sqrt(D) L(arg::P<1>, arg::R<2>, arg::R<1>), // b, sqrt(D), a*# double(arg::P<0>, arg::P<1>), // + double(arg::R<0>, arg::P<2>) // ^/(a*#) >, L(arg::P<1>, arg::R<2>, arg::R<1>), // b, sqrt(D), a*# double(arg::P<1>), // sqrt(D)*# double(arg::R<0>, arg::P<0>), // ^+b double(arg::R<1>, arg::P<2>) // ^/(a*#) >, std::tuple(arg::R<3>, arg::R<4>) >; using Solver = BuildSkeletonT; constexpr std::initializer_list benchVec1{5, 2, 3, 7, 8, 9, 1, 2, 7, 6, 3, 2, 7}; constexpr std::initializer_list benchVec2{2, 2, 3, 5, 2, 1, 1, 4, 7, 9, 2, 3, 5, 6, 1}; using MultiplyByV = MultiplyBy; using ProcessV = Process; using SumV = Sum; using ProdVectV = ProdVect; using CMTestStruct = S; using CMTestLinks = L(int, int, int, int&), int(arg::P<0>), int(arg::P<1>), Vector(arg::P<2>, arg::R<0>), Vector(arg::P<2>, arg::R<1>), Vector(arg::R<2> const&, arg::R<3> const&), void(arg::P<3>, arg::R<2> const&, arg::R<3> const&) >; using CMTest = BuildSkeletonT; decltype(auto) cmTest(int a, int b, int n, int& r) { decltype(auto) r0 = MultiplyByV{Vector::value_type{benchVec1}}(a); decltype(auto) r1 = MultiplyByV{Vector::value_type{benchVec2}}(b); decltype(auto) r2 = ProcessV{}(n, r0); decltype(auto) r3 = ProcessV{}(n, r1); decltype(auto) r4 = SumV{}(r2, r3); ProdVectV{}(r, r2, r3); return r4; } } TEST_CASE("Serial") { SECTION("basic test") { using F0 = std::function; using FN = std::function; using FX = std::function; std::size_t count; F0 f0 = [&]{ ++count; return 0; }; FN f1 = [&](int v) { ++count; return v+1; }; FN f2 = [&](int v) { ++count; return v*2; }; FX f3 = [&](int v, int x) { ++count; return v<, FX>; using Links = L(int), int(), L(arg::R<0>), int(arg::P<0>), int(arg::R<0>)>, int(arg::R<1>, arg::P<0>)>; using Skel = BuildSkeletonT; auto f = implement(); f.skeleton.task<0>() = f0; f.skeleton.task<1>().task<0>() = f1; f.skeleton.task<1>().task<1>() = f2; f.skeleton.task<2>() = f3; count = 0; REQUIRE(f(3) == 16); REQUIRE(count == 4); } SECTION("serial") { auto solver = implement(); solver.skeleton.task<0>().task<2>().m = -4; solver.skeleton.task<1>().m = -2; solver.skeleton.task<4>().task<0>().m = -1; double x0 = -2.63; double x1 = 3.77; double a = 3.7; double b = -a*(x0+x1); double c = a*x0*x1; auto sol = solver(a, b, c); REQUIRE(std::get<0>(sol) == Approx{x0}); REQUIRE(std::get<1>(sol) == Approx{x1}); } SECTION("copy/moves") { int a{500}, b{100}, n{1'000}, r; int cpBase, mvBase, cpSkel, mvSkel; _copy = _move = 0; cmTest(a, b, n, r); cpBase = _copy; mvBase = _move; std::printf("[base] copy: %zu, move: %zu\n", _copy, _move); _copy = _move = 0; auto cmTestSkel = implement(); // cmTestSkel(a, b); cmTestSkel.skeleton.task<0>() = MultiplyByV{Vector::value_type{benchVec1}}; cmTestSkel.skeleton.task<1>() = MultiplyByV{Vector::value_type{benchVec2}}; cmTestSkel(a, b, n, r); cpSkel = _copy; mvSkel = _move; std::printf("[skel] copy: %zu, move: %zu\n", _copy, _move); REQUIRE(cpBase >= cpSkel); REQUIRE(mvBase <= mvSkel); } }