summaryrefslogtreecommitdiffstats
path: root/src/boost/libs/yap/perf/code_gen_samples.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/boost/libs/yap/perf/code_gen_samples.cpp')
-rw-r--r--src/boost/libs/yap/perf/code_gen_samples.cpp99
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;
+}