]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/phoenix/example/parallel_for.cpp
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / boost / libs / phoenix / example / parallel_for.cpp
1 /*=============================================================================
2 Copyright (c) 2001-2007 Joel de Guzman
3
4 Distributed under the Boost Software License, Version 1.0. (See accompanying
5 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 ==============================================================================*/
7
8 #include <boost/phoenix.hpp>
9
10 struct omp_for_eval
11 {
12 typedef void result_type;
13
14 template <typename Init, typename Cond, typename Step, typename Do, typename Context>
15 result_type
16 operator()(
17 Init const& init
18 , Cond const& cond
19 , Step const& step
20 , Do const& do_
21 , Context & ctx
22 ) const
23 {
24 #pragma omp parallel
25 for(
26 boost::phoenix::eval(init, ctx);
27 boost::phoenix::eval(cond, ctx);
28 boost::phoenix::eval(step, ctx)
29 )
30 {
31 boost::phoenix::eval(do_, ctx);
32 }
33 }
34 };
35
36
37 ////////////////////////////////////////////////////////////////////////////////
38 // Define new custom expression
39 BOOST_PHOENIX_DEFINE_EXPRESSION(
40 (omp_for)
41 , (boost::phoenix::meta_grammar) // Cond
42 (boost::phoenix::meta_grammar) // Init
43 (boost::phoenix::meta_grammar) // Step
44 (boost::phoenix::meta_grammar) // Do
45 )
46
47 namespace boost { namespace phoenix
48 {
49 template <>
50 struct default_actions::when< ::rule::omp_for>
51 : boost::phoenix::call< ::omp_for_eval>
52 {};
53 }}
54
55 template <typename Init, typename Cond, typename Step>
56 struct omp_for_gen
57 {
58 omp_for_gen(Init const& init, Cond const& cond, Step const& step)
59 : init(init), cond(cond), step(step) {}
60
61 template <typename Do>
62 typename result_of::make_omp_for<Init, Cond, Step, Do>::type const
63 operator[](Do const& do_) const
64 {
65 return make_omp_for(init, cond, step, do_);
66 }
67
68 Init init;
69 Cond cond;
70 Step step;
71 };
72
73 template <typename Init, typename Cond, typename Step>
74 inline
75 omp_for_gen<Init, Cond, Step> const
76 omp_for(Init const& init, Cond const& cond, Step const& step)
77 {
78 return omp_for_gen<Init, Cond, Step>(init, cond, step);
79 }
80 ////////////////////////////////////////////////////////////////////////////////
81
82
83 ////////////////////////////////////////////////////////////////////////////////
84 // Define new evaluation scheme
85
86 struct parallel_actions
87 {
88 template <typename Rule>
89 struct when
90 : boost::phoenix::default_actions::when<Rule>
91 {};
92 };
93
94 template <>
95 struct parallel_actions::when<boost::phoenix::rule::for_>
96 : boost::phoenix::call<omp_for_eval>
97 {};
98
99 // Doing the same as actor<Expr>::operator
100 template <typename Expr, typename A0, typename A1, typename A2>
101 typename boost::phoenix::result_of::eval<
102 Expr const &
103 , typename boost::phoenix::result_of::make_context<
104 typename boost::phoenix::result_of::make_env<
105 Expr const *
106 , A0 &
107 , A1 &
108 , A2 &
109 >::type
110 , parallel_actions
111 >::type
112 >::type
113 parallel_eval(Expr & expr, A0 & a0, A1 & a1, A2 & a2)
114 {
115 Expr const * this_ = boost::addressof(expr);
116 return
117 boost::phoenix::eval(
118 expr
119 , boost::phoenix::make_context(
120 boost::phoenix::make_env(this_, a0, a1, a2)
121 , parallel_actions()
122 )
123 );
124 }
125
126 // changing evaluation mechanism on the fly
127 BOOST_PHOENIX_DEFINE_EXPRESSION(
128 (parallel)
129 , (boost::phoenix::meta_grammar)
130 )
131
132 namespace boost { namespace phoenix
133 {
134 template <>
135 struct default_actions::when< ::rule::parallel>
136 : proto::call<
137 evaluator(
138 proto::_child0
139 , functional::make_context(
140 _env
141 , parallel_actions()
142 )
143 , unused()//mpl::void_()
144 )
145 >
146 {};
147 }}
148
149 template <typename Expr>
150 typename result_of::make_parallel<Expr>::type
151 parallel(Expr const & expr)
152 {
153 return make_parallel(expr);
154 }
155 ////////////////////////////////////////////////////////////////////////////////
156
157
158 #include <vector>
159 #include <iostream>
160
161 int main()
162 {
163 using boost::phoenix::arg_names::_1;
164 using boost::phoenix::arg_names::_2;
165 using boost::phoenix::arg_names::_3;
166 using boost::phoenix::local_names::_a;
167 using boost::phoenix::local_names::_b;
168 using boost::phoenix::local_names::_c;
169 using boost::phoenix::let;
170 using boost::phoenix::bind;
171 using boost::phoenix::lambda;
172 using boost::phoenix::nothing;
173
174 const int NUM = 1;
175
176 {
177 std::vector<int> a(NUM, 1);
178 std::vector<int> b(NUM, 2);
179 std::vector<int> c(NUM, 0);
180
181 (
182 let(_a = begin(_1), _b = begin(_2), _c = begin(_3))
183 [
184 for_(nothing, _a != end(_1), (++_a, ++_b, ++_c))
185 [
186 *_c = *_a + *_b
187 ]
188 ]
189 , std::cout << accumulate(_3, 0) << "\n"
190 )(a, b, c);
191 }
192
193 {
194 std::vector<int> a(NUM, 1);
195 std::vector<int> b(NUM, 2);
196 std::vector<int> c(NUM, 0);
197
198 (
199 let(_a = begin(_1), _b = begin(_2), _c = begin(_3))
200 [
201 omp_for(nothing, _a != end(_1), (++_a, ++_b, ++_c))
202 [
203 *_c = *_a + *_b
204 ]
205 , std::cout << accumulate(_3, 0) << "\n"
206 ]
207 )(a, b, c);
208 }
209
210 {
211 std::vector<int> a(NUM, 1);
212 std::vector<int> b(NUM, 2);
213 std::vector<int> c(NUM, 0);
214
215 parallel_eval(
216 let(_a = begin(_1), _b = begin(_2), _c = begin(_3))
217 [
218 for_(nothing, _a != end(_1), (++_a, ++_b, ++_c))
219 [
220 *_c = *_a + *_b
221 ]
222 , std::cout << accumulate(_3, 0) << "\n"
223 ]
224 , a, b, c);
225 }
226
227 {
228 std::vector<int> a(NUM, 1);
229 std::vector<int> b(NUM, 2);
230 std::vector<int> c(NUM, 0);
231
232 (
233 let(_a = begin(_1), _b = begin(_2), _c = begin(_3))
234 [
235 parallel(
236 for_(nothing, _a != end(_1), (++_a, ++_b, ++_c))
237 [
238 *_c = *_a + *_b
239 ]
240 )
241 ]
242 , std::cout << accumulate(_3, 0) << "\n"
243 )(a, b, c);
244 }
245 }