packed_oarchive.hpp 4.7 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/mpi/detail/packed_oprimitive.hpp>
  22. #include <boost/mpi/detail/binary_buffer_oprimitive.hpp>
  23. #include <boost/serialization/string.hpp>
  24. #include <boost/serialization/collection_size_type.hpp>
  25. #include <boost/serialization/item_version_type.hpp>
  26. namespace boost { namespace mpi {
  27. #ifdef BOOST_MPI_HOMOGENEOUS
  28. typedef binary_buffer_oprimitive oprimitive;
  29. #else
  30. typedef packed_oprimitive oprimitive;
  31. #endif
  32. /** @brief An archive that packs binary data into an MPI buffer.
  33. *
  34. * The @c packed_iarchive class is an Archiver (as in the
  35. * Boost.Serialization library) that packs binary data into a buffer
  36. * for transmission via MPI. It can operate on any Serializable data
  37. * type and will use the @c MPI_Pack function of the underlying MPI
  38. * implementation to perform serialization.
  39. */
  40. class BOOST_MPI_DECL packed_oarchive
  41. : public oprimitive
  42. , public archive::detail::common_oarchive<packed_oarchive>
  43. {
  44. public:
  45. /**
  46. * Construct a @c packed_oarchive for transmission over the given
  47. * MPI communicator and with an initial buffer.
  48. *
  49. * @param comm The communicator over which this archive will be
  50. * sent.
  51. *
  52. * @param b A user-defined buffer that will be filled with the
  53. * binary representation of serialized objects.
  54. *
  55. * @param flags Control the serialization of the data types. Refer
  56. * to the Boost.Serialization documentation before changing the
  57. * default flags.
  58. *
  59. * @param position Set the offset into buffer @p b at which
  60. * deserialization will begin.
  61. */
  62. packed_oarchive( MPI_Comm const & comm, buffer_type & b, unsigned int flags = boost::archive::no_header)
  63. : oprimitive(b,comm),
  64. archive::detail::common_oarchive<packed_oarchive>(flags)
  65. {}
  66. /**
  67. * Construct a @c packed_oarchive for transmission over the given
  68. * MPI communicator.
  69. *
  70. * @param comm The communicator over which this archive will be
  71. * sent.
  72. *
  73. * @param s The size of the buffer to be received.
  74. *
  75. * @param flags Control the serialization of the data types. Refer
  76. * to the Boost.Serialization documentation before changing the
  77. * default flags.
  78. */
  79. packed_oarchive ( MPI_Comm const & comm, unsigned int flags = boost::archive::no_header)
  80. : oprimitive(internal_buffer_,comm),
  81. archive::detail::common_oarchive<packed_oarchive>(flags)
  82. {}
  83. // Save everything else in the usual way, forwarding on to the Base class
  84. template<class T>
  85. void save_override(T const& x, mpl::false_)
  86. {
  87. archive::detail::common_oarchive<packed_oarchive>::save_override(x);
  88. }
  89. // Save it directly using the primitives
  90. template<class T>
  91. void save_override(T const& x, mpl::true_)
  92. {
  93. oprimitive::save(x);
  94. }
  95. // Save all supported datatypes directly
  96. template<class T>
  97. void save_override(T const& x)
  98. {
  99. typedef typename mpl::apply1<use_array_optimization,T>::type use_optimized;
  100. save_override(x, use_optimized());
  101. }
  102. // output archives need to ignore the optional information
  103. void save_override(const archive::class_id_optional_type & ){}
  104. // explicitly convert to char * to avoid compile ambiguities
  105. void save_override(const archive::class_name_type & t){
  106. const std::string s(t);
  107. * this->This() << s;
  108. }
  109. void save_override(const archive::class_id_type & t){
  110. const boost::int_least16_t x = t;
  111. * this->This() << x;
  112. }
  113. void save_override(const archive::version_type & t){
  114. const boost::int_least8_t x = t;
  115. * this->This() << x;
  116. }
  117. private:
  118. /// An internal buffer to be used when the user does not supply his
  119. /// own buffer.
  120. buffer_type internal_buffer_;
  121. };
  122. } } // end namespace boost::mpi
  123. // required by export
  124. BOOST_SERIALIZATION_REGISTER_ARCHIVE(boost::mpi::packed_oarchive)
  125. BOOST_SERIALIZATION_USE_ARRAY_OPTIMIZATION(boost::mpi::packed_oarchive)
  126. #endif // BOOST_MPI_PACKED_OARCHIVE_HPP