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