]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/mpi/detail/mpi_datatype_primitive.hpp
update sources to v12.2.3
[ceph.git] / ceph / src / boost / boost / mpi / detail / mpi_datatype_primitive.hpp
1 // (C) Copyright 2005 Matthias Troyer
2
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
7 // Authors: Matthias Troyer
8
9 #ifndef BOOST_MPI_DETAIL_MPI_DATATYPE_OPRIMITIVE_HPP
10 #define BOOST_MPI_DETAIL_MPI_DATATYPE_OPRIMITIVE_HPP
11
12 #include <boost/mpi/config.hpp>
13 #include <cstddef> // size_t
14
15 #include <boost/config.hpp>
16 #if defined(BOOST_NO_STDC_NAMESPACE)
17 namespace std{
18 using ::size_t;
19 } // namespace std
20 #endif
21
22 #include <boost/mpi/datatype_fwd.hpp>
23 #include <boost/mpi/exception.hpp>
24 #include <boost/throw_exception.hpp>
25 #include <boost/assert.hpp>
26 #include <boost/mpl/placeholders.hpp>
27 #include <boost/serialization/array.hpp>
28 #include <stdexcept>
29 #include <iostream>
30 #include <vector>
31 #include <boost/mpi/detail/antiques.hpp>
32
33 namespace boost { namespace mpi { namespace detail {
34
35 /////////////////////////////////////////////////////////////////////////
36 // class mpi_data_type_oprimitive - creation of custom MPI data types
37
38 class mpi_datatype_primitive
39 {
40 public:
41
42 // trivial default constructor
43 mpi_datatype_primitive()
44 : is_committed(false),
45 origin(0)
46 {}
47
48 mpi_datatype_primitive(void const* orig)
49 : is_committed(false),
50 origin()
51 {
52 #if defined(MPI_VERSION) && MPI_VERSION >= 2
53 BOOST_MPI_CHECK_RESULT(MPI_Get_address,(const_cast<void*>(orig), &origin));
54 #else
55 BOOST_MPI_CHECK_RESULT(MPI_Address,(const_cast<void*>(orig), &origin));
56 #endif
57 }
58
59 void save_binary(void const *address, std::size_t count)
60 {
61 save_impl(address,MPI_BYTE,count);
62 }
63
64 // fast saving of arrays of MPI types
65 template<class T>
66 void save_array(serialization::array_wrapper<T> const& x, unsigned int /* version */)
67 {
68 if (x.count())
69 save_impl(x.address(), boost::mpi::get_mpi_datatype(*x.address()), x.count());
70 }
71
72 typedef is_mpi_datatype<mpl::_1> use_array_optimization;
73
74 // create and return the custom MPI data type
75 MPI_Datatype get_mpi_datatype()
76 {
77 if (!is_committed)
78 {
79 #if defined(MPI_VERSION) && MPI_VERSION >= 2
80 BOOST_MPI_CHECK_RESULT(MPI_Type_create_struct,
81 (
82 addresses.size(),
83 c_data(lengths),
84 c_data(addresses),
85 c_data(types),
86 &datatype_
87 ));
88 #else
89 BOOST_MPI_CHECK_RESULT(MPI_Type_struct,
90 (
91 addresses.size(),
92 c_data(lengths),
93 c_data(addresses),
94 c_data(types),
95 &datatype_
96 ));
97 #endif
98 BOOST_MPI_CHECK_RESULT(MPI_Type_commit,(&datatype_));
99
100 is_committed = true;
101 }
102
103 return datatype_;
104 }
105
106 // default saving of primitives.
107 template<class T>
108 void save(const T & t)
109 {
110 save_impl(&t, boost::mpi::get_mpi_datatype(t), 1);
111 }
112
113 private:
114
115 void save_impl(void const * p, MPI_Datatype t, int l)
116 {
117 BOOST_ASSERT ( !is_committed );
118
119 // store address, type and length
120
121 MPI_Aint a;
122 #if defined(MPI_VERSION) && MPI_VERSION >= 2
123 BOOST_MPI_CHECK_RESULT(MPI_Get_address,(const_cast<void*>(p), &a));
124 #else
125 BOOST_MPI_CHECK_RESULT(MPI_Address,(const_cast<void*>(p), &a));
126 #endif
127 addresses.push_back(a-origin);
128 types.push_back(t);
129 lengths.push_back(l);
130 }
131
132 std::vector<MPI_Aint> addresses;
133 std::vector<MPI_Datatype> types;
134 std::vector<int> lengths;
135
136 bool is_committed;
137 MPI_Datatype datatype_;
138 MPI_Aint origin;
139 };
140
141
142 } } } // end namespace boost::mpi::detail
143
144
145 #endif // BOOST_MPI_DETAIL_MPI_DATATYPE_OPRIMITIVE_HPP