20#ifndef DUNE_COMMON_PARALLEL_MPIPACK_HH
21#define DUNE_COMMON_PARALLEL_MPIPACK_HH
37 std::vector<char> _buffer;
41 friend struct MPIData<MPIPack>;
42 friend struct MPIData<const MPIPack>;
44 MPIPack(Communication<MPI_Comm> comm, std::size_t
size = 0)
51 MPIPack(
const MPIPack&) =
delete;
52 MPIPack& operator = (
const MPIPack& other) =
delete;
53 MPIPack(MPIPack&&) =
default;
54 MPIPack& operator = (MPIPack&& other) =
default;
62 void pack(
const T& data){
63 auto mpidata = getMPIData(data);
64 int size = getPackSize(mpidata.size(), _comm, mpidata.type());
65 constexpr bool has_static_size =
decltype(getMPIData(std::declval<T&>()))::static_size;
67 size += getPackSize(1, _comm, MPI_INT);
68 if (_position +
size > 0 &&
size_t(_position +
size) > _buffer.size())
69 _buffer.resize(_position +
size);
71 int size = mpidata.size();
72 MPI_Pack(&
size, 1, MPI_INT, _buffer.data(), _buffer.size(),
75 MPI_Pack(mpidata.ptr(), mpidata.size(),
76 mpidata.type(), _buffer.data(), _buffer.size(),
86 -> std::enable_if_t<
decltype(getMPIData(data))::static_size,
void>
88 auto mpidata = getMPIData(data);
89 MPI_Unpack(_buffer.data(), _buffer.size(), &_position,
90 mpidata.ptr(), mpidata.size(),
91 mpidata.type(), _comm);
100 -> std::enable_if_t<!
decltype(getMPIData(data))::static_size,
void>
102 auto mpidata = getMPIData(data);
104 MPI_Unpack(_buffer.data(), _buffer.size(), &_position,
107 mpidata.resize(
size);
108 MPI_Unpack(_buffer.data(), _buffer.size(), &_position,
109 mpidata.ptr(), mpidata.size(),
110 mpidata.type(), _comm);
116 friend MPIPack& operator << (MPIPack& p,
const T& t){
137 MPIPack& write(
const T& t){
145 void resize(
size_t size){
146 _buffer.resize(
size);
151 void enlarge(
int s) {
152 _buffer.resize(_buffer.size() + s);
157 size_t size()
const {
158 return _buffer.size();
178 return std::size_t(_position)==_buffer.size();
184 static int getPackSize(
int len,
const MPI_Comm& comm,
const MPI_Datatype& dt){
186 MPI_Pack_size(len, dt, comm, &
size);
190 friend bool operator==(
const MPIPack& a,
const MPIPack& b) {
191 return a._buffer == b._buffer && a._comm == b._comm;
193 friend bool operator!=(
const MPIPack& a,
const MPIPack& b) {
200 struct MPIData<P,
std::enable_if_t<std::is_same<std::remove_const_t<P>, MPIPack>::value>> {
202 friend auto getMPIData<P>(P& t);
207 static constexpr bool static_size = std::is_const<P>::value;
210 return (
void*) data_._buffer.data();
217 MPI_Datatype type()
const{
221 void resize(
int size){
std::istream & operator>>(std::istream &stream, std::tuple< Ts... > &t)
Read a std::tuple.
Definition: streamoperators.hh:43
EnableIfInterOperable< T1, T2, bool >::type operator==(const ForwardIteratorFacade< T1, V1, R1, D > &lhs, const ForwardIteratorFacade< T2, V2, R2, D > &rhs)
Checks for equality.
Definition: iteratorfacades.hh:238
EnableIfInterOperable< T1, T2, bool >::type operator!=(const ForwardIteratorFacade< T1, V1, R1, D > &lhs, const ForwardIteratorFacade< T2, V2, R2, D > &rhs)
Checks for inequality.
Definition: iteratorfacades.hh:260
Implements an utility class that provides MPI's collective communication methods.
Interface class to translate objects to a MPI_Datatype, void* and size used for MPI calls.
Dune namespace.
Definition: alignedallocator.hh:13
constexpr std::integral_constant< std::size_t, sizeof...(II)> size(std::integer_sequence< T, II... >)
Return the size of the sequence.
Definition: integersequence.hh:75