packed_oarchive.hpp 4.8 KB

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