20#ifndef DUNE_COMMON_PARALLEL_MPIPACK_HH
21#define DUNE_COMMON_PARALLEL_MPIPACK_HH
33 std::vector<char> _buffer;
37 friend struct MPIData<MPIPack>;
38 friend struct MPIData<const MPIPack>;
40 MPIPack(Communication<MPI_Comm> comm, std::size_t size = 0)
47 MPIPack(
const MPIPack&) =
delete;
48 MPIPack& operator = (
const MPIPack& other) =
delete;
49 MPIPack(MPIPack&&) =
default;
50 MPIPack& operator = (MPIPack&& other) =
default;
58 void pack(
const T& data){
59 auto mpidata = getMPIData(data);
60 int size = getPackSize(mpidata.size(), _comm, mpidata.type());
61 constexpr bool has_static_size =
decltype(getMPIData(std::declval<T&>()))::static_size;
63 size += getPackSize(1, _comm, MPI_INT);
64 if (_position + size > 0 &&
size_t(_position + size) > _buffer.size())
65 _buffer.resize(_position + size);
67 int size = mpidata.size();
68 MPI_Pack(&size, 1, MPI_INT, _buffer.data(), _buffer.size(),
71 MPI_Pack(mpidata.ptr(), mpidata.size(),
72 mpidata.type(), _buffer.data(), _buffer.size(),
82 -> std::enable_if_t<
decltype(getMPIData(data))::static_size,
void>
84 auto mpidata = getMPIData(data);
85 MPI_Unpack(_buffer.data(), _buffer.size(), &_position,
86 mpidata.ptr(), mpidata.size(),
87 mpidata.type(), _comm);
96 -> std::enable_if_t<!
decltype(getMPIData(data))::static_size,
void>
98 auto mpidata = getMPIData(data);
100 MPI_Unpack(_buffer.data(), _buffer.size(), &_position,
103 mpidata.resize(size);
104 MPI_Unpack(_buffer.data(), _buffer.size(), &_position,
105 mpidata.ptr(), mpidata.size(),
106 mpidata.type(), _comm);
112 friend MPIPack& operator << (MPIPack& p,
const T& t){
133 MPIPack& write(
const T& t){
141 void resize(
size_t size){
142 _buffer.resize(size);
147 void enlarge(
int s) {
148 _buffer.resize(_buffer.size() + s);
153 size_t size()
const {
154 return _buffer.size();
174 return std::size_t(_position)==_buffer.size();
180 static int getPackSize(
int len,
const MPI_Comm& comm,
const MPI_Datatype& dt){
182 MPI_Pack_size(len, dt, comm, &size);
186 friend bool operator==(
const MPIPack& a,
const MPIPack& b) {
187 return a._buffer == b._buffer && a._comm == b._comm;
189 friend bool operator!=(
const MPIPack& a,
const MPIPack& b) {
196 struct MPIData<P,
std::enable_if_t<std::is_same<std::remove_const_t<P>, MPIPack>::value>> {
198 friend auto getMPIData<P>(P& t);
203 static constexpr bool static_size = std::is_const<P>::value;
206 return (
void*) data_._buffer.data();
213 MPI_Datatype type()
const{
217 void resize(
int size){
Stream & operator>>(Stream &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:237
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:259
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