• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // (C) Copyright 2005 Matthias Troyer
2 // (C) Copyright 2006 Douglas Gregor <doug.gregor -at- gmail.com>
3 
4 // Use, modification and distribution is subject to the Boost Software
5 // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
6 // http://www.boost.org/LICENSE_1_0.txt)
7 
8 //  Authors: Matthias Troyer
9 //           Douglas Gregor
10 
11 /** @file packed_oarchive.hpp
12  *
13  *  This header provides the facilities for unpacking Serializable
14  *  data types from a buffer using @c MPI_Unpack. The buffers are
15  *  typically received via MPI and have been packed either by via the
16  *  facilities in @c packed_iarchive.hpp or @c MPI_Pack.
17  */
18 #ifndef BOOST_MPI_PACKED_OARCHIVE_HPP
19 #define BOOST_MPI_PACKED_OARCHIVE_HPP
20 
21 #include <boost/mpi/datatype.hpp>
22 #include <boost/archive/basic_archive.hpp>
23 #include <boost/archive/detail/auto_link_archive.hpp>
24 #include <boost/archive/detail/common_oarchive.hpp>
25 #include <boost/mpi/detail/packed_oprimitive.hpp>
26 #include <boost/mpi/detail/binary_buffer_oprimitive.hpp>
27 #include <boost/serialization/string.hpp>
28 #include <boost/serialization/collection_size_type.hpp>
29 #include <boost/serialization/item_version_type.hpp>
30 
31 namespace boost { namespace mpi {
32 
33 #ifdef BOOST_MPI_HOMOGENEOUS
34   typedef binary_buffer_oprimitive oprimitive;
35 #else
36   typedef packed_oprimitive oprimitive;
37 #endif
38 
39 /** @brief An archive that packs binary data into an MPI buffer.
40  *
41  *  The @c packed_iarchive class is an Archiver (as in the
42  *  Boost.Serialization library) that packs binary data into a buffer
43  *  for transmission via MPI. It can operate on any Serializable data
44  *  type and will use the @c MPI_Pack function of the underlying MPI
45  *  implementation to perform serialization.
46  */
47 
48 class BOOST_MPI_DECL packed_oarchive
49   : public oprimitive
50   , public archive::detail::common_oarchive<packed_oarchive>
51 {
52 public:
53   /**
54    *  Construct a @c packed_oarchive for transmission over the given
55    *  MPI communicator and with an initial buffer.
56    *
57    *  @param comm The communicator over which this archive will be
58    *  sent.
59    *
60    *  @param b A user-defined buffer that will be filled with the
61    *  binary representation of serialized objects.
62    *
63    *  @param flags Control the serialization of the data types. Refer
64    *  to the Boost.Serialization documentation before changing the
65    *  default flags.
66    *
67    *  @param position Set the offset into buffer @p b at which
68    *  deserialization will begin.
69    */
packed_oarchive(MPI_Comm const & comm,buffer_type & b,unsigned int flags=boost::archive::no_header)70   packed_oarchive( MPI_Comm const & comm, buffer_type & b, unsigned int flags = boost::archive::no_header)
71          : oprimitive(b,comm),
72            archive::detail::common_oarchive<packed_oarchive>(flags)
73         {}
74 
75   /**
76    *  Construct a @c packed_oarchive for transmission over the given
77    *  MPI communicator.
78    *
79    *  @param comm The communicator over which this archive will be
80    *  sent.
81    *
82    *  @param s The size of the buffer to be received.
83    *
84    *  @param flags Control the serialization of the data types. Refer
85    *  to the Boost.Serialization documentation before changing the
86    *  default flags.
87    */
packed_oarchive(MPI_Comm const & comm,unsigned int flags=boost::archive::no_header)88   packed_oarchive ( MPI_Comm const & comm, unsigned int flags =  boost::archive::no_header)
89          : oprimitive(internal_buffer_,comm),
90            archive::detail::common_oarchive<packed_oarchive>(flags)
91         {}
92 
93   // Save everything else in the usual way, forwarding on to the Base class
94   template<class T>
save_override(T const & x,mpl::false_)95   void save_override(T const& x, mpl::false_)
96   {
97     archive::detail::common_oarchive<packed_oarchive>::save_override(x);
98   }
99 
100   // Save it directly using the primitives
101   template<class T>
save_override(T const & x,mpl::true_)102   void save_override(T const& x, mpl::true_)
103   {
104     oprimitive::save(x);
105   }
106 
107   // Save all supported datatypes directly
108   template<class T>
save_override(T const & x)109   void save_override(T const& x)
110   {
111     typedef typename mpl::apply1<use_array_optimization,T>::type use_optimized;
112     save_override(x, use_optimized());
113   }
114 
115   // output archives need to ignore  the optional information
save_override(const archive::class_id_optional_type &)116   void save_override(const archive::class_id_optional_type & ){}
117 
118   // explicitly convert to char * to avoid compile ambiguities
save_override(const archive::class_name_type & t)119   void save_override(const archive::class_name_type & t){
120       const std::string s(t);
121       * this->This() << s;
122   }
123 
save_override(const archive::class_id_type & t)124   void save_override(const archive::class_id_type & t){
125     const boost::int_least16_t x = t;
126     * this->This() << x;
127   }
128 
save_override(const archive::version_type & t)129   void save_override(const archive::version_type & t){
130     const boost::int_least8_t x = t;
131     * this->This() << x;
132   }
133 private:
134   /// An internal buffer to be used when the user does not supply his
135   /// own buffer.
136   buffer_type internal_buffer_;
137 };
138 
139 } } // end namespace boost::mpi
140 
141 // required by export
142 BOOST_SERIALIZATION_REGISTER_ARCHIVE(boost::mpi::packed_oarchive)
143 BOOST_SERIALIZATION_USE_ARRAY_OPTIMIZATION(boost::mpi::packed_oarchive)
144 
145 
146 
147 #endif // BOOST_MPI_PACKED_OARCHIVE_HPP
148