diff options
Diffstat (limited to 'src/boost/libs/yap/perf/code_gen_samples.cpp')
-rw-r--r-- | src/boost/libs/yap/perf/code_gen_samples.cpp | 99 |
1 files changed, 99 insertions, 0 deletions
diff --git a/src/boost/libs/yap/perf/code_gen_samples.cpp b/src/boost/libs/yap/perf/code_gen_samples.cpp new file mode 100644 index 000000000..3df71b1cb --- /dev/null +++ b/src/boost/libs/yap/perf/code_gen_samples.cpp @@ -0,0 +1,99 @@ +// 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; +} |