openmp_range_algebra.hpp 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276
  1. /*
  2. [auto_generated]
  3. boost/numeric/odeint/external/openmp/openmp_range_algebra.hpp
  4. [begin_description]
  5. Range algebra for OpenMP.
  6. [end_description]
  7. Copyright 2013 Karsten Ahnert
  8. Copyright 2013 Mario Mulansky
  9. Copyright 2013 Pascal Germroth
  10. Distributed under the Boost Software License, Version 1.0.
  11. (See accompanying file LICENSE_1_0.txt or
  12. copy at http://www.boost.org/LICENSE_1_0.txt)
  13. */
  14. #ifndef BOOST_NUMERIC_ODEINT_EXTERNAL_OPENMP_OPENMP_RANGE_ALGEBRA_HPP_INCLUDED
  15. #define BOOST_NUMERIC_ODEINT_EXTERNAL_OPENMP_OPENMP_RANGE_ALGEBRA_HPP_INCLUDED
  16. #include <boost/assert.hpp>
  17. #include <boost/range.hpp>
  18. #include <boost/numeric/odeint/algebra/norm_result_type.hpp>
  19. #include <boost/numeric/odeint/util/n_ary_helper.hpp>
  20. namespace boost {
  21. namespace numeric {
  22. namespace odeint {
  23. /** \brief OpenMP-parallelized range algebra.
  24. *
  25. * State must be a model of Random Access Range.
  26. */
  27. struct openmp_range_algebra
  28. {
  29. #if __cplusplus >= 201103L // C++11 supports _Pragma
  30. #define BOOST_ODEINT_GEN_LOCAL(z, n, unused) \
  31. BOOST_ASSERT_MSG( len == boost::size(s ## n), "All state ranges must have the same size." ); \
  32. typename boost::range_iterator<S ## n>::type beg ## n = boost::begin(s ## n);
  33. #define BOOST_ODEINT_GEN_BODY(n) \
  34. const size_t len = boost::size(s0); \
  35. BOOST_PP_REPEAT(n, BOOST_ODEINT_GEN_LOCAL, ~) \
  36. _Pragma("omp parallel for schedule(runtime)") \
  37. for( size_t i = 0 ; i < len ; i++ ) \
  38. op( BOOST_PP_ENUM_BINARY_PARAMS(n, beg, [i] BOOST_PP_INTERCEPT) );
  39. BOOST_ODEINT_GEN_FOR_EACH(BOOST_ODEINT_GEN_BODY)
  40. #undef BOOST_ODEINT_GEN_BODY
  41. #undef BOOST_ODEINT_GEN_LOCAL
  42. #else
  43. template< class S0 , class Op > static void for_each1 ( S0 &s0 , Op op ) {
  44. const size_t len = boost::size(s0);
  45. typename boost::range_iterator<S0>::type beg0 = boost::begin(s0);
  46. #pragma omp parallel for schedule(runtime)
  47. for( size_t i = 0 ; i < len ; i++ ) op( beg0 [i] );
  48. }
  49. template< class S0 , class S1 , class Op > static void for_each2 ( S0 &s0 , S1 &s1 , Op op ) {
  50. const size_t len = boost::size(s0);
  51. typename boost::range_iterator<S0>::type beg0 = boost::begin(s0);
  52. typename boost::range_iterator<S1>::type beg1 = boost::begin(s1);
  53. #pragma omp parallel for schedule(runtime)
  54. for( size_t i = 0 ; i < len ; i++ ) op( beg0 [i] , beg1 [i] );
  55. }
  56. template< class S0 , class S1 , class S2 , class Op > static void for_each3 ( S0 &s0 , S1 &s1 , S2 &s2 , Op op ) {
  57. const size_t len = boost::size(s0);
  58. typename boost::range_iterator<S0>::type beg0 = boost::begin(s0);
  59. typename boost::range_iterator<S1>::type beg1 = boost::begin(s1);
  60. typename boost::range_iterator<S2>::type beg2 = boost::begin(s2);
  61. #pragma omp parallel for schedule(runtime)
  62. for( size_t i = 0 ; i < len ; i++ ) op( beg0 [i] , beg1 [i] , beg2 [i] );
  63. }
  64. template< class S0 , class S1 , class S2 , class S3 , class Op > static void for_each4 ( S0 &s0 , S1 &s1 , S2 &s2 , S3 &s3 , Op op ) {
  65. const size_t len = boost::size(s0);
  66. typename boost::range_iterator<S0>::type beg0 = boost::begin(s0);
  67. typename boost::range_iterator<S1>::type beg1 = boost::begin(s1);
  68. typename boost::range_iterator<S2>::type beg2 = boost::begin(s2);
  69. typename boost::range_iterator<S3>::type beg3 = boost::begin(s3);
  70. #pragma omp parallel for schedule(runtime)
  71. for( size_t i = 0 ; i < len ; i++ ) op( beg0 [i] , beg1 [i] , beg2 [i] , beg3 [i] );
  72. }
  73. template< class S0 , class S1 , class S2 , class S3 , class S4 , class Op > static void for_each5 ( S0 &s0 , S1 &s1 , S2 &s2 , S3 &s3 , S4 &s4 , Op op ) {
  74. const size_t len = boost::size(s0);
  75. typename boost::range_iterator<S0>::type beg0 = boost::begin(s0);
  76. typename boost::range_iterator<S1>::type beg1 = boost::begin(s1);
  77. typename boost::range_iterator<S2>::type beg2 = boost::begin(s2);
  78. typename boost::range_iterator<S3>::type beg3 = boost::begin(s3);
  79. typename boost::range_iterator<S4>::type beg4 = boost::begin(s4);
  80. #pragma omp parallel for schedule(runtime)
  81. for( size_t i = 0 ; i < len ; i++ ) op( beg0 [i] , beg1 [i] , beg2 [i] , beg3 [i] , beg4 [i] );
  82. }
  83. template< class S0 , class S1 , class S2 , class S3 , class S4 , class S5 , class Op > static void for_each6 ( S0 &s0 , S1 &s1 , S2 &s2 , S3 &s3 , S4 &s4 , S5 &s5 , Op op ) {
  84. const size_t len = boost::size(s0);
  85. typename boost::range_iterator<S0>::type beg0 = boost::begin(s0);
  86. typename boost::range_iterator<S1>::type beg1 = boost::begin(s1);
  87. typename boost::range_iterator<S2>::type beg2 = boost::begin(s2);
  88. typename boost::range_iterator<S3>::type beg3 = boost::begin(s3);
  89. typename boost::range_iterator<S4>::type beg4 = boost::begin(s4);
  90. typename boost::range_iterator<S5>::type beg5 = boost::begin(s5);
  91. #pragma omp parallel for schedule(runtime)
  92. for( size_t i = 0 ; i < len ; i++ ) op( beg0 [i] , beg1 [i] , beg2 [i] , beg3 [i] , beg4 [i] , beg5 [i] );
  93. }
  94. template< class S0 , class S1 , class S2 , class S3 , class S4 , class S5 , class S6 , class Op > static void for_each7 ( S0 &s0 , S1 &s1 , S2 &s2 , S3 &s3 , S4 &s4 , S5 &s5 , S6 &s6 , Op op ) {
  95. const size_t len = boost::size(s0);
  96. typename boost::range_iterator<S0>::type beg0 = boost::begin(s0);
  97. typename boost::range_iterator<S1>::type beg1 = boost::begin(s1);
  98. typename boost::range_iterator<S2>::type beg2 = boost::begin(s2);
  99. typename boost::range_iterator<S3>::type beg3 = boost::begin(s3);
  100. typename boost::range_iterator<S4>::type beg4 = boost::begin(s4);
  101. typename boost::range_iterator<S5>::type beg5 = boost::begin(s5);
  102. typename boost::range_iterator<S6>::type beg6 = boost::begin(s6);
  103. #pragma omp parallel for schedule(runtime)
  104. for( size_t i = 0 ; i < len ; i++ ) op( beg0 [i] , beg1 [i] , beg2 [i] , beg3 [i] , beg4 [i] , beg5 [i] , beg6 [i] );
  105. }
  106. template< class S0 , class S1 , class S2 , class S3 , class S4 , class S5 , class S6 , class S7 , class Op > static void for_each8 ( S0 &s0 , S1 &s1 , S2 &s2 , S3 &s3 , S4 &s4 , S5 &s5 , S6 &s6 , S7 &s7 , Op op ) {
  107. const size_t len = boost::size(s0);
  108. typename boost::range_iterator<S0>::type beg0 = boost::begin(s0);
  109. typename boost::range_iterator<S1>::type beg1 = boost::begin(s1);
  110. typename boost::range_iterator<S2>::type beg2 = boost::begin(s2);
  111. typename boost::range_iterator<S3>::type beg3 = boost::begin(s3);
  112. typename boost::range_iterator<S4>::type beg4 = boost::begin(s4);
  113. typename boost::range_iterator<S5>::type beg5 = boost::begin(s5);
  114. typename boost::range_iterator<S6>::type beg6 = boost::begin(s6);
  115. typename boost::range_iterator<S7>::type beg7 = boost::begin(s7);
  116. #pragma omp parallel for schedule(runtime)
  117. for( size_t i = 0 ; i < len ; i++ ) op( beg0 [i] , beg1 [i] , beg2 [i] , beg3 [i] , beg4 [i] , beg5 [i] , beg6 [i] , beg7 [i] );
  118. }
  119. template< class S0 , class S1 , class S2 , class S3 , class S4 , class S5 , class S6 , class S7 , class S8 , class Op > static void for_each9 ( S0 &s0 , S1 &s1 , S2 &s2 , S3 &s3 , S4 &s4 , S5 &s5 , S6 &s6 , S7 &s7 , S8 &s8 , Op op ) {
  120. const size_t len = boost::size(s0);
  121. typename boost::range_iterator<S0>::type beg0 = boost::begin(s0);
  122. typename boost::range_iterator<S1>::type beg1 = boost::begin(s1);
  123. typename boost::range_iterator<S2>::type beg2 = boost::begin(s2);
  124. typename boost::range_iterator<S3>::type beg3 = boost::begin(s3);
  125. typename boost::range_iterator<S4>::type beg4 = boost::begin(s4);
  126. typename boost::range_iterator<S5>::type beg5 = boost::begin(s5);
  127. typename boost::range_iterator<S6>::type beg6 = boost::begin(s6);
  128. typename boost::range_iterator<S7>::type beg7 = boost::begin(s7);
  129. typename boost::range_iterator<S8>::type beg8 = boost::begin(s8);
  130. #pragma omp parallel for schedule(runtime)
  131. for( size_t i = 0 ; i < len ; i++ ) op( beg0 [i] , beg1 [i] , beg2 [i] , beg3 [i] , beg4 [i] , beg5 [i] , beg6 [i] , beg7 [i] , beg8 [i] );
  132. }
  133. template< class S0 , class S1 , class S2 , class S3 , class S4 , class S5 , class S6 , class S7 , class S8 , class S9 , class Op > static void for_each10 ( S0 &s0 , S1 &s1 , S2 &s2 , S3 &s3 , S4 &s4 , S5 &s5 , S6 &s6 , S7 &s7 , S8 &s8 , S9 &s9 , Op op ) {
  134. const size_t len = boost::size(s0);
  135. typename boost::range_iterator<S0>::type beg0 = boost::begin(s0);
  136. typename boost::range_iterator<S1>::type beg1 = boost::begin(s1);
  137. typename boost::range_iterator<S2>::type beg2 = boost::begin(s2);
  138. typename boost::range_iterator<S3>::type beg3 = boost::begin(s3);
  139. typename boost::range_iterator<S4>::type beg4 = boost::begin(s4);
  140. typename boost::range_iterator<S5>::type beg5 = boost::begin(s5);
  141. typename boost::range_iterator<S6>::type beg6 = boost::begin(s6);
  142. typename boost::range_iterator<S7>::type beg7 = boost::begin(s7);
  143. typename boost::range_iterator<S8>::type beg8 = boost::begin(s8);
  144. typename boost::range_iterator<S9>::type beg9 = boost::begin(s9);
  145. #pragma omp parallel for schedule(runtime)
  146. for( size_t i = 0 ; i < len ; i++ ) op( beg0 [i] , beg1 [i] , beg2 [i] , beg3 [i] , beg4 [i] , beg5 [i] , beg6 [i] , beg7 [i] , beg8 [i] , beg9 [i] );
  147. }
  148. template< class S0 , class S1 , class S2 , class S3 , class S4 , class S5 , class S6 , class S7 , class S8 , class S9 , class S10 , class Op > static void for_each11 ( S0 &s0 , S1 &s1 , S2 &s2 , S3 &s3 , S4 &s4 , S5 &s5 , S6 &s6 , S7 &s7 , S8 &s8 , S9 &s9 , S10 &s10 , Op op ) {
  149. const size_t len = boost::size(s0);
  150. typename boost::range_iterator<S0>::type beg0 = boost::begin(s0);
  151. typename boost::range_iterator<S1>::type beg1 = boost::begin(s1);
  152. typename boost::range_iterator<S2>::type beg2 = boost::begin(s2);
  153. typename boost::range_iterator<S3>::type beg3 = boost::begin(s3);
  154. typename boost::range_iterator<S4>::type beg4 = boost::begin(s4);
  155. typename boost::range_iterator<S5>::type beg5 = boost::begin(s5);
  156. typename boost::range_iterator<S6>::type beg6 = boost::begin(s6);
  157. typename boost::range_iterator<S7>::type beg7 = boost::begin(s7);
  158. typename boost::range_iterator<S8>::type beg8 = boost::begin(s8);
  159. typename boost::range_iterator<S9>::type beg9 = boost::begin(s9);
  160. typename boost::range_iterator<S10>::type beg10 = boost::begin(s10);
  161. #pragma omp parallel for schedule(runtime)
  162. for( size_t i = 0 ; i < len ; i++ ) op( beg0 [i] , beg1 [i] , beg2 [i] , beg3 [i] , beg4 [i] , beg5 [i] , beg6 [i] , beg7 [i] , beg8 [i] , beg9 [i] , beg10 [i] );
  163. }
  164. template< class S0 , class S1 , class S2 , class S3 , class S4 , class S5 , class S6 , class S7 , class S8 , class S9 , class S10 , class S11 , class Op > static void for_each12 ( S0 &s0 , S1 &s1 , S2 &s2 , S3 &s3 , S4 &s4 , S5 &s5 , S6 &s6 , S7 &s7 , S8 &s8 , S9 &s9 , S10 &s10 , S11 &s11 , Op op ) {
  165. const size_t len = boost::size(s0);
  166. typename boost::range_iterator<S0>::type beg0 = boost::begin(s0);
  167. typename boost::range_iterator<S1>::type beg1 = boost::begin(s1);
  168. typename boost::range_iterator<S2>::type beg2 = boost::begin(s2);
  169. typename boost::range_iterator<S3>::type beg3 = boost::begin(s3);
  170. typename boost::range_iterator<S4>::type beg4 = boost::begin(s4);
  171. typename boost::range_iterator<S5>::type beg5 = boost::begin(s5);
  172. typename boost::range_iterator<S6>::type beg6 = boost::begin(s6);
  173. typename boost::range_iterator<S7>::type beg7 = boost::begin(s7);
  174. typename boost::range_iterator<S8>::type beg8 = boost::begin(s8);
  175. typename boost::range_iterator<S9>::type beg9 = boost::begin(s9);
  176. typename boost::range_iterator<S10>::type beg10 = boost::begin(s10);
  177. typename boost::range_iterator<S11>::type beg11 = boost::begin(s11);
  178. #pragma omp parallel for schedule(runtime)
  179. for( size_t i = 0 ; i < len ; i++ ) op( beg0 [i] , beg1 [i] , beg2 [i] , beg3 [i] , beg4 [i] , beg5 [i] , beg6 [i] , beg7 [i] , beg8 [i] , beg9 [i] , beg10 [i] , beg11 [i] );
  180. }
  181. template< class S0 , class S1 , class S2 , class S3 , class S4 , class S5 , class S6 , class S7 , class S8 , class S9 , class S10 , class S11 , class S12 , class Op > static void for_each13 ( S0 &s0 , S1 &s1 , S2 &s2 , S3 &s3 , S4 &s4 , S5 &s5 , S6 &s6 , S7 &s7 , S8 &s8 , S9 &s9 , S10 &s10 , S11 &s11 , S12 &s12 , Op op ) {
  182. const size_t len = boost::size(s0);
  183. typename boost::range_iterator<S0>::type beg0 = boost::begin(s0);
  184. typename boost::range_iterator<S1>::type beg1 = boost::begin(s1);
  185. typename boost::range_iterator<S2>::type beg2 = boost::begin(s2);
  186. typename boost::range_iterator<S3>::type beg3 = boost::begin(s3);
  187. typename boost::range_iterator<S4>::type beg4 = boost::begin(s4);
  188. typename boost::range_iterator<S5>::type beg5 = boost::begin(s5);
  189. typename boost::range_iterator<S6>::type beg6 = boost::begin(s6);
  190. typename boost::range_iterator<S7>::type beg7 = boost::begin(s7);
  191. typename boost::range_iterator<S8>::type beg8 = boost::begin(s8);
  192. typename boost::range_iterator<S9>::type beg9 = boost::begin(s9);
  193. typename boost::range_iterator<S10>::type beg10 = boost::begin(s10);
  194. typename boost::range_iterator<S11>::type beg11 = boost::begin(s11);
  195. typename boost::range_iterator<S12>::type beg12 = boost::begin(s12);
  196. #pragma omp parallel for schedule(runtime)
  197. for( size_t i = 0 ; i < len ; i++ ) op( beg0 [i] , beg1 [i] , beg2 [i] , beg3 [i] , beg4 [i] , beg5 [i] , beg6 [i] , beg7 [i] , beg8 [i] , beg9 [i] , beg10 [i] , beg11 [i] , beg12 [i] );
  198. }
  199. template< class S0 , class S1 , class S2 , class S3 , class S4 , class S5 , class S6 , class S7 , class S8 , class S9 , class S10 , class S11 , class S12 , class S13 , class Op > static void for_each14 ( S0 &s0 , S1 &s1 , S2 &s2 , S3 &s3 , S4 &s4 , S5 &s5 , S6 &s6 , S7 &s7 , S8 &s8 , S9 &s9 , S10 &s10 , S11 &s11 , S12 &s12 , S13 &s13 , Op op ) {
  200. const size_t len = boost::size(s0);
  201. typename boost::range_iterator<S0>::type beg0 = boost::begin(s0);
  202. typename boost::range_iterator<S1>::type beg1 = boost::begin(s1);
  203. typename boost::range_iterator<S2>::type beg2 = boost::begin(s2);
  204. typename boost::range_iterator<S3>::type beg3 = boost::begin(s3);
  205. typename boost::range_iterator<S4>::type beg4 = boost::begin(s4);
  206. typename boost::range_iterator<S5>::type beg5 = boost::begin(s5);
  207. typename boost::range_iterator<S6>::type beg6 = boost::begin(s6);
  208. typename boost::range_iterator<S7>::type beg7 = boost::begin(s7);
  209. typename boost::range_iterator<S8>::type beg8 = boost::begin(s8);
  210. typename boost::range_iterator<S9>::type beg9 = boost::begin(s9);
  211. typename boost::range_iterator<S10>::type beg10 = boost::begin(s10);
  212. typename boost::range_iterator<S11>::type beg11 = boost::begin(s11);
  213. typename boost::range_iterator<S12>::type beg12 = boost::begin(s12);
  214. typename boost::range_iterator<S13>::type beg13 = boost::begin(s13);
  215. #pragma omp parallel for schedule(runtime)
  216. for( size_t i = 0 ; i < len ; i++ ) op( beg0 [i] , beg1 [i] , beg2 [i] , beg3 [i] , beg4 [i] , beg5 [i] , beg6 [i] , beg7 [i] , beg8 [i] , beg9 [i] , beg10 [i] , beg11 [i] , beg12 [i] , beg13 [i] );
  217. }
  218. template< class S0 , class S1 , class S2 , class S3 , class S4 , class S5 , class S6 , class S7 , class S8 , class S9 , class S10 , class S11 , class S12 , class S13 , class S14 , class Op > static void for_each15 ( S0 &s0 , S1 &s1 , S2 &s2 , S3 &s3 , S4 &s4 , S5 &s5 , S6 &s6 , S7 &s7 , S8 &s8 , S9 &s9 , S10 &s10 , S11 &s11 , S12 &s12 , S13 &s13 , S14 &s14 , Op op ) {
  219. const size_t len = boost::size(s0);
  220. typename boost::range_iterator<S0>::type beg0 = boost::begin(s0);
  221. typename boost::range_iterator<S1>::type beg1 = boost::begin(s1);
  222. typename boost::range_iterator<S2>::type beg2 = boost::begin(s2);
  223. typename boost::range_iterator<S3>::type beg3 = boost::begin(s3);
  224. typename boost::range_iterator<S4>::type beg4 = boost::begin(s4);
  225. typename boost::range_iterator<S5>::type beg5 = boost::begin(s5);
  226. typename boost::range_iterator<S6>::type beg6 = boost::begin(s6);
  227. typename boost::range_iterator<S7>::type beg7 = boost::begin(s7);
  228. typename boost::range_iterator<S8>::type beg8 = boost::begin(s8);
  229. typename boost::range_iterator<S9>::type beg9 = boost::begin(s9);
  230. typename boost::range_iterator<S10>::type beg10 = boost::begin(s10);
  231. typename boost::range_iterator<S11>::type beg11 = boost::begin(s11);
  232. typename boost::range_iterator<S12>::type beg12 = boost::begin(s12);
  233. typename boost::range_iterator<S13>::type beg13 = boost::begin(s13);
  234. typename boost::range_iterator<S14>::type beg14 = boost::begin(s14);
  235. #pragma omp parallel for schedule(runtime)
  236. for( size_t i = 0 ; i < len ; i++ ) op( beg0 [i] , beg1 [i] , beg2 [i] , beg3 [i] , beg4 [i] , beg5 [i] , beg6 [i] , beg7 [i] , beg8 [i] , beg9 [i] , beg10 [i] , beg11 [i] , beg12 [i] , beg13 [i] , beg14 [i] );
  237. }
  238. #endif
  239. template< class S >
  240. static typename norm_result_type< S >::type norm_inf( const S &s )
  241. {
  242. using std::max;
  243. using std::abs;
  244. typedef typename norm_result_type< S >::type result_type;
  245. result_type init = static_cast< result_type >( 0 );
  246. const size_t len = boost::size(s);
  247. typename boost::range_iterator<const S>::type beg = boost::begin(s);
  248. # pragma omp parallel for reduction(max: init) schedule(dynamic)
  249. for( size_t i = 0 ; i < len ; ++i )
  250. init = max( init , abs( beg[i] ) );
  251. return init;
  252. }
  253. };
  254. }
  255. }
  256. }
  257. #endif