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