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_STATE_HPP_INCLUDED
0020 #define BOOST_NUMERIC_ODEINT_EXTERNAL_OPENMP_OPENMP_STATE_HPP_INCLUDED
0021
0022 #include <omp.h>
0023 #include <vector>
0024 #include <algorithm>
0025 #include <boost/range/adaptor/sliced.hpp>
0026 #include <boost/numeric/odeint/util/copy.hpp>
0027 #include <boost/numeric/odeint/util/split.hpp>
0028 #include <boost/numeric/odeint/util/resize.hpp>
0029 #include <boost/numeric/odeint/external/openmp/openmp_nested_algebra.hpp>
0030
0031 namespace boost {
0032 namespace numeric {
0033 namespace odeint {
0034
0035
0036
0037
0038 template< class T >
0039 struct openmp_state : public std::vector< std::vector< T > >
0040 {
0041 openmp_state() {}
0042
0043 openmp_state(size_t n, const std::vector<T>& val = std::vector<T>())
0044 : std::vector< std::vector< T > >(n, val) {}
0045
0046 template<class InputIterator>
0047 openmp_state(InputIterator first, InputIterator last)
0048 : std::vector< std::vector< T > >(first, last) {}
0049
0050 openmp_state(const std::vector< std::vector< T > > &orig)
0051 : std::vector< std::vector< T > >(orig) {}
0052
0053 };
0054
0055
0056
0057
0058 template< class T >
0059 struct is_resizeable< openmp_state< T > > : boost::true_type { };
0060
0061
0062 template< class T >
0063 struct same_size_impl< openmp_state< T > , openmp_state< T > >
0064 {
0065 static bool same_size( const openmp_state< T > &x , const openmp_state< T > &y )
0066 {
0067 if( x.size() != y.size() ) return false;
0068 for( size_t i = 0 ; i != x.size() ; i++ )
0069 if( x[i].size() != y[i].size() ) return false;
0070 return true;
0071 }
0072 };
0073
0074
0075 template< class T >
0076 struct resize_impl< openmp_state< T > , openmp_state< T > >
0077 {
0078 static void resize( openmp_state< T > &x , const openmp_state< T > &y )
0079 {
0080 x.resize( y.size() );
0081 # pragma omp parallel for schedule(dynamic)
0082 for(size_t i = 0 ; i < x.size() ; i++)
0083 x[i].resize( y[i].size() );
0084 }
0085 };
0086
0087
0088
0089 template< class T >
0090 struct copy_impl< openmp_state< T >, openmp_state< T > >
0091 {
0092 static void copy( const openmp_state< T > &from, openmp_state< T > &to )
0093 {
0094 # pragma omp parallel for schedule(dynamic)
0095 for(size_t i = 0 ; i < from.size() ; i++)
0096 std::copy( from[i].begin() , from[i].end() , to.begin() );
0097 }
0098 };
0099
0100
0101
0102
0103
0104
0105
0106
0107 template< class SourceContainer >
0108 struct split_impl< SourceContainer, openmp_state< typename SourceContainer::value_type > >
0109 {
0110 static void split( const SourceContainer &from, openmp_state< typename SourceContainer::value_type > &to )
0111 {
0112 if(to.size() == 0) to.resize( omp_get_max_threads() );
0113 const size_t part = from.size() / to.size();
0114 # pragma omp parallel for schedule(dynamic)
0115 for(size_t i = 0 ; i < to.size() ; i++) {
0116 typedef typename SourceContainer::const_iterator it_t;
0117 const it_t begin = from.begin() + i * part;
0118 it_t end = begin + part;
0119
0120 if(i + 1 == to.size() || end > from.end()) end = from.end();
0121 to[i].resize(end - begin);
0122 std::copy(begin, end, to[i].begin());
0123 }
0124 }
0125 };
0126
0127
0128
0129
0130 template< class TargetContainer >
0131 struct unsplit_impl< openmp_state< typename TargetContainer::value_type >, TargetContainer >
0132 {
0133 static void unsplit( const openmp_state< typename TargetContainer::value_type > &from , TargetContainer &to )
0134 {
0135
0136 size_t total_size = 0;
0137 for(size_t i = 0 ; i < from.size() ; i++)
0138 total_size += from[i].size();
0139 to.resize( total_size );
0140
0141 typename TargetContainer::iterator out = to.begin();
0142 for(size_t i = 0 ; i < from.size() ; i++)
0143 out = std::copy(from[i].begin(), from[i].end(), out);
0144 }
0145 };
0146
0147
0148
0149
0150
0151
0152
0153 typedef openmp_nested_algebra< range_algebra > openmp_algebra;
0154
0155
0156
0157
0158 template< class T >
0159 struct algebra_dispatcher< openmp_state< T > >
0160 {
0161 typedef openmp_algebra algebra_type;
0162 };
0163
0164
0165 }
0166 }
0167 }
0168
0169
0170 #endif
0171