packed_iarchive.hpp 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  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_iarchive.hpp
  9. *
  10. * This header provides the facilities for packing Serializable data
  11. * types into a buffer using @c MPI_Pack. The buffers can then be
  12. * transmitted via MPI and then be unpacked either via the facilities
  13. * in @c packed_oarchive.hpp or @c MPI_Unpack.
  14. */
  15. #ifndef BOOST_MPI_PACKED_IARCHIVE_HPP
  16. #define BOOST_MPI_PACKED_IARCHIVE_HPP
  17. #include <boost/mpi/datatype.hpp>
  18. #include <boost/archive/detail/auto_link_archive.hpp>
  19. #include <boost/archive/detail/common_iarchive.hpp>
  20. #include <boost/archive/basic_archive.hpp>
  21. #include <boost/mpi/detail/packed_iprimitive.hpp>
  22. #include <boost/mpi/detail/binary_buffer_iprimitive.hpp>
  23. #include <boost/serialization/string.hpp>
  24. #include <boost/serialization/collection_size_type.hpp>
  25. #include <boost/serialization/item_version_type.hpp>
  26. #include <boost/assert.hpp>
  27. namespace boost { namespace mpi {
  28. #ifdef BOOST_MPI_HOMOGENEOUS
  29. typedef binary_buffer_iprimitive iprimitive;
  30. #else
  31. typedef packed_iprimitive iprimitive;
  32. #endif
  33. /** @brief An archive that unpacks binary data from an MPI buffer.
  34. *
  35. * The @c packed_oarchive class is an Archiver (as in the
  36. * Boost.Serialization library) that unpacks binary data from a
  37. * buffer received via MPI. It can operate on any Serializable data
  38. * type and will use the @c MPI_Unpack function of the underlying MPI
  39. * implementation to perform deserialization.
  40. */
  41. class BOOST_MPI_DECL packed_iarchive
  42. : public iprimitive
  43. , public archive::detail::common_iarchive<packed_iarchive>
  44. {
  45. public:
  46. /**
  47. * Construct a @c packed_iarchive to receive data over the given
  48. * MPI communicator and with an initial buffer.
  49. *
  50. * @param comm The communicator over which this archive will be
  51. * received.
  52. *
  53. * @param b A user-defined buffer that contains the binary
  54. * representation of serialized objects.
  55. *
  56. * @param flags Control the serialization of the data types. Refer
  57. * to the Boost.Serialization documentation before changing the
  58. * default flags.
  59. */
  60. packed_iarchive(MPI_Comm const & comm, buffer_type & b, unsigned int flags = boost::archive::no_header, int position = 0)
  61. : iprimitive(b,comm,position),
  62. archive::detail::common_iarchive<packed_iarchive>(flags)
  63. {}
  64. /**
  65. * Construct a @c packed_iarchive to receive data over the given
  66. * MPI communicator.
  67. *
  68. * @param comm The communicator over which this archive will be
  69. * received.
  70. *
  71. * @param flags Control the serialization of the data types. Refer
  72. * to the Boost.Serialization documentation before changing the
  73. * default flags.
  74. */
  75. packed_iarchive
  76. ( MPI_Comm const & comm , std::size_t s=0,
  77. unsigned int flags = boost::archive::no_header)
  78. : iprimitive(internal_buffer_,comm)
  79. , archive::detail::common_iarchive<packed_iarchive>(flags)
  80. , internal_buffer_(s)
  81. {}
  82. // Load everything else in the usual way, forwarding on to the Base class
  83. template<class T>
  84. void load_override(T& x, mpl::false_)
  85. {
  86. archive::detail::common_iarchive<packed_iarchive>::load_override(x);
  87. }
  88. // Load it directly using the primnivites
  89. template<class T>
  90. void load_override(T& x, mpl::true_)
  91. {
  92. iprimitive::load(x);
  93. }
  94. // Load all supported datatypes directly
  95. template<class T>
  96. void load_override(T& x)
  97. {
  98. typedef typename mpl::apply1<use_array_optimization
  99. , BOOST_DEDUCED_TYPENAME remove_const<T>::type
  100. >::type use_optimized;
  101. load_override(x, use_optimized());
  102. }
  103. // input archives need to ignore the optional information
  104. void load_override(archive::class_id_optional_type & /*t*/){}
  105. void load_override(archive::class_id_type & t){
  106. int_least16_t x=0;
  107. * this->This() >> x;
  108. t = boost::archive::class_id_type(x);
  109. }
  110. void load_override(archive::version_type & t){
  111. int_least8_t x=0;
  112. * this->This() >> x;
  113. t = boost::archive::version_type(x);
  114. }
  115. void load_override(archive::class_id_reference_type & t){
  116. load_override(static_cast<archive::class_id_type &>(t));
  117. }
  118. void load_override(archive::class_name_type & t)
  119. {
  120. std::string cn;
  121. cn.reserve(BOOST_SERIALIZATION_MAX_KEY_SIZE);
  122. * this->This() >> cn;
  123. std::memcpy(t, cn.data(), cn.size());
  124. // borland tweak
  125. t.t[cn.size()] = '\0';
  126. }
  127. private:
  128. /// An internal buffer to be used when the user does not supply his
  129. /// own buffer.
  130. buffer_type internal_buffer_;
  131. };
  132. } } // end namespace boost::mpi
  133. BOOST_SERIALIZATION_REGISTER_ARCHIVE(boost::mpi::packed_iarchive)
  134. BOOST_SERIALIZATION_USE_ARRAY_OPTIMIZATION(boost::mpi::packed_iarchive)
  135. #endif // BOOST_MPI_PACKED_IARCHIVE_HPP