18#ifndef DUNE_COMMON_PARALLEL_MPIPACK_HH
19#define DUNE_COMMON_PARALLEL_MPIPACK_HH
31 std::vector<char> _buffer;
35 friend struct MPIData<MPIPack>;
36 friend struct MPIData<const MPIPack>;
38 MPIPack(Communication<MPI_Comm> comm, std::size_t size = 0)
45 MPIPack(
const MPIPack&) =
delete;
46 MPIPack& operator = (
const MPIPack& other) =
delete;
47 MPIPack(MPIPack&&) =
default;
48 MPIPack& operator = (MPIPack&& other) =
default;
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;
61 size += getPackSize(1, _comm, MPI_INT);
62 if (_position + size > 0 &&
size_t(_position + size) > _buffer.size())
63 _buffer.resize(_position + size);
65 int size = mpidata.size();
66 MPI_Pack(&size, 1, MPI_INT, _buffer.data(), _buffer.size(),
69 MPI_Pack(mpidata.ptr(), mpidata.size(),
70 mpidata.type(), _buffer.data(), _buffer.size(),
80 -> std::enable_if_t<
decltype(getMPIData(data))::static_size,
void>
82 auto mpidata = getMPIData(data);
83 MPI_Unpack(_buffer.data(), _buffer.size(), &_position,
84 mpidata.ptr(), mpidata.size(),
85 mpidata.type(), _comm);
94 -> std::enable_if_t<!
decltype(getMPIData(data))::static_size,
void>
96 auto mpidata = getMPIData(data);
98 MPI_Unpack(_buffer.data(), _buffer.size(), &_position,
101 mpidata.resize(size);
102 MPI_Unpack(_buffer.data(), _buffer.size(), &_position,
103 mpidata.ptr(), mpidata.size(),
104 mpidata.type(), _comm);
110 friend MPIPack& operator << (MPIPack& p,
const T& t){
131 MPIPack& write(
const T& t){
139 void resize(
size_t size){
140 _buffer.resize(size);
145 void enlarge(
int s) {
146 _buffer.resize(_buffer.size() + s);
151 size_t size()
const {
152 return _buffer.size();
172 return std::size_t(_position)==_buffer.size();
178 static int getPackSize(
int len,
const MPI_Comm& comm,
const MPI_Datatype& dt){
180 MPI_Pack_size(len, dt, comm, &size);
184 friend bool operator==(
const MPIPack& a,
const MPIPack& b) {
185 return a._buffer == b._buffer && a._comm == b._comm;
187 friend bool operator!=(
const MPIPack& a,
const MPIPack& b) {
194 struct MPIData<P,
std::enable_if_t<std::is_same<std::remove_const_t<P>, MPIPack>::value>> {
196 friend auto getMPIData<P>(P& t);
201 static constexpr bool static_size = std::is_const<P>::value;
204 return (
void*) data_._buffer.data();
211 MPI_Datatype type()
const{
215 void resize(
int size){
Stream & operator>>(Stream &stream, std::tuple< Ts... > &t)
Read a std::tuple.
Definition: streamoperators.hh:41
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:235
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:257
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:14