Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-12-15 09:56:26

0001 // (C) Copyright 2005 Matthias Troyer
0002 // (C) Copyright 2006 Douglas Gregor <doug.gregor -at- gmail.com>
0003 
0004 // Use, modification and distribution is subject to the Boost Software
0005 // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
0006 // http://www.boost.org/LICENSE_1_0.txt)
0007 
0008 //  Authors: Matthias Troyer
0009 //           Douglas Gregor
0010 
0011 /** @file packed_iarchive.hpp
0012  *
0013  *  This header provides the facilities for packing Serializable data
0014  *  types into a buffer using @c MPI_Pack. The buffers can then be
0015  *  transmitted via MPI and then be unpacked either via the facilities
0016  *  in @c packed_oarchive.hpp or @c MPI_Unpack.
0017  */
0018 #ifndef BOOST_MPI_PACKED_IARCHIVE_HPP
0019 #define BOOST_MPI_PACKED_IARCHIVE_HPP
0020 
0021 #include <boost/mpi/datatype.hpp>
0022 #include <boost/archive/detail/auto_link_archive.hpp>
0023 #include <boost/archive/detail/common_iarchive.hpp>
0024 #include <boost/archive/basic_archive.hpp>
0025 #include <boost/mpi/detail/packed_iprimitive.hpp>
0026 #include <boost/mpi/detail/binary_buffer_iprimitive.hpp>
0027 #include <boost/serialization/string.hpp>
0028 #include <boost/serialization/collection_size_type.hpp>
0029 #include <boost/serialization/item_version_type.hpp>
0030 #include <boost/assert.hpp>
0031 
0032 namespace boost { namespace mpi {
0033 
0034 #ifdef BOOST_MPI_HOMOGENEOUS
0035   typedef binary_buffer_iprimitive iprimitive;
0036 #else
0037   typedef packed_iprimitive iprimitive;
0038 #endif
0039 
0040 
0041 /** @brief An archive that unpacks binary data from an MPI buffer.
0042  *
0043  *  The @c packed_oarchive class is an Archiver (as in the
0044  *  Boost.Serialization library) that unpacks binary data from a
0045  *  buffer received via MPI. It can operate on any Serializable data
0046  *  type and will use the @c MPI_Unpack function of the underlying MPI
0047  *  implementation to perform deserialization.
0048  */
0049 
0050 class BOOST_MPI_DECL packed_iarchive
0051   : public iprimitive
0052   , public archive::detail::common_iarchive<packed_iarchive>
0053 {
0054 public:
0055   /**
0056    *  Construct a @c packed_iarchive to receive data over the given
0057    *  MPI communicator and with an initial buffer.
0058    *
0059    *  @param comm The communicator over which this archive will be
0060    *  received.
0061    *
0062    *  @param b A user-defined buffer that contains the binary
0063    *  representation of serialized objects.
0064    *
0065    *  @param flags Control the serialization of the data types. Refer
0066    *  to the Boost.Serialization documentation before changing the
0067    *  default flags.
0068    */
0069 
0070   packed_iarchive(MPI_Comm const & comm, buffer_type & b, unsigned int flags = boost::archive::no_header, int position = 0)
0071         : iprimitive(b,comm,position),
0072           archive::detail::common_iarchive<packed_iarchive>(flags)
0073         {}
0074 
0075   /**
0076    *  Construct a @c packed_iarchive to receive data over the given
0077    *  MPI communicator.
0078    *
0079    *  @param comm The communicator over which this archive will be
0080    *  received.
0081    *
0082    *  @param flags Control the serialization of the data types. Refer
0083    *  to the Boost.Serialization documentation before changing the
0084    *  default flags.
0085    */
0086 
0087   packed_iarchive
0088           ( MPI_Comm const & comm , std::size_t s=0,
0089            unsigned int flags = boost::archive::no_header)
0090          : iprimitive(internal_buffer_,comm)
0091          , archive::detail::common_iarchive<packed_iarchive>(flags)
0092          , internal_buffer_(s)
0093         {}
0094 
0095   // Load everything else in the usual way, forwarding on to the Base class
0096   template<class T>
0097   void load_override(T& x, mpl::false_)
0098   {
0099     archive::detail::common_iarchive<packed_iarchive>::load_override(x);
0100   }
0101 
0102   // Load it directly using the primnivites
0103   template<class T>
0104   void load_override(T& x, mpl::true_)
0105   {
0106     iprimitive::load(x);
0107   }
0108 
0109   // Load all supported datatypes directly
0110   template<class T>
0111   void load_override(T& x)
0112   {
0113     typedef typename mpl::apply1<use_array_optimization
0114       , BOOST_DEDUCED_TYPENAME remove_const<T>::type
0115     >::type use_optimized;
0116     load_override(x, use_optimized());
0117   }
0118 
0119   // input archives need to ignore  the optional information
0120   void load_override(archive::class_id_optional_type & /*t*/){}
0121 
0122   void load_override(archive::class_id_type & t){
0123     int_least16_t x=0;
0124     * this->This() >> x;
0125     t = boost::archive::class_id_type(x);
0126   }
0127 
0128   void load_override(archive::version_type & t){
0129     int_least8_t x=0;
0130     * this->This() >> x;
0131     t = boost::archive::version_type(x);
0132   }
0133 
0134   void load_override(archive::class_id_reference_type & t){
0135     load_override(static_cast<archive::class_id_type &>(t));
0136   }
0137 
0138   void load_override(archive::class_name_type & t)
0139   {
0140     std::string cn;
0141     cn.reserve(BOOST_SERIALIZATION_MAX_KEY_SIZE);
0142     * this->This() >> cn;
0143     std::memcpy(t, cn.data(), cn.size());
0144     // borland tweak
0145     t.t[cn.size()] = '\0';
0146   }
0147 
0148 private:
0149   /// An internal buffer to be used when the user does not supply his
0150   /// own buffer.
0151   buffer_type internal_buffer_;
0152 };
0153 
0154 } } // end namespace boost::mpi
0155 
0156 BOOST_SERIALIZATION_REGISTER_ARCHIVE(boost::mpi::packed_iarchive)
0157 BOOST_SERIALIZATION_USE_ARRAY_OPTIMIZATION(boost::mpi::packed_iarchive)
0158 
0159 #endif // BOOST_MPI_PACKED_IARCHIVE_HPP