Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-07-09 08:17:53

0001 /*
0002  [auto_generated]
0003  boost/numeric/odeint/external/mpi/mpi_vector_state.hpp
0004 
0005  [begin_description]
0006  Copying a container from/to an mpi_state splits/joins it.
0007  [end_description]
0008 
0009  Copyright 2013 Karsten Ahnert
0010  Copyright 2013 Mario Mulansky
0011  Copyright 2013 Pascal Germroth
0012 
0013  Distributed under the Boost Software License, Version 1.0.
0014  (See accompanying file LICENSE_1_0.txt or
0015  copy at http://www.boost.org/LICENSE_1_0.txt)
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 /** \brief Split data from some container on node 0 to the slaves.
0037  * Source must be a model of Random Access Range. */
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         // send to nodes
0057         boost::mpi::scatter(to.world, pieces, to(), 0);
0058     }
0059 };
0060 
0061 /** \brief Merge data from an mpi_state to some container on node 0.
0062  * Target must be a model Single Pass Range. */
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         // send data to root
0073         boost::mpi::gather(from.world, from(), pieces, 0);
0074         if(from.world.rank() == 0) {
0075             // check target size
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             // copy parts
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