153 lines
4.1 KiB
C++
153 lines
4.1 KiB
C++
#include <catch.hpp>
|
|
#include <alsk/alsk.h>
|
|
|
|
#include "common.h"
|
|
|
|
using namespace alsk;
|
|
|
|
namespace {
|
|
|
|
using Vector = Measure<std::vector<int>>;
|
|
|
|
using Struct =
|
|
S<Serial,
|
|
S<Serial, Mult, Mult, MultC<double>, Add>,
|
|
MultC<double>,
|
|
Sqrt,
|
|
S<Serial, Add, Div>,
|
|
S<Serial, MultC<double>, Add, Div>,
|
|
Tupler
|
|
>;
|
|
|
|
using Links =
|
|
L<Serial, arg::R<5>(double, double, double),
|
|
L<Serial, arg::R<3>(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<Serial, arg::R<1>(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<Serial, arg::R<2>(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<double, double>(arg::R<3>, arg::R<4>)
|
|
>;
|
|
|
|
using Solver = BuildSkeletonT<Struct, Links>;
|
|
|
|
constexpr std::initializer_list<int> benchVec1{5, 2, 3, 7, 8, 9, 1, 2, 7, 6, 3, 2, 7};
|
|
constexpr std::initializer_list<int> benchVec2{2, 2, 3, 5, 2, 1, 1, 4, 7, 9, 2, 3, 5, 6, 1};
|
|
|
|
using MultiplyByV = MultiplyBy<Vector>;
|
|
using ProcessV = Process<Vector>;
|
|
using SumV = Sum<Vector>;
|
|
using ProdVectV = ProdVect<Vector>;
|
|
|
|
using CMTestStruct = S<Serial, MultiplyByV, MultiplyByV, ProcessV, ProcessV, SumV, ProdVectV>;
|
|
using CMTestLinks =
|
|
L<Serial, arg::R<4>(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<CMTestStruct, CMTestLinks>;
|
|
|
|
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<int()>;
|
|
using FN = std::function<int(int)>;
|
|
using FX = std::function<int(int, int)>;
|
|
|
|
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<<x; };
|
|
|
|
using Struct = S<Serial, F0, S<Serial, FN, FN>, FX>;
|
|
using Links = L<Serial, arg::R<2>(int), int(), L<Serial, arg::R<1>(arg::R<0>), int(arg::P<0>), int(arg::R<0>)>, int(arg::R<1>, arg::P<0>)>;
|
|
using Skel = BuildSkeletonT<Struct, Links>;
|
|
|
|
auto f = implement<exec::FirstLevelEqui, Skel>();
|
|
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<exec::StaticPool, Solver>();
|
|
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<exec::Sequential, CMTest>();
|
|
// 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);
|
|
}
|
|
}
|