/Src/Dependencies/Boost/libs/phoenix/example/parallel_for.cpp

http://hadesmem.googlecode.com/ · C++ · 239 lines · 201 code · 30 blank · 8 comment · 5 complexity · c84b62e3308bb5e6641827ad0c1ba94f MD5 · raw file

  1. #include <boost/phoenix.hpp>
  2. struct omp_for_eval
  3. {
  4. typedef void result_type;
  5. template <typename Init, typename Cond, typename Step, typename Do, typename Context>
  6. result_type
  7. operator()(
  8. Init const& init
  9. , Cond const& cond
  10. , Step const& step
  11. , Do const& do_
  12. , Context & ctx
  13. ) const
  14. {
  15. #pragma omp parallel
  16. for(
  17. boost::phoenix::eval(init, ctx);
  18. boost::phoenix::eval(cond, ctx);
  19. boost::phoenix::eval(step, ctx)
  20. )
  21. {
  22. boost::phoenix::eval(do_, ctx);
  23. }
  24. }
  25. };
  26. ////////////////////////////////////////////////////////////////////////////////
  27. // Define new custom expression
  28. BOOST_PHOENIX_DEFINE_EXPRESSION(
  29. (omp_for)
  30. , (boost::phoenix::meta_grammar) // Cond
  31. (boost::phoenix::meta_grammar) // Init
  32. (boost::phoenix::meta_grammar) // Step
  33. (boost::phoenix::meta_grammar) // Do
  34. )
  35. namespace boost { namespace phoenix
  36. {
  37. template <>
  38. struct default_actions::when< ::rule::omp_for>
  39. : boost::phoenix::call< ::omp_for_eval>
  40. {};
  41. }}
  42. template <typename Init, typename Cond, typename Step>
  43. struct omp_for_gen
  44. {
  45. omp_for_gen(Init const& init, Cond const& cond, Step const& step)
  46. : init(init), cond(cond), step(step) {}
  47. template <typename Do>
  48. typename result_of::make_omp_for<Init, Cond, Step, Do>::type const
  49. operator[](Do const& do_) const
  50. {
  51. return make_omp_for(init, cond, step, do_);
  52. }
  53. Init init;
  54. Cond cond;
  55. Step step;
  56. };
  57. template <typename Init, typename Cond, typename Step>
  58. inline
  59. omp_for_gen<Init, Cond, Step> const
  60. omp_for(Init const& init, Cond const& cond, Step const& step)
  61. {
  62. return omp_for_gen<Init, Cond, Step>(init, cond, step);
  63. }
  64. ////////////////////////////////////////////////////////////////////////////////
  65. ////////////////////////////////////////////////////////////////////////////////
  66. // Define new evaluation scheme
  67. struct parallel_actions
  68. {
  69. template <typename Rule>
  70. struct when
  71. : boost::phoenix::default_actions::when<Rule>
  72. {};
  73. };
  74. template <>
  75. struct parallel_actions::when<boost::phoenix::rule::for_>
  76. : boost::phoenix::call<omp_for_eval>
  77. {};
  78. // Doing the same as actor<Expr>::operator
  79. template <typename Expr, typename A0, typename A1, typename A2>
  80. typename boost::phoenix::result_of::eval<
  81. Expr const &
  82. , typename boost::phoenix::result_of::make_context<
  83. typename boost::phoenix::result_of::make_env<
  84. Expr const *
  85. , A0 &
  86. , A1 &
  87. , A2 &
  88. >::type
  89. , parallel_actions
  90. >::type
  91. >::type
  92. parallel_eval(Expr & expr, A0 & a0, A1 & a1, A2 & a2)
  93. {
  94. Expr const * this_ = boost::addressof(expr);
  95. return
  96. boost::phoenix::eval(
  97. expr
  98. , boost::phoenix::make_context(
  99. boost::phoenix::make_env(this_, a0, a1, a2)
  100. , parallel_actions()
  101. )
  102. );
  103. }
  104. // changing evaluation mechanism on the fly
  105. BOOST_PHOENIX_DEFINE_EXPRESSION(
  106. (parallel)
  107. , (boost::phoenix::meta_grammar)
  108. )
  109. namespace boost { namespace phoenix
  110. {
  111. template <>
  112. struct default_actions::when< ::rule::parallel>
  113. : proto::call<
  114. evaluator(
  115. proto::_child0
  116. , functional::make_context(
  117. _env
  118. , parallel_actions()
  119. )
  120. , unused()//mpl::void_()
  121. )
  122. >
  123. {};
  124. }}
  125. template <typename Expr>
  126. typename result_of::make_parallel<Expr>::type
  127. parallel(Expr const & expr)
  128. {
  129. return make_parallel(expr);
  130. }
  131. ////////////////////////////////////////////////////////////////////////////////
  132. #include <vector>
  133. #include <iostream>
  134. int main()
  135. {
  136. using boost::phoenix::arg_names::_1;
  137. using boost::phoenix::arg_names::_2;
  138. using boost::phoenix::arg_names::_3;
  139. using boost::phoenix::local_names::_a;
  140. using boost::phoenix::local_names::_b;
  141. using boost::phoenix::local_names::_c;
  142. using boost::phoenix::let;
  143. using boost::phoenix::bind;
  144. using boost::phoenix::lambda;
  145. using boost::phoenix::nothing;
  146. const int NUM = 1;
  147. {
  148. std::vector<int> a(NUM, 1);
  149. std::vector<int> b(NUM, 2);
  150. std::vector<int> c(NUM, 0);
  151. (
  152. let(_a = begin(_1), _b = begin(_2), _c = begin(_3))
  153. [
  154. for_(nothing, _a != end(_1), (++_a, ++_b, ++_c))
  155. [
  156. *_c = *_a + *_b
  157. ]
  158. ]
  159. , std::cout << accumulate(_3, 0) << "\n"
  160. )(a, b, c);
  161. }
  162. {
  163. std::vector<int> a(NUM, 1);
  164. std::vector<int> b(NUM, 2);
  165. std::vector<int> c(NUM, 0);
  166. (
  167. let(_a = begin(_1), _b = begin(_2), _c = begin(_3))
  168. [
  169. omp_for(nothing, _a != end(_1), (++_a, ++_b, ++_c))
  170. [
  171. *_c = *_a + *_b
  172. ]
  173. , std::cout << accumulate(_3, 0) << "\n"
  174. ]
  175. )(a, b, c);
  176. }
  177. {
  178. std::vector<int> a(NUM, 1);
  179. std::vector<int> b(NUM, 2);
  180. std::vector<int> c(NUM, 0);
  181. parallel_eval(
  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. , std::cout << accumulate(_3, 0) << "\n"
  189. ]
  190. , a, b, c);
  191. }
  192. {
  193. std::vector<int> a(NUM, 1);
  194. std::vector<int> b(NUM, 2);
  195. std::vector<int> c(NUM, 0);
  196. (
  197. let(_a = begin(_1), _b = begin(_2), _c = begin(_3))
  198. [
  199. parallel(
  200. for_(nothing, _a != end(_1), (++_a, ++_b, ++_c))
  201. [
  202. *_c = *_a + *_b
  203. ]
  204. )
  205. ]
  206. , std::cout << accumulate(_3, 0) << "\n"
  207. )(a, b, c);
  208. }
  209. }