packed_iarchive.hpp 5.0 KB

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