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_MPI_MPI_VECTOR_STATE_HPP_INCLUDED
0020 #define BOOST_NUMERIC_ODEINT_EXTERNAL_MPI_MPI_VECTOR_STATE_HPP_INCLUDED
0021
0022 #include <vector>
0023 #include <algorithm>
0024 #include <boost/mpi.hpp>
0025 #include <boost/numeric/odeint/util/copy.hpp>
0026 #include <boost/numeric/odeint/util/split_adaptor.hpp>
0027 #include <boost/numeric/odeint/algebra/algebra_dispatcher.hpp>
0028 #include <boost/numeric/odeint/external/mpi/mpi_state.hpp>
0029
0030 namespace boost {
0031 namespace numeric {
0032 namespace odeint {
0033
0034
0035
0036
0037 template< class Source , class InnerState >
0038 struct split_impl< Source, mpi_state< InnerState >,
0039 typename boost::enable_if< boost::has_range_const_iterator<Source> >::type >
0040 {
0041 typedef typename boost::range_iterator<const Source>::type iterator;
0042
0043 static void split( const Source &from, mpi_state< InnerState > &to )
0044 {
0045 std::vector< InnerState > pieces;
0046 if(to.world.rank() == 0) {
0047 const size_t num = static_cast<size_t>(to.world.size());
0048 pieces.resize(num);
0049 for(size_t i = 0 ; i < num ; i++) {
0050 iterator_range<iterator> part = detail::make_split_range(from, i, num);
0051 boost::numeric::odeint::resize(pieces[i], part);
0052 boost::numeric::odeint::copy(part, pieces[i]);
0053 }
0054 }
0055
0056 boost::mpi::scatter(to.world, pieces, to(), 0);
0057 }
0058 };
0059
0060
0061
0062 template< class Target, class InnerState >
0063 struct unsplit_impl< mpi_state< InnerState >, Target,
0064 typename boost::enable_if< boost::has_range_iterator<Target> >::type >
0065 {
0066 typedef typename boost::range_iterator<Target>::type iterator;
0067
0068 static void unsplit( const mpi_state< InnerState > &from , Target &to )
0069 {
0070 std::vector< InnerState > pieces;
0071
0072 boost::mpi::gather(from.world, from(), pieces, 0);
0073 if(from.world.rank() == 0) {
0074
0075 size_t total_size = 0;
0076 for(size_t i = 0 ; i < pieces.size() ; i++)
0077 total_size += boost::size(pieces[i]);
0078 BOOST_ASSERT( total_size <= boost::size(to) );
0079
0080 iterator out = boost::begin(to);
0081 for(size_t i = 0 ; i < pieces.size() ; i++)
0082 out = boost::copy(pieces[i], out);
0083 }
0084 }
0085 };
0086
0087
0088 }
0089 }
0090 }
0091
0092
0093 #endif
0094