Chris@16: // (C) Copyright 2005 Matthias Troyer Chris@16: // (C) Copyright 2006 Douglas Gregor Chris@16: Chris@16: // Use, modification and distribution is subject to the Boost Software Chris@16: // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at Chris@16: // http://www.boost.org/LICENSE_1_0.txt) Chris@16: Chris@16: // Authors: Matthias Troyer Chris@16: // Douglas Gregor Chris@16: Chris@16: /** @file packed_iarchive.hpp Chris@16: * Chris@16: * This header provides the facilities for packing Serializable data Chris@16: * types into a buffer using @c MPI_Pack. The buffers can then be Chris@16: * transmitted via MPI and then be unpacked either via the facilities Chris@16: * in @c packed_oarchive.hpp or @c MPI_Unpack. Chris@16: */ Chris@16: #ifndef BOOST_MPI_PACKED_IARCHIVE_HPP Chris@16: #define BOOST_MPI_PACKED_IARCHIVE_HPP Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: namespace boost { namespace mpi { Chris@16: Chris@16: #ifdef BOOST_MPI_HOMOGENEOUS Chris@16: typedef binary_buffer_iprimitive iprimitive; Chris@16: #else Chris@16: typedef packed_iprimitive iprimitive; Chris@16: #endif Chris@16: Chris@16: Chris@16: /** @brief An archive that unpacks binary data from an MPI buffer. Chris@16: * Chris@16: * The @c packed_oarchive class is an Archiver (as in the Chris@16: * Boost.Serialization library) that unpacks binary data from a Chris@16: * buffer received via MPI. It can operate on any Serializable data Chris@16: * type and will use the @c MPI_Unpack function of the underlying MPI Chris@16: * implementation to perform deserialization. Chris@16: */ Chris@16: Chris@16: class BOOST_MPI_DECL packed_iarchive Chris@16: : public iprimitive Chris@16: , public archive::detail::common_iarchive Chris@16: { Chris@16: public: Chris@16: /** Chris@16: * Construct a @c packed_iarchive to receive data over the given Chris@16: * MPI communicator and with an initial buffer. Chris@16: * Chris@16: * @param comm The communicator over which this archive will be Chris@16: * received. Chris@16: * Chris@16: * @param b A user-defined buffer that contains the binary Chris@16: * representation of serialized objects. Chris@16: * Chris@16: * @param flags Control the serialization of the data types. Refer Chris@16: * to the Boost.Serialization documentation before changing the Chris@16: * default flags. Chris@16: */ Chris@16: Chris@16: packed_iarchive(MPI_Comm const & comm, buffer_type & b, unsigned int flags = boost::archive::no_header, int position = 0) Chris@16: : iprimitive(b,comm,position), Chris@16: archive::detail::common_iarchive(flags) Chris@16: {} Chris@16: Chris@16: /** Chris@16: * Construct a @c packed_iarchive to receive data over the given Chris@16: * MPI communicator. Chris@16: * Chris@16: * @param comm The communicator over which this archive will be Chris@16: * received. Chris@16: * Chris@16: * @param flags Control the serialization of the data types. Refer Chris@16: * to the Boost.Serialization documentation before changing the Chris@16: * default flags. Chris@16: */ Chris@16: Chris@16: packed_iarchive Chris@101: ( MPI_Comm const & comm , std::size_t s=0, Chris@16: unsigned int flags = boost::archive::no_header) Chris@16: : iprimitive(internal_buffer_,comm) Chris@16: , archive::detail::common_iarchive(flags) Chris@16: , internal_buffer_(s) Chris@16: {} Chris@16: Chris@16: // Load everything else in the usual way, forwarding on to the Base class Chris@16: template Chris@16: void load_override(T& x, int version, mpl::false_) Chris@16: { Chris@16: archive::detail::common_iarchive::load_override(x,version); Chris@16: } Chris@16: Chris@16: // Load it directly using the primnivites Chris@16: template Chris@16: void load_override(T& x, int /*version*/, mpl::true_) Chris@16: { Chris@16: iprimitive::load(x); Chris@16: } Chris@16: Chris@16: // Load all supported datatypes directly Chris@16: template Chris@16: void load_override(T& x, int version) Chris@16: { Chris@16: typedef typename mpl::apply1::type Chris@16: >::type use_optimized; Chris@16: load_override(x, version, use_optimized()); Chris@16: } Chris@16: Chris@101: // input archives need to ignore the optional information Chris@16: void load_override(archive::class_id_optional_type & /*t*/, int){} Chris@16: Chris@16: void load_override(archive::class_id_type & t, int version){ Chris@16: int_least16_t x=0; Chris@16: * this->This() >> x; Chris@16: t = boost::archive::class_id_type(x); Chris@16: } Chris@16: Chris@101: void load_override(archive::version_type & t, int version){ Chris@101: int_least8_t x=0; Chris@101: * this->This() >> x; Chris@101: t = boost::archive::version_type(x); Chris@101: } Chris@101: Chris@16: void load_override(archive::class_id_reference_type & t, int version){ Chris@16: load_override(static_cast(t), version); Chris@16: } Chris@16: Chris@16: void load_override(archive::class_name_type & t, int) Chris@16: { Chris@16: std::string cn; Chris@16: cn.reserve(BOOST_SERIALIZATION_MAX_KEY_SIZE); Chris@16: * this->This() >> cn; Chris@16: std::memcpy(t, cn.data(), cn.size()); Chris@16: // borland tweak Chris@16: t.t[cn.size()] = '\0'; Chris@16: } Chris@16: Chris@16: private: Chris@16: /// An internal buffer to be used when the user does not supply his Chris@16: /// own buffer. Chris@16: buffer_type internal_buffer_; Chris@16: }; Chris@16: Chris@16: } } // end namespace boost::mpi Chris@16: Chris@16: BOOST_SERIALIZATION_REGISTER_ARCHIVE(boost::mpi::packed_iarchive) Chris@16: BOOST_SERIALIZATION_USE_ARRAY_OPTIMIZATION(boost::mpi::packed_iarchive) Chris@16: Chris@16: #endif // BOOST_MPI_PACKED_IARCHIVE_HPP