My Project
Loading...
Searching...
No Matches
MPIPacker.hpp
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>
23#include <opm/simulators/utils/ParallelCommunication.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,
75 Parallel::MPIComm comm)
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,
90 Parallel::MPIComm comm)
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,
104 Parallel::MPIComm comm)
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,
119 Parallel::MPIComm comm)
120 {
121 MPI_Unpack(buffer.data(), buffer.size(), &position, data, n,
122 Dune::MPITraits<T>::getType(), comm);
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&,
137 Parallel::MPIComm)
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&,
143 Parallel::MPIComm)
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 {
178 Packer(Parallel::Communication comm)
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 {
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");
229 }
230
236 template<class T>
237 void unpack(T& data,
238 std::vector<char>& buffer,
239 int& position) const
240 {
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");
258 }
259
260private:
261 Parallel::Communication m_comm;
262};
263
264} // end namespace Mpi
265} // end namespace Opm
266
267#endif // MPI_PACKER_HPP
Definition AquiferInterface.hpp:35
This file contains a set of helper functions used by VFPProd / VFPInj.
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 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