dune-common 2.8.0
Loading...
Searching...
No Matches
mpipack.hh
Go to the documentation of this file.
1// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2// vi: set et ts=4 sw=2 sts=2:
18#ifndef DUNE_COMMON_PARALLEL_MPIPACK_HH
19#define DUNE_COMMON_PARALLEL_MPIPACK_HH
20
21#include <vector>
22#if HAVE_MPI
23#include <mpi.h>
26
27
28namespace Dune {
29
30 class MPIPack {
31 std::vector<char> _buffer;
32 int _position;
33 MPI_Comm _comm;
34
35 friend struct MPIData<MPIPack>;
36 friend struct MPIData<const MPIPack>;
37 public:
39 : _buffer(size)
40 , _position(0)
41 , _comm(comm)
42 {}
43
44 // Its not valid to copy a MPIPack but you can move it
45 MPIPack(const MPIPack&) = delete;
46 MPIPack& operator = (const MPIPack& other) = delete;
47 MPIPack(MPIPack&&) = default;
48 MPIPack& operator = (MPIPack&& other) = default;
49
55 template<class T>
56 void pack(const T& data){
57 auto mpidata = getMPIData(data);
58 int size = getPackSize(mpidata.size(), _comm, mpidata.type());
59 constexpr bool has_static_size = decltype(getMPIData(std::declval<T&>()))::static_size;
60 if(!has_static_size)
61 size += getPackSize(1, _comm, MPI_INT);
62 if (_position + size > 0 && size_t(_position + size) > _buffer.size()) // resize buffer if necessary
63 _buffer.resize(_position + size);
64 if(!has_static_size){
65 int size = mpidata.size();
66 MPI_Pack(&size, 1, MPI_INT, _buffer.data(), _buffer.size(),
67 &_position, _comm);
68 }
69 MPI_Pack(mpidata.ptr(), mpidata.size(),
70 mpidata.type(), _buffer.data(), _buffer.size(),
71 &_position, _comm);
72 }
73
78 template<class T>
79 auto /*void*/ unpack(T& data)
80 -> std::enable_if_t<decltype(getMPIData(data))::static_size, void>
81 {
82 auto mpidata = getMPIData(data);
83 MPI_Unpack(_buffer.data(), _buffer.size(), &_position,
84 mpidata.ptr(), mpidata.size(),
85 mpidata.type(), _comm);
86 }
87
92 template<class T>
93 auto /*void*/ unpack(T& data)
94 -> std::enable_if_t<!decltype(getMPIData(data))::static_size, void>
95 {
96 auto mpidata = getMPIData(data);
97 int size = 0;
98 MPI_Unpack(_buffer.data(), _buffer.size(), &_position,
99 &size, 1,
100 MPI_INT, _comm);
101 mpidata.resize(size);
102 MPI_Unpack(_buffer.data(), _buffer.size(), &_position,
103 mpidata.ptr(), mpidata.size(),
104 mpidata.type(), _comm);
105 }
106
107
109 template<typename T>
110 friend MPIPack& operator << (MPIPack& p, const T& t){
111 p.pack(t);
112 return p;
113 }
114
116 template<typename T>
117 friend MPIPack& operator >> (MPIPack& p, T& t){
118 p.unpack(t);
119 return p;
120 }
121
123 template<typename T>
124 MPIPack& read(T& t){
125 unpack(t);
126 return *this;
127 }
128
130 template<typename T>
131 MPIPack& write(const T& t){
132 pack(t);
133 return *this;
134 }
135
139 void resize(size_t size){
140 _buffer.resize(size);
141 }
142
145 void enlarge(int s) {
146 _buffer.resize(_buffer.size() + s);
147 }
148
151 size_t size() const {
152 return _buffer.size();
153 }
154
158 void seek(int p){
159 _position = p;
160 }
161
165 int tell() const{
166 return _position;
167 }
168
171 bool eof() const{
172 return std::size_t(_position)==_buffer.size();
173 }
174
178 static int getPackSize(int len, const MPI_Comm& comm, const MPI_Datatype& dt){
179 int size;
180 MPI_Pack_size(len, dt, comm, &size);
181 return size;
182 }
183
184 friend bool operator==(const MPIPack& a, const MPIPack& b) {
185 return a._buffer == b._buffer && a._comm == b._comm;
186 }
187 friend bool operator!=(const MPIPack& a, const MPIPack& b) {
188 return !(a==b);
189 }
190
191 };
192
193 template<class P>
194 struct MPIData<P, std::enable_if_t<std::is_same<std::remove_const_t<P>, MPIPack>::value>> {
195 protected:
196 friend auto getMPIData<P>(P& t);
197 MPIData(P& t) :
198 data_(t)
199 {}
200 public:
201 static constexpr bool static_size = std::is_const<P>::value;
202
203 void* ptr() {
204 return (void*) data_._buffer.data();
205 }
206
207 int size() {
208 return data_.size();
209 }
210
211 MPI_Datatype type() const{
212 return MPI_PACKED;
213 }
214
215 void resize(int size){
216 data_.resize(size);
217 }
218 protected:
220 };
221
222} // end namespace Dune
223
224#endif
225#endif
Interface class to translate objects to a MPI_Datatype, void* and size used for MPI calls.
Implements an utility class that provides MPI's collective communication methods.
STL namespace.
Dune namespace.
Definition alignedallocator.hh:11
auto getMPIData(T &t)
Definition mpidata.hh:41
Collective communication interface and sequential default implementation.
Definition communication.hh:98
Definition mpidata.hh:48
T & data_
Definition mpidata.hh:51
int size() const
Definition mpidata.hh:65
static constexpr bool static_size
Definition mpidata.hh:63
Definition mpipack.hh:30
void enlarge(int s)
Enlarges the internal buffer.
Definition mpipack.hh:145
friend MPIPack & operator>>(MPIPack &p, T &t)
Unpacks data from the object.
Definition mpipack.hh:117
friend MPIPack & operator<<(MPIPack &p, const T &t)
Packs the data into the object. Enlarges the internal buffer if necessary.
Definition mpipack.hh:110
friend bool operator!=(const MPIPack &a, const MPIPack &b)
Definition mpipack.hh:187
size_t size() const
Returns the size of the internal buffer.
Definition mpipack.hh:151
MPIPack & operator=(const MPIPack &other)=delete
MPIPack(Communication< MPI_Comm > comm, std::size_t size=0)
Definition mpipack.hh:38
void pack(const T &data)
Packs the data into the object. Enlarges the internal buffer if necessary.
Definition mpipack.hh:56
auto unpack(T &data) -> std::enable_if_t<!decltype(getMPIData(data))::static_size, void >
Unpacks data from the object.
Definition mpipack.hh:93
auto unpack(T &data) -> std::enable_if_t< decltype(getMPIData(data))::static_size, void >
Unpacks data from the object.
Definition mpipack.hh:79
friend bool operator==(const MPIPack &a, const MPIPack &b)
Definition mpipack.hh:184
MPIPack(const MPIPack &)=delete
void seek(int p)
Sets the position in the buffer where the next pack/unpack operation should take place.
Definition mpipack.hh:158
bool eof() const
Checks whether the end of the buffer is reached.
Definition mpipack.hh:171
void resize(size_t size)
Resizes the internal buffer.
Definition mpipack.hh:139
int tell() const
Gets the position in the buffer where the next pack/unpack operation should take place.
Definition mpipack.hh:165
MPIPack(MPIPack &&)=default
MPIPack & read(T &t)
Unpacks data from the object.
Definition mpipack.hh:124
static int getPackSize(int len, const MPI_Comm &comm, const MPI_Datatype &dt)
Returns the size of the data needed to store the data in an MPIPack. See MPI_Pack_size.
Definition mpipack.hh:178
MPIPack & write(const T &t)
Packs the data into the object. Enlarges the internal buffer if necessary.
Definition mpipack.hh:131
T data(T... args)
T resize(T... args)
T size(T... args)