Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:40:57

0001 // (C) Copyright 2005 Matthias Troyer
0002 
0003 // Use, modification and distribution is subject to the Boost Software
0004 // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
0005 // http://www.boost.org/LICENSE_1_0.txt)
0006 
0007 //  Authors: Matthias Troyer
0008 
0009 #ifndef BOOST_MPI_PACKED_OPRIMITIVE_HPP
0010 #define BOOST_MPI_PACKED_OPRIMITIVE_HPP
0011 
0012 #include <boost/mpi/config.hpp>
0013 #include <cstddef> // size_t
0014 #include <boost/config.hpp>
0015 #include <boost/mpi/datatype.hpp>
0016 #include <boost/mpi/exception.hpp>
0017 #include <boost/mpi/detail/antiques.hpp>
0018 #include <boost/serialization/array.hpp>
0019 #include <boost/assert.hpp>
0020 #include <vector>
0021 #include <boost/mpi/allocator.hpp>
0022 
0023 namespace boost { namespace mpi {
0024 
0025 /// serialization using MPI::Pack
0026 
0027 class BOOST_MPI_DECL packed_oprimitive
0028 {
0029 public:
0030     /// the type of the buffer into which the data is packed upon serialization
0031     typedef std::vector<char, allocator<char> > buffer_type;
0032 
0033     packed_oprimitive(buffer_type & b, MPI_Comm const & comm)
0034          : buffer_(b),
0035            comm(comm)
0036         {
0037         }
0038 
0039     void const * address() const
0040     {
0041       return detail::c_data(buffer_);
0042     }
0043 
0044     const std::size_t& size() const
0045     {
0046       return size_ = buffer_.size();
0047     }
0048 
0049     const std::size_t* size_ptr() const
0050     {
0051       return &size();
0052     }
0053 
0054     void save_binary(void const *address, std::size_t count)
0055         {
0056           save_impl(address,MPI_BYTE,count);
0057         }
0058 
0059     // fast saving of arrays
0060     template<class T>
0061     void save_array(serialization::array_wrapper<T> const& x, unsigned int /* file_version */)
0062     {
0063         if (x.count())
0064           save_impl(x.address(), get_mpi_datatype(*x.address()), x.count());
0065     }
0066 
0067     typedef is_mpi_datatype<mpl::_1> use_array_optimization;
0068 
0069 #ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
0070     friend class archive::save_access;
0071 protected:
0072 #else
0073 public:
0074 #endif
0075 
0076     // default saving of primitives.
0077     template<class T>
0078     void save(const T & t)
0079     {
0080       save_impl(&t, get_mpi_datatype<T>(t), 1);
0081     }
0082 
0083     template<class CharType>
0084     void save(const std::basic_string<CharType> &s)
0085     {
0086       unsigned int l = static_cast<unsigned int>(s.size());
0087       save(l);
0088       if (l)
0089         save_impl(s.data(),get_mpi_datatype(CharType()),s.size());
0090     }
0091 
0092 private:
0093 
0094     void save_impl(void const * p, MPI_Datatype t, int l)
0095     {
0096       // allocate enough memory
0097       int memory_needed;
0098       BOOST_MPI_CHECK_RESULT(MPI_Pack_size,(l,t,comm,&memory_needed));
0099 
0100       int position = buffer_.size();
0101       buffer_.resize(position + memory_needed);
0102 
0103       // pack the data into the buffer
0104       BOOST_MPI_CHECK_RESULT(MPI_Pack,
0105                              (const_cast<void*>(p),l,t, 
0106                               detail::c_data(buffer_),
0107                               buffer_.size(), 
0108                               &position,comm));
0109       // reduce the buffer size if needed
0110       BOOST_ASSERT(std::size_t(position) <= buffer_.size());
0111       if (std::size_t(position) < buffer_.size())
0112           buffer_.resize(position);
0113     }
0114 
0115     static buffer_type::value_type* get_data(buffer_type& b)
0116     {
0117       return detail::c_data(b);
0118     }
0119 
0120   buffer_type& buffer_;
0121   mutable std::size_t size_;
0122   MPI_Comm comm;
0123 };
0124 
0125 } } // end namespace boost::mpi
0126 
0127 #endif // BOOST_MPI_PACKED_OPRIMITIVE_HPP