/Src/Dependencies/Boost/boost/mpi/detail/mpi_datatype_primitive.hpp

http://hadesmem.googlecode.com/ · C++ Header · 128 lines · 86 code · 30 blank · 12 comment · 2 complexity · c4344c7ac457f1e0c5a65645e6d77e29 MD5 · raw file

  1. // (C) Copyright 2005 Matthias Troyer
  2. // Use, modification and distribution is subject to the Boost Software
  3. // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  4. // http://www.boost.org/LICENSE_1_0.txt)
  5. // Authors: Matthias Troyer
  6. #ifndef BOOST_MPI_DETAIL_MPI_DATATYPE_OPRIMITIVE_HPP
  7. #define BOOST_MPI_DETAIL_MPI_DATATYPE_OPRIMITIVE_HPP
  8. #include <boost/mpi/config.hpp>
  9. #include <cstddef> // size_t
  10. #include <boost/config.hpp>
  11. #if defined(BOOST_NO_STDC_NAMESPACE)
  12. namespace std{
  13. using ::size_t;
  14. } // namespace std
  15. #endif
  16. #include <boost/mpi/datatype_fwd.hpp>
  17. #include <boost/mpi/exception.hpp>
  18. #include <boost/throw_exception.hpp>
  19. #include <boost/assert.hpp>
  20. #include <boost/mpl/placeholders.hpp>
  21. #include <boost/serialization/array.hpp>
  22. #include <boost/serialization/detail/get_data.hpp>
  23. #include <stdexcept>
  24. #include <iostream>
  25. #include <vector>
  26. namespace boost { namespace mpi { namespace detail {
  27. /////////////////////////////////////////////////////////////////////////
  28. // class mpi_data_type_oprimitive - creation of custom MPI data types
  29. class mpi_datatype_primitive
  30. {
  31. public:
  32. // trivial default constructor
  33. mpi_datatype_primitive()
  34. : is_committed(false),
  35. origin(0)
  36. {}
  37. mpi_datatype_primitive(void const* orig)
  38. : is_committed(false),
  39. origin()
  40. {
  41. BOOST_MPI_CHECK_RESULT(MPI_Address,(const_cast<void*>(orig), &origin));
  42. }
  43. void save_binary(void const *address, std::size_t count)
  44. {
  45. save_impl(address,MPI_BYTE,count);
  46. }
  47. // fast saving of arrays of MPI types
  48. template<class T>
  49. void save_array(serialization::array<T> const& x, unsigned int /* version */)
  50. {
  51. if (x.count())
  52. save_impl(x.address(), boost::mpi::get_mpi_datatype(*x.address()), x.count());
  53. }
  54. typedef is_mpi_datatype<mpl::_1> use_array_optimization;
  55. // create and return the custom MPI data type
  56. MPI_Datatype get_mpi_datatype()
  57. {
  58. if (!is_committed)
  59. {
  60. BOOST_MPI_CHECK_RESULT(MPI_Type_struct,
  61. (
  62. addresses.size(),
  63. boost::serialization::detail::get_data(lengths),
  64. boost::serialization::detail::get_data(addresses),
  65. boost::serialization::detail::get_data(types),
  66. &datatype_
  67. ));
  68. BOOST_MPI_CHECK_RESULT(MPI_Type_commit,(&datatype_));
  69. is_committed = true;
  70. }
  71. return datatype_;
  72. }
  73. // default saving of primitives.
  74. template<class T>
  75. void save(const T & t)
  76. {
  77. save_impl(&t, boost::mpi::get_mpi_datatype(t), 1);
  78. }
  79. private:
  80. void save_impl(void const * p, MPI_Datatype t, int l)
  81. {
  82. BOOST_ASSERT ( !is_committed );
  83. // store address, type and length
  84. MPI_Aint a;
  85. BOOST_MPI_CHECK_RESULT(MPI_Address,(const_cast<void*>(p), &a));
  86. addresses.push_back(a-origin);
  87. types.push_back(t);
  88. lengths.push_back(l);
  89. }
  90. std::vector<MPI_Aint> addresses;
  91. std::vector<MPI_Datatype> types;
  92. std::vector<int> lengths;
  93. bool is_committed;
  94. MPI_Datatype datatype_;
  95. MPI_Aint origin;
  96. };
  97. } } } // end namespace boost::mpi::detail
  98. #endif // BOOST_MPI_DETAIL_MPI_DATATYPE_OPRIMITIVE_HPP