File indexing completed on 2025-01-18 09:42:51
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019 #ifndef BOOST_NUMERIC_ODEINT_EXTERNAL_OPENMP_OPENMP_NESTED_ALGEBRA_HPP_INCLUDED
0020 #define BOOST_NUMERIC_ODEINT_EXTERNAL_OPENMP_OPENMP_NESTED_ALGEBRA_HPP_INCLUDED
0021
0022 #include <boost/assert.hpp>
0023 #include <boost/range.hpp>
0024 #include <boost/numeric/odeint/algebra/norm_result_type.hpp>
0025 #include <boost/numeric/odeint/util/n_ary_helper.hpp>
0026
0027 namespace boost {
0028 namespace numeric {
0029 namespace odeint {
0030
0031
0032
0033
0034
0035
0036 template< class InnerAlgebra >
0037 struct openmp_nested_algebra
0038 {
0039
0040 #if __cplusplus >= 201103L
0041
0042 #define BOOST_ODEINT_GEN_LOCAL(z, n, unused) \
0043 BOOST_ASSERT_MSG( len == boost::size(s ## n), "All nested state ranges must have the same size." ); \
0044 typename boost::range_iterator<S ## n>::type beg ## n = boost::begin(s ## n);
0045 #define BOOST_ODEINT_GEN_BODY(n) \
0046 const size_t len = boost::size(s0); \
0047 BOOST_PP_REPEAT(n, BOOST_ODEINT_GEN_LOCAL, ~) \
0048 _Pragma("omp parallel for schedule(runtime)") \
0049 for( size_t i = 0 ; i < len ; i++ ) \
0050 InnerAlgebra::for_each##n( \
0051 BOOST_PP_ENUM_BINARY_PARAMS(n, beg, [i] BOOST_PP_INTERCEPT) , \
0052 op \
0053 );
0054 BOOST_ODEINT_GEN_FOR_EACH(BOOST_ODEINT_GEN_BODY)
0055 #undef BOOST_ODEINT_GEN_BODY
0056 #undef BOOST_ODEINT_GEN_LOCAL
0057
0058 #else
0059
0060 template< class S0 , class Op > static void for_each1 ( S0 &s0 , Op op ) {
0061 const size_t len = boost::size(s0);
0062 typename boost::range_iterator<S0>::type beg0 = boost::begin(s0);
0063 #pragma omp parallel for schedule(runtime)
0064 for( size_t i = 0 ; i < len ; i++ ) InnerAlgebra::for_each1( beg0 [i] , op );
0065 }
0066 template< class S0 , class S1 , class Op > static void for_each2 ( S0 &s0 , S1 &s1 , Op op ) {
0067 const size_t len = boost::size(s0);
0068 typename boost::range_iterator<S0>::type beg0 = boost::begin(s0);
0069 typename boost::range_iterator<S1>::type beg1 = boost::begin(s1);
0070 #pragma omp parallel for schedule(runtime)
0071 for( size_t i = 0 ; i < len ; i++ ) InnerAlgebra::for_each2( beg0 [i] , beg1 [i] , op );
0072 }
0073 template< class S0 , class S1 , class S2 , class Op > static void for_each3 ( S0 &s0 , S1 &s1 , S2 &s2 , Op op ) {
0074 const size_t len = boost::size(s0);
0075 typename boost::range_iterator<S0>::type beg0 = boost::begin(s0);
0076 typename boost::range_iterator<S1>::type beg1 = boost::begin(s1);
0077 typename boost::range_iterator<S2>::type beg2 = boost::begin(s2);
0078 #pragma omp parallel for schedule(runtime)
0079 for( size_t i = 0 ; i < len ; i++ ) InnerAlgebra::for_each3( beg0 [i] , beg1 [i] , beg2 [i] , op );
0080 }
0081 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 ) {
0082 const size_t len = boost::size(s0);
0083 typename boost::range_iterator<S0>::type beg0 = boost::begin(s0);
0084 typename boost::range_iterator<S1>::type beg1 = boost::begin(s1);
0085 typename boost::range_iterator<S2>::type beg2 = boost::begin(s2);
0086 typename boost::range_iterator<S3>::type beg3 = boost::begin(s3);
0087 #pragma omp parallel for schedule(runtime)
0088 for( size_t i = 0 ; i < len ; i++ ) InnerAlgebra::for_each4( beg0 [i] , beg1 [i] , beg2 [i] , beg3 [i] , op );
0089 }
0090 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 ) {
0091 const size_t len = boost::size(s0);
0092 typename boost::range_iterator<S0>::type beg0 = boost::begin(s0);
0093 typename boost::range_iterator<S1>::type beg1 = boost::begin(s1);
0094 typename boost::range_iterator<S2>::type beg2 = boost::begin(s2);
0095 typename boost::range_iterator<S3>::type beg3 = boost::begin(s3);
0096 typename boost::range_iterator<S4>::type beg4 = boost::begin(s4);
0097 #pragma omp parallel for schedule(runtime)
0098 for( size_t i = 0 ; i < len ; i++ ) InnerAlgebra::for_each5( beg0 [i] , beg1 [i] , beg2 [i] , beg3 [i] , beg4 [i] , op );
0099 }
0100 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 ) {
0101 const size_t len = boost::size(s0);
0102 typename boost::range_iterator<S0>::type beg0 = boost::begin(s0);
0103 typename boost::range_iterator<S1>::type beg1 = boost::begin(s1);
0104 typename boost::range_iterator<S2>::type beg2 = boost::begin(s2);
0105 typename boost::range_iterator<S3>::type beg3 = boost::begin(s3);
0106 typename boost::range_iterator<S4>::type beg4 = boost::begin(s4);
0107 typename boost::range_iterator<S5>::type beg5 = boost::begin(s5);
0108 #pragma omp parallel for schedule(runtime)
0109 for( size_t i = 0 ; i < len ; i++ ) InnerAlgebra::for_each6( beg0 [i] , beg1 [i] , beg2 [i] , beg3 [i] , beg4 [i] , beg5 [i] , op );
0110 }
0111 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 ) {
0112 const size_t len = boost::size(s0);
0113 typename boost::range_iterator<S0>::type beg0 = boost::begin(s0);
0114 typename boost::range_iterator<S1>::type beg1 = boost::begin(s1);
0115 typename boost::range_iterator<S2>::type beg2 = boost::begin(s2);
0116 typename boost::range_iterator<S3>::type beg3 = boost::begin(s3);
0117 typename boost::range_iterator<S4>::type beg4 = boost::begin(s4);
0118 typename boost::range_iterator<S5>::type beg5 = boost::begin(s5);
0119 typename boost::range_iterator<S6>::type beg6 = boost::begin(s6);
0120 #pragma omp parallel for schedule(runtime)
0121 for( size_t i = 0 ; i < len ; i++ ) InnerAlgebra::for_each7( beg0 [i] , beg1 [i] , beg2 [i] , beg3 [i] , beg4 [i] , beg5 [i] , beg6 [i] , op );
0122 }
0123 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 ) {
0124 const size_t len = boost::size(s0);
0125 typename boost::range_iterator<S0>::type beg0 = boost::begin(s0);
0126 typename boost::range_iterator<S1>::type beg1 = boost::begin(s1);
0127 typename boost::range_iterator<S2>::type beg2 = boost::begin(s2);
0128 typename boost::range_iterator<S3>::type beg3 = boost::begin(s3);
0129 typename boost::range_iterator<S4>::type beg4 = boost::begin(s4);
0130 typename boost::range_iterator<S5>::type beg5 = boost::begin(s5);
0131 typename boost::range_iterator<S6>::type beg6 = boost::begin(s6);
0132 typename boost::range_iterator<S7>::type beg7 = boost::begin(s7);
0133 #pragma omp parallel for schedule(runtime)
0134 for( size_t i = 0 ; i < len ; i++ ) InnerAlgebra::for_each8( beg0 [i] , beg1 [i] , beg2 [i] , beg3 [i] , beg4 [i] , beg5 [i] , beg6 [i] , beg7 [i] , op );
0135 }
0136 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 ) {
0137 const size_t len = boost::size(s0);
0138 typename boost::range_iterator<S0>::type beg0 = boost::begin(s0);
0139 typename boost::range_iterator<S1>::type beg1 = boost::begin(s1);
0140 typename boost::range_iterator<S2>::type beg2 = boost::begin(s2);
0141 typename boost::range_iterator<S3>::type beg3 = boost::begin(s3);
0142 typename boost::range_iterator<S4>::type beg4 = boost::begin(s4);
0143 typename boost::range_iterator<S5>::type beg5 = boost::begin(s5);
0144 typename boost::range_iterator<S6>::type beg6 = boost::begin(s6);
0145 typename boost::range_iterator<S7>::type beg7 = boost::begin(s7);
0146 typename boost::range_iterator<S8>::type beg8 = boost::begin(s8);
0147 #pragma omp parallel for schedule(runtime)
0148 for( size_t i = 0 ; i < len ; i++ ) InnerAlgebra::for_each9( beg0 [i] , beg1 [i] , beg2 [i] , beg3 [i] , beg4 [i] , beg5 [i] , beg6 [i] , beg7 [i] , beg8 [i] , op );
0149 }
0150 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 ) {
0151 const size_t len = boost::size(s0);
0152 typename boost::range_iterator<S0>::type beg0 = boost::begin(s0);
0153 typename boost::range_iterator<S1>::type beg1 = boost::begin(s1);
0154 typename boost::range_iterator<S2>::type beg2 = boost::begin(s2);
0155 typename boost::range_iterator<S3>::type beg3 = boost::begin(s3);
0156 typename boost::range_iterator<S4>::type beg4 = boost::begin(s4);
0157 typename boost::range_iterator<S5>::type beg5 = boost::begin(s5);
0158 typename boost::range_iterator<S6>::type beg6 = boost::begin(s6);
0159 typename boost::range_iterator<S7>::type beg7 = boost::begin(s7);
0160 typename boost::range_iterator<S8>::type beg8 = boost::begin(s8);
0161 typename boost::range_iterator<S9>::type beg9 = boost::begin(s9);
0162 #pragma omp parallel for schedule(runtime)
0163 for( size_t i = 0 ; i < len ; i++ ) InnerAlgebra::for_each10( beg0 [i] , beg1 [i] , beg2 [i] , beg3 [i] , beg4 [i] , beg5 [i] , beg6 [i] , beg7 [i] , beg8 [i] , beg9 [i] , op );
0164 }
0165 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 ) {
0166 const size_t len = boost::size(s0);
0167 typename boost::range_iterator<S0>::type beg0 = boost::begin(s0);
0168 typename boost::range_iterator<S1>::type beg1 = boost::begin(s1);
0169 typename boost::range_iterator<S2>::type beg2 = boost::begin(s2);
0170 typename boost::range_iterator<S3>::type beg3 = boost::begin(s3);
0171 typename boost::range_iterator<S4>::type beg4 = boost::begin(s4);
0172 typename boost::range_iterator<S5>::type beg5 = boost::begin(s5);
0173 typename boost::range_iterator<S6>::type beg6 = boost::begin(s6);
0174 typename boost::range_iterator<S7>::type beg7 = boost::begin(s7);
0175 typename boost::range_iterator<S8>::type beg8 = boost::begin(s8);
0176 typename boost::range_iterator<S9>::type beg9 = boost::begin(s9);
0177 typename boost::range_iterator<S10>::type beg10 = boost::begin(s10);
0178 #pragma omp parallel for schedule(runtime)
0179 for( size_t i = 0 ; i < len ; i++ ) InnerAlgebra::for_each11( beg0 [i] , beg1 [i] , beg2 [i] , beg3 [i] , beg4 [i] , beg5 [i] , beg6 [i] , beg7 [i] , beg8 [i] , beg9 [i] , beg10 [i] , op );
0180 }
0181 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 ) {
0182 const size_t len = boost::size(s0);
0183 typename boost::range_iterator<S0>::type beg0 = boost::begin(s0);
0184 typename boost::range_iterator<S1>::type beg1 = boost::begin(s1);
0185 typename boost::range_iterator<S2>::type beg2 = boost::begin(s2);
0186 typename boost::range_iterator<S3>::type beg3 = boost::begin(s3);
0187 typename boost::range_iterator<S4>::type beg4 = boost::begin(s4);
0188 typename boost::range_iterator<S5>::type beg5 = boost::begin(s5);
0189 typename boost::range_iterator<S6>::type beg6 = boost::begin(s6);
0190 typename boost::range_iterator<S7>::type beg7 = boost::begin(s7);
0191 typename boost::range_iterator<S8>::type beg8 = boost::begin(s8);
0192 typename boost::range_iterator<S9>::type beg9 = boost::begin(s9);
0193 typename boost::range_iterator<S10>::type beg10 = boost::begin(s10);
0194 typename boost::range_iterator<S11>::type beg11 = boost::begin(s11);
0195 #pragma omp parallel for schedule(runtime)
0196 for( size_t i = 0 ; i < len ; i++ ) InnerAlgebra::for_each12( beg0 [i] , beg1 [i] , beg2 [i] , beg3 [i] , beg4 [i] , beg5 [i] , beg6 [i] , beg7 [i] , beg8 [i] , beg9 [i] , beg10 [i] , beg11 [i] , op );
0197 }
0198 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 ) {
0199 const size_t len = boost::size(s0);
0200 typename boost::range_iterator<S0>::type beg0 = boost::begin(s0);
0201 typename boost::range_iterator<S1>::type beg1 = boost::begin(s1);
0202 typename boost::range_iterator<S2>::type beg2 = boost::begin(s2);
0203 typename boost::range_iterator<S3>::type beg3 = boost::begin(s3);
0204 typename boost::range_iterator<S4>::type beg4 = boost::begin(s4);
0205 typename boost::range_iterator<S5>::type beg5 = boost::begin(s5);
0206 typename boost::range_iterator<S6>::type beg6 = boost::begin(s6);
0207 typename boost::range_iterator<S7>::type beg7 = boost::begin(s7);
0208 typename boost::range_iterator<S8>::type beg8 = boost::begin(s8);
0209 typename boost::range_iterator<S9>::type beg9 = boost::begin(s9);
0210 typename boost::range_iterator<S10>::type beg10 = boost::begin(s10);
0211 typename boost::range_iterator<S11>::type beg11 = boost::begin(s11);
0212 typename boost::range_iterator<S12>::type beg12 = boost::begin(s12);
0213 #pragma omp parallel for schedule(runtime)
0214 for( size_t i = 0 ; i < len ; i++ ) InnerAlgebra::for_each13( 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] , op );
0215 }
0216 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 ) {
0217 const size_t len = boost::size(s0);
0218 typename boost::range_iterator<S0>::type beg0 = boost::begin(s0);
0219 typename boost::range_iterator<S1>::type beg1 = boost::begin(s1);
0220 typename boost::range_iterator<S2>::type beg2 = boost::begin(s2);
0221 typename boost::range_iterator<S3>::type beg3 = boost::begin(s3);
0222 typename boost::range_iterator<S4>::type beg4 = boost::begin(s4);
0223 typename boost::range_iterator<S5>::type beg5 = boost::begin(s5);
0224 typename boost::range_iterator<S6>::type beg6 = boost::begin(s6);
0225 typename boost::range_iterator<S7>::type beg7 = boost::begin(s7);
0226 typename boost::range_iterator<S8>::type beg8 = boost::begin(s8);
0227 typename boost::range_iterator<S9>::type beg9 = boost::begin(s9);
0228 typename boost::range_iterator<S10>::type beg10 = boost::begin(s10);
0229 typename boost::range_iterator<S11>::type beg11 = boost::begin(s11);
0230 typename boost::range_iterator<S12>::type beg12 = boost::begin(s12);
0231 typename boost::range_iterator<S13>::type beg13 = boost::begin(s13);
0232 #pragma omp parallel for schedule(runtime)
0233 for( size_t i = 0 ; i < len ; i++ ) InnerAlgebra::for_each14( 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] , op );
0234 }
0235 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 ) {
0236 const size_t len = boost::size(s0);
0237 typename boost::range_iterator<S0>::type beg0 = boost::begin(s0);
0238 typename boost::range_iterator<S1>::type beg1 = boost::begin(s1);
0239 typename boost::range_iterator<S2>::type beg2 = boost::begin(s2);
0240 typename boost::range_iterator<S3>::type beg3 = boost::begin(s3);
0241 typename boost::range_iterator<S4>::type beg4 = boost::begin(s4);
0242 typename boost::range_iterator<S5>::type beg5 = boost::begin(s5);
0243 typename boost::range_iterator<S6>::type beg6 = boost::begin(s6);
0244 typename boost::range_iterator<S7>::type beg7 = boost::begin(s7);
0245 typename boost::range_iterator<S8>::type beg8 = boost::begin(s8);
0246 typename boost::range_iterator<S9>::type beg9 = boost::begin(s9);
0247 typename boost::range_iterator<S10>::type beg10 = boost::begin(s10);
0248 typename boost::range_iterator<S11>::type beg11 = boost::begin(s11);
0249 typename boost::range_iterator<S12>::type beg12 = boost::begin(s12);
0250 typename boost::range_iterator<S13>::type beg13 = boost::begin(s13);
0251 typename boost::range_iterator<S14>::type beg14 = boost::begin(s14);
0252 #pragma omp parallel for schedule(runtime)
0253 for( size_t i = 0 ; i < len ; i++ ) InnerAlgebra::for_each15( 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] , op );
0254 }
0255
0256 #endif
0257
0258
0259 template< class NestedState >
0260 static typename norm_result_type< typename NestedState::value_type >::type norm_inf( const NestedState &s )
0261 {
0262 typedef typename boost::range_iterator<const NestedState>::type iterator;
0263 typedef typename std::iterator_traits<iterator>::value_type value_type;
0264 typedef typename norm_result_type<value_type>::type result_type;
0265 result_type init = static_cast< result_type >( 0 );
0266 const size_t len = boost::size(s);
0267 iterator beg = boost::begin(s);
0268 # pragma omp parallel for reduction(max: init) schedule(dynamic)
0269 for( size_t i = 0 ; i < len ; i++ )
0270 init = (std::max)( init , InnerAlgebra::norm_inf( beg[i] ) );
0271 return init;
0272 }
0273
0274 };
0275
0276
0277 }
0278 }
0279 }
0280
0281 #endif