yap/perf/code_gen_samples.cpp
2018-02-15 18:07:48 -06:00

108 lines
2.8 KiB
C++

// Copyright (C) 2016-2018 T. Zachary Laine
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include <boost/yap/expression.hpp>
template <typename T>
using term = boost::yap::terminal<boost::yap::expression, T>;
namespace yap = boost::yap;
namespace bh = boost::hana;
namespace user {
struct number
{
double value;
friend number operator+ (number lhs, number rhs)
{ return number{lhs.value + rhs.value}; }
friend number operator* (number lhs, number rhs)
{ return number{lhs.value * rhs.value}; }
};
// A more efficient fused multiply-add operation would normally go here.
number naxpy (number a, number x, number y)
{ return number{a.value * x.value + y.value}; }
// Transforms expressions of the form "a * x + y" to "naxpy(a, x, y)" via
// the implicit transform customiztion point.
template <typename Expr1, typename Expr2, typename Expr3>
decltype(auto) transform_expression (
yap::expression<
yap::expr_kind::plus,
bh::tuple<
yap::expression<
yap::expr_kind::multiplies,
bh::tuple<
Expr1,
Expr2
>
>,
Expr3
>
> const & expr
) {
return naxpy(
evaluate(expr.left().left()),
evaluate(expr.left().right()),
evaluate(expr.right())
);
}
}
term<user::number> a{{1.0}};
term<user::number> x{{42.0}};
term<user::number> y{{3.0}};
user::number eval_as_yap_expr (
decltype((a * x + y) * (a * x + y) + (a * x + y)) & expr
) {
return yap::evaluate(expr);
}
user::number eval_as_yap_expr_4x (
decltype(
(a * x + y) * (a * x + y) + (a * x + y) +
(a * x + y) * (a * x + y) + (a * x + y) +
(a * x + y) * (a * x + y) + (a * x + y) +
(a * x + y) * (a * x + y) + (a * x + y)
) & expr
) {
return yap::evaluate(expr);
}
user::number eval_as_cpp_expr (user::number a, user::number x, user::number y)
{
return (a * x + y) * (a * x + y) + (a * x + y);
}
user::number eval_as_cpp_expr_4x (user::number a, user::number x, user::number y)
{
return
(a * x + y) * (a * x + y) + (a * x + y) +
(a * x + y) * (a * x + y) + (a * x + y) +
(a * x + y) * (a * x + y) + (a * x + y) +
(a * x + y) * (a * x + y) + (a * x + y);
}
int main ()
{
auto expr = (a * x + y) * (a * x + y) + (a * x + y);
user::number result_1 = eval_as_yap_expr(expr);
user::number result_2 =
eval_as_cpp_expr(yap::value(a), yap::value(x), yap::value(y));
(void)result_1;
(void)result_2;
return 0;
}