user_data_types.qbk 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. [section:user_data_types User-defined data types]
  2. The inclusion of `boost/serialization/string.hpp` in the previous
  3. examples is very important: it makes values of type `std::string`
  4. serializable, so that they can be be transmitted using Boost.MPI. In
  5. general, built-in C++ types (`int`s, `float`s, characters, etc.) can
  6. be transmitted over MPI directly, while user-defined and
  7. library-defined types will need to first be serialized (packed) into a
  8. format that is amenable to transmission. Boost.MPI relies on the
  9. _Serialization_ library to serialize and deserialize data types.
  10. For types defined by the standard library (such as `std::string` or
  11. `std::vector`) and some types in Boost (such as `boost::variant`), the
  12. _Serialization_ library already contains all of the required
  13. serialization code. In these cases, you need only include the
  14. appropriate header from the `boost/serialization` directory.
  15. [def _gps_position_ [link gps_position `gps_position`]]
  16. For types that do not already have a serialization header, you will
  17. first need to implement serialization code before the types can be
  18. transmitted using Boost.MPI. Consider a simple class _gps_position_
  19. that contains members `degrees`, `minutes`, and `seconds`. This class
  20. is made serializable by making it a friend of
  21. `boost::serialization::access` and introducing the templated
  22. `serialize()` function, as follows:[#gps_position]
  23. class gps_position
  24. {
  25. private:
  26. friend class boost::serialization::access;
  27. template<class Archive>
  28. void serialize(Archive & ar, const unsigned int version)
  29. {
  30. ar & degrees;
  31. ar & minutes;
  32. ar & seconds;
  33. }
  34. int degrees;
  35. int minutes;
  36. float seconds;
  37. public:
  38. gps_position(){};
  39. gps_position(int d, int m, float s) :
  40. degrees(d), minutes(m), seconds(s)
  41. {}
  42. };
  43. Complete information about making types serializable is beyond the
  44. scope of this tutorial. For more information, please see the
  45. _Serialization_ library tutorial from which the above example was
  46. extracted. One important side benefit of making types serializable for
  47. Boost.MPI is that they become serializable for any other usage, such
  48. as storing the objects to disk and manipulated them in XML.
  49. Some serializable types, like _gps_position_ above, have a fixed
  50. amount of data stored at fixed offsets and are fully defined by
  51. the values of their data member (most POD with no pointers are a good example).
  52. When this is the case, Boost.MPI can optimize their serialization and
  53. transmission by avoiding extraneous copy operations.
  54. To enable this optimization, users must specialize the type trait [classref
  55. boost::mpi::is_mpi_datatype `is_mpi_datatype`], e.g.:
  56. namespace boost { namespace mpi {
  57. template <>
  58. struct is_mpi_datatype<gps_position> : mpl::true_ { };
  59. } }
  60. For non-template types we have defined a macro to simplify declaring a type
  61. as an MPI datatype
  62. BOOST_IS_MPI_DATATYPE(gps_position)
  63. For composite traits, the specialization of [classref
  64. boost::mpi::is_mpi_datatype `is_mpi_datatype`] may depend on
  65. `is_mpi_datatype` itself. For instance, a `boost::array` object is
  66. fixed only when the type of the parameter it stores is fixed:
  67. namespace boost { namespace mpi {
  68. template <typename T, std::size_t N>
  69. struct is_mpi_datatype<array<T, N> >
  70. : public is_mpi_datatype<T> { };
  71. } }
  72. The redundant copy elimination optimization can only be applied when
  73. the shape of the data type is completely fixed. Variable-length types
  74. (e.g., strings, linked lists) and types that store pointers cannot use
  75. the optimization, but Boost.MPI will be unable to detect this error at
  76. compile time. Attempting to perform this optimization when it is not
  77. correct will likely result in segmentation faults and other strange
  78. program behavior.
  79. Boost.MPI can transmit any user-defined data type from one process to
  80. another. Built-in types can be transmitted without any extra effort;
  81. library-defined types require the inclusion of a serialization header;
  82. and user-defined types will require the addition of serialization
  83. code. Fixed data types can be optimized for transmission using the
  84. [classref boost::mpi::is_mpi_datatype `is_mpi_datatype`]
  85. type trait.
  86. [endsect:user_data_types]