MPIPacker.hpp
Go to the documentation of this file.
1/*
2 Copyright 2019 Equinor AS.
3
4 This file is part of the Open Porous Media project (OPM).
5
6 OPM is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 3 of the License, or
9 (at your option) any later version.
10
11 OPM is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with OPM. If not, see <http://www.gnu.org/licenses/>.
18*/
19#ifndef MPI_PACKER_HPP
20#define MPI_PACKER_HPP
21
22#include <opm/common/utility/TimeService.hpp>
24
25#include <dune/common/parallel/mpitraits.hh>
26
27#include <bitset>
28#include <cstddef>
29#include <string>
30
31namespace Opm {
32namespace Mpi {
33namespace detail {
34
36template <bool pod, class T>
37struct Packing
38{
39 static std::size_t packSize(const T&, Parallel::MPIComm);
40 static void pack(const T&, std::vector<char>&, int&, Parallel::MPIComm);
41 static void unpack(T&, std::vector<char>&, int&, Parallel::MPIComm);
42};
43
45template<class T>
46struct Packing<true,T>
47{
51 static std::size_t packSize(const T& data, Parallel::MPIComm comm)
52 {
53 return packSize(&data, 1, comm);
54 }
55
60 static std::size_t packSize(const T*, std::size_t n, Parallel::MPIComm comm)
61 {
62 int size = 0;
63 MPI_Pack_size(n, Dune::MPITraits<T>::getType(), comm, &size);
64 return size;
65 }
66
72 static void pack(const T& data,
73 std::vector<char>& buffer,
74 int& position,
76 {
77 pack(&data, 1, buffer, position, comm);
78 }
79
86 static void pack(const T* data,
87 std::size_t n,
88 std::vector<char>& buffer,
89 int& position,
91 {
92 MPI_Pack(data, n, Dune::MPITraits<T>::getType(), buffer.data(),
93 buffer.size(), &position, comm);
94 }
95
101 static void unpack(T& data,
102 std::vector<char>& buffer,
103 int& position,
105 {
106 unpack(&data, 1, buffer, position, comm);
107 }
108
115 static void unpack(T* data,
116 std::size_t n,
117 std::vector<char>& buffer,
118 int& position,
120 {
121 MPI_Unpack(buffer.data(), buffer.size(), &position, data, n,
123 }
124};
125
127template<class T>
128struct Packing<false,T>
129{
130 static std::size_t packSize(const T&, Parallel::MPIComm)
131 {
132 static_assert(!std::is_same_v<T,T>, "Packing not supported for type");
133 return 0;
134 }
135
136 static void pack(const T&, std::vector<char>&, int&,
138 {
139 static_assert(!std::is_same_v<T,T>, "Packing not supported for type");
140 }
141
142 static void unpack(T&, std::vector<char>&, int&,
144 {
145 static_assert(!std::is_same_v<T,T>, "Packing not supported for type");
146 }
147};
148
150template <std::size_t Size>
151struct Packing<false,std::bitset<Size>>
152{
153 static std::size_t packSize(const std::bitset<Size>&, Opm::Parallel::MPIComm);
154 static void pack(const std::bitset<Size>&, std::vector<char>&, int&, Opm::Parallel::MPIComm);
155 static void unpack(std::bitset<Size>&, std::vector<char>&, int&, Opm::Parallel::MPIComm);
156};
157
158#define ADD_PACK_SPECIALIZATION(T) \
159 template<> \
160 struct Packing<false,T> \
161 { \
162 static std::size_t packSize(const T&, Parallel::MPIComm); \
163 static void pack(const T&, std::vector<char>&, int&, Parallel::MPIComm); \
164 static void unpack(T&, std::vector<char>&, int&, Parallel::MPIComm); \
165 };
166
167ADD_PACK_SPECIALIZATION(std::string)
168ADD_PACK_SPECIALIZATION(time_point)
169
170#undef ADD_PACK_SPECIALIZATION
171
172}
173
175struct Packer {
179 : m_comm(comm)
180 {}
181
185 template<class T>
186 std::size_t packSize(const T& data) const
187 {
188 return detail::Packing<std::is_pod_v<T>,T>::packSize(data, m_comm);
189 }
190
195 template<class T>
196 std::size_t packSize(const T* data, std::size_t n) const
197 {
198 static_assert(std::is_pod_v<T>, "Array packing not supported for non-pod data");
199 return detail::Packing<true,T>::packSize(data, n, m_comm);
200 }
201
207 template<class T>
208 void pack(const T& data,
209 std::vector<char>& buffer,
210 int& position) const
211 {
212 detail::Packing<std::is_pod_v<T>,T>::pack(data, buffer, position, m_comm);
213 }
214
221 template<class T>
222 void pack(const T* data,
223 std::size_t n,
224 std::vector<char>& buffer,
225 int& position) const
226 {
227 static_assert(std::is_pod_v<T>, "Array packing not supported for non-pod data");
228 detail::Packing<true,T>::pack(data, n, buffer, position, m_comm);
229 }
230
236 template<class T>
237 void unpack(T& data,
238 std::vector<char>& buffer,
239 int& position) const
240 {
241 detail::Packing<std::is_pod_v<T>,T>::unpack(data, buffer, position, m_comm);
242 }
243
250 template<class T>
251 void unpack(T* data,
252 std::size_t n,
253 std::vector<char>& buffer,
254 int& position) const
255 {
256 static_assert(std::is_pod_v<T>, "Array packing not supported for non-pod data");
257 detail::Packing<true,T>::unpack(data, n, buffer, position, m_comm);
258 }
259
260private:
262};
263
264} // end namespace Mpi
265} // end namespace Opm
266
267#endif // MPI_PACKER_HPP
#define ADD_PACK_SPECIALIZATION(T)
Definition: MPIPacker.hpp:158
Dune::Communication< MPIComm > Communication
Definition: ParallelCommunication.hpp:30
typename Dune::MPIHelper::MPICommunicator MPIComm
Definition: ParallelCommunication.hpp:29
TYPE getType(const TABLE &table)
Definition: BlackoilPhases.hpp:27
Struct handling packing of serialization for MPI communication.
Definition: MPIPacker.hpp:175
void unpack(T *data, std::size_t n, std::vector< char > &buffer, int &position) const
Unpack an array.
Definition: MPIPacker.hpp:251
void pack(const T *data, std::size_t n, std::vector< char > &buffer, int &position) const
Pack an array.
Definition: MPIPacker.hpp:222
Packer(Parallel::Communication comm)
Constructor.
Definition: MPIPacker.hpp:178
std::size_t packSize(const T *data, std::size_t n) const
Calculates the pack size for an array.
Definition: MPIPacker.hpp:196
void pack(const T &data, std::vector< char > &buffer, int &position) const
Pack a variable.
Definition: MPIPacker.hpp:208
std::size_t packSize(const T &data) const
Calculates the pack size for a variable.
Definition: MPIPacker.hpp:186
void unpack(T &data, std::vector< char > &buffer, int &position) const
Unpack a variable.
Definition: MPIPacker.hpp:237
static void pack(const T &, std::vector< char > &, int &, Parallel::MPIComm)
Definition: MPIPacker.hpp:136
static std::size_t packSize(const T &, Parallel::MPIComm)
Definition: MPIPacker.hpp:130
static void unpack(T &, std::vector< char > &, int &, Parallel::MPIComm)
Definition: MPIPacker.hpp:142
static void pack(const std::bitset< Size > &, std::vector< char > &, int &, Opm::Parallel::MPIComm)
static void unpack(std::bitset< Size > &, std::vector< char > &, int &, Opm::Parallel::MPIComm)
static std::size_t packSize(const std::bitset< Size > &, Opm::Parallel::MPIComm)
static void unpack(T &data, std::vector< char > &buffer, int &position, Parallel::MPIComm comm)
Unpack a POD.
Definition: MPIPacker.hpp:101
static void pack(const T *data, std::size_t n, std::vector< char > &buffer, int &position, Parallel::MPIComm comm)
Pack an array of POD.
Definition: MPIPacker.hpp:86
static std::size_t packSize(const T *, std::size_t n, Parallel::MPIComm comm)
Calculates the pack size for an array of POD.
Definition: MPIPacker.hpp:60
static void unpack(T *data, std::size_t n, std::vector< char > &buffer, int &position, Parallel::MPIComm comm)
Unpack an array of POD.
Definition: MPIPacker.hpp:115
static void pack(const T &data, std::vector< char > &buffer, int &position, Parallel::MPIComm comm)
Pack a POD.
Definition: MPIPacker.hpp:72
static std::size_t packSize(const T &data, Parallel::MPIComm comm)
Calculates the pack size for a POD.
Definition: MPIPacker.hpp:51
Abstract struct for packing which is (partially) specialized for specific types.
Definition: MPIPacker.hpp:38
static std::size_t packSize(const T &, Parallel::MPIComm)
static void unpack(T &, std::vector< char > &, int &, Parallel::MPIComm)
static void pack(const T &, std::vector< char > &, int &, Parallel::MPIComm)