MADNESS  0.10.1
mpi_archive.h
Go to the documentation of this file.
1 /*
2  This file is part of MADNESS.
3 
4  Copyright (C) 2007,2010 Oak Ridge National Laboratory
5 
6  This program 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 2 of the License, or
9  (at your option) any later version.
10 
11  This program 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 this program; if not, write to the Free Software
18  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 
20  For more information please contact:
21 
22  Robert J. Harrison
23  Oak Ridge National Laboratory
24  One Bethel Valley Road
25  P.O. Box 2008, MS-6367
26 
27  email: harrisonrj@ornl.gov
28  tel: 865-241-3937
29  fax: 865-572-0680
30 */
31 
32 /**
33  \file mpi_archive.h
34  \brief Implements archives to serialize data for MPI.
35  \ingroup serialization
36 */
37 
38 #ifndef MADNESS_WORLD_MPI_ARCHIVE_H__INCLUDED
39 #define MADNESS_WORLD_MPI_ARCHIVE_H__INCLUDED
40 
41 #include <type_traits>
42 #include <madness/world/archive.h>
43 #include <madness/world/world.h>
45 
46 namespace madness {
47  namespace archive {
48 
49  /// \addtogroup serialization
50  /// @{
51 
52  /// Archive allowing serialization and point-to-point communication between processes with MPI.
54  mutable World* world; ///< The world.
55  ProcessID dest; ///< The destination process.
56  int tag; ///< MPI communication tag.
57 
58  public:
59  /// Construct an archive for sending data via MPI.
60 
61  /// \param[in] world The world.
62  /// \param[in] dest The destination process.
63  /// \param[in] tag MPI communication tag.
65  : world(&world), dest(dest), tag(tag) {};
66 
67  /// Serialize data and send it to the destination process.
68 
69  /// The function only appears (due to \c enable_if) if \c T is
70  /// fundamental.
71  /// \tparam T The data type to be sent.
72  /// \param[in] t Pointer to the data to be sent.
73  /// \param[in] n The number of data items to be sent.
74  template <class T>
75  inline
76  typename std::enable_if< is_trivially_serializable<T>::value, void >::type
77  store(const T* t, long n) const {
78  if (n > 0) {
79  world->mpi.Send(t, n, dest, tag);
80  }
81  }
82  };
83 
84  /// Archive allowing deserialization and point-to-point communication between processes with MPI.
86  mutable World* world; ///< The world.
87  ProcessID src; ///< The source process.
88  int tag; ///< MPI communication tag.
89 
90  public:
91  /// Construct an archive for receiving data via MPI.
92 
93  /// \todo Descriptions needed.
94  /// \param[in] world The world.
95  /// \param[in] src The source process.
96  /// \param[in] tag MPI communication tag.
98  : world(&world), src(src), tag(tag) {};
99 
100  /// Receive data from the source process and deserialize it.
101 
102  /// The function only appears (due to \c enable_if) if \c T is
103  /// fundamental.
104  /// \tparam T The data type to receive.
105  /// \param[out] t Pointer to where the data should be stored.
106  /// \param[in] n The number of data items to receive.
107  template <class T>
108  inline
109  typename std::enable_if< is_trivially_serializable<T>::value, void >::type
110  load(T* t, long n) const {
111  if (n > 0) {
112  world->mpi.Recv(t, n, src, tag);
113  }
114  }
115  };
116 
117  /// Archive allowing buffering, serialization of data, and point-to-point communication between processes with MPI.
119  mutable World* world; ///< The world.
120  ProcessID dest; ///< The destination process.
121  int tag; ///< MPI communication tag.
122  const std::size_t bufsize; ///< Size of the buffer.
123  mutable std::vector<unsigned char> v; ///< The buffer.
124  madness::archive::VectorOutputArchive var; ///< Archive for storing the buffer.
125 
126  public:
127  /// Construct an archive for sending data via MPI.
128 
129  /// \param[in] world The world.
130  /// \param[in] dest The destination process.
131  /// \param[in] tag MPI communication tag.
133  : world(&world), dest(dest), tag(tag), bufsize(1024*1024), v(), var(v) {
134  v.reserve(2*bufsize);
135  };
136 
137  /// Serialize data and store it in the buffer.
138 
139  /// The function only appears (due to \c enable_if) if \c T is
140  /// fundamental.
141  /// \tparam T The data type to be serialized.
142  /// \param[in] t Pointer to the data.
143  /// \param[in] n Number of data items to serialize.
144  template <class T>
145  inline
146  typename std::enable_if< is_trivially_serializable<T>::value, void >::type
147  store(const T* t, long n) const {
148  if (v.size() > bufsize) flush();
149  if (n > 0) {
150  var.store(t, n);
151  if (v.size() > bufsize) flush();
152  }
153  }
154 
155  /// Send all data in the buffer to the destination process.
156 
157  /// \todo Check out the "?? why ??" comment.
158  void flush() const {
159  if (v.size()) {
160  world->mpi.Send(v.size(), dest, tag);
161  world->mpi.Send(&v[0], v.size(), dest, tag);
162  v.clear();
163  if (v.capacity() < 2*bufsize)
164  v.reserve(2*bufsize); // ?? why ??
165  }
166  };
167 
168  /// Close the archive (i.e., send any data in the buffer).
169  void close() {
170  flush();
171  };
172 
173  /// Destructor. Close the archive first, which may entail sending data.
175  close();
176  };
177  };
178 
179  /// Archive allowing buffering, deserialization of data, and point-to-point communication between processes with MPI.
181  mutable World* world; ///< The world.
182  ProcessID src; ///< The source process.
183  int tag; ///< MPI communication tag.
184  mutable std::vector<unsigned char> v; ///< The buffer.
185  madness::archive::VectorInputArchive var; ///< Archive for loading the buffer.
186 
187  public:
188  /// Construct an archive for receiving data via MPI.
189 
190  /// \param[in] world The world.
191  /// \param[in] src The source process.
192  /// \param[in] tag MPI communication tag.
194  : world(&world), src(src), tag(tag), v(), var(v) {};
195 
196  /// Deserialize data and store it in the buffer.
197 
198  /// The function only appears (due to \c enable_if) if \c T is
199  /// fundamental.
200  /// \tparam T The data type to be deserialized.
201  /// \param[out] t Pointer to the data.
202  /// \param[in] n Number of data items to serialize.
203  template <class T>
204  inline
205  typename std::enable_if< is_trivially_serializable<T>::value, void >::type
206  load(T* t, long n) const {
207  if (n > 0) {
208  if (!var.nbyte_avail()) {
209  var.rewind();
210  std::size_t m;
211  world->mpi.Recv(m, src, tag);
212  v.resize(m);
213  world->mpi.Recv(v.data(), m, src, tag);
214  }
215  var.load(t, n);
216  }
217  }
218  };
219 
220  /// Implementation of functions for storing the pre/postamble in MPI archives.
221 
222  /// \attention No type checking over MPI streams, for efficiency.
223  /// \tparam T The data type.
224  template <class T>
226  /// Store the preamble.
227 
228  /// \param[in] ar The archive.
229  static void preamble_store(const MPIRawOutputArchive& ar) {};
230 
231  /// Store the postamble.
232 
233  /// \param[in] ar The archive.
234  static inline void postamble_store(const MPIRawOutputArchive& ar) {};
235  };
236 
237  /// Implementation of functions for loading the pre/postamble in MPI archives.
238 
239  /// \attention No type checking over MPI streams, for efficiency.
240  /// \tparam T The data type.
241  template <class T>
243  /// Load the preamble.
244 
245  /// \param[in] ar The archive.
246  static inline void preamble_load(const MPIRawInputArchive& ar) {};
247 
248  /// Load the postamble.
249 
250  /// \param[in] ar The archive.
251  static inline void postamble_load(const MPIRawInputArchive& ar) {};
252  };
253 
254  /// Implementation of functions for storing the pre/postamble in MPI archives.
255 
256  /// \attention No type checking over MPI streams, for efficiency.
257  /// \tparam T The data type.
258  template <class T>
260  /// Store the preamble.
261 
262  /// \param[in] ar The archive.
263  static void preamble_store(const MPIOutputArchive& ar) {};
264 
265  /// Store the postamble.
266 
267  /// \param[in] ar The archive.
268  static inline void postamble_store(const MPIOutputArchive& ar) {};
269  };
270 
271  /// Implementation of functions for loading the pre/postamble in MPI archives.
272 
273  /// \attention No type checking over MPI streams, for efficiency.
274  /// \tparam T The data type.
275  template <class T>
277  /// Load the preamble.
278 
279  /// \param[in] ar The archive.
280  static inline void preamble_load(const MPIInputArchive& ar) {};
281 
282  /// Load the postamble.
283 
284  /// \param[in] ar The archive.
285  static inline void postamble_load(const MPIInputArchive& ar) {};
286  };
287 
288  /// @}
289  }
290 }
291 #endif // MADNESS_WORLD_MPI_ARCHIVE_H__INCLUDED
Interface templates for the archives (serialization).
void Send(const T *buf, long lenbuf, int dest, int tag=SafeMPI::DEFAULT_SEND_RECV_TAG) const
Send array of lenbuf elements to process dest.
Definition: worldmpi.h:347
void Recv(T *buf, long lenbuf, int src, int tag) const
Receive data of up to lenbuf elements from process src.
Definition: worldmpi.h:374
A parallel world class.
Definition: world.h:132
WorldMpiInterface & mpi
MPI interface.
Definition: world.h:202
Base class for input archive classes.
Definition: archive.h:374
Base class for output archive classes.
Definition: archive.h:382
Archive allowing buffering, deserialization of data, and point-to-point communication between process...
Definition: mpi_archive.h:180
MPIInputArchive(World &world, const ProcessID &src, int tag=SafeMPI::MPIAR_TAG)
Construct an archive for receiving data via MPI.
Definition: mpi_archive.h:193
madness::archive::VectorInputArchive var
Archive for loading the buffer.
Definition: mpi_archive.h:185
std::enable_if< is_trivially_serializable< T >::value, void >::type load(T *t, long n) const
Deserialize data and store it in the buffer.
Definition: mpi_archive.h:206
ProcessID src
The source process.
Definition: mpi_archive.h:182
std::vector< unsigned char > v
The buffer.
Definition: mpi_archive.h:184
World * world
The world.
Definition: mpi_archive.h:181
int tag
MPI communication tag.
Definition: mpi_archive.h:183
Archive allowing buffering, serialization of data, and point-to-point communication between processes...
Definition: mpi_archive.h:118
MPIOutputArchive(World &world, const ProcessID &dest, int tag=SafeMPI::MPIAR_TAG)
Construct an archive for sending data via MPI.
Definition: mpi_archive.h:132
void close()
Close the archive (i.e., send any data in the buffer).
Definition: mpi_archive.h:169
void flush() const
Send all data in the buffer to the destination process.
Definition: mpi_archive.h:158
~MPIOutputArchive()
Destructor. Close the archive first, which may entail sending data.
Definition: mpi_archive.h:174
World * world
The world.
Definition: mpi_archive.h:119
int tag
MPI communication tag.
Definition: mpi_archive.h:121
std::enable_if< is_trivially_serializable< T >::value, void >::type store(const T *t, long n) const
Serialize data and store it in the buffer.
Definition: mpi_archive.h:147
madness::archive::VectorOutputArchive var
Archive for storing the buffer.
Definition: mpi_archive.h:124
std::vector< unsigned char > v
The buffer.
Definition: mpi_archive.h:123
ProcessID dest
The destination process.
Definition: mpi_archive.h:120
const std::size_t bufsize
Size of the buffer.
Definition: mpi_archive.h:122
Archive allowing deserialization and point-to-point communication between processes with MPI.
Definition: mpi_archive.h:85
std::enable_if< is_trivially_serializable< T >::value, void >::type load(T *t, long n) const
Receive data from the source process and deserialize it.
Definition: mpi_archive.h:110
MPIRawInputArchive(World &world, const ProcessID &src, int tag=SafeMPI::MPIAR_TAG)
Construct an archive for receiving data via MPI.
Definition: mpi_archive.h:97
int tag
MPI communication tag.
Definition: mpi_archive.h:88
World * world
The world.
Definition: mpi_archive.h:86
ProcessID src
The source process.
Definition: mpi_archive.h:87
Archive allowing serialization and point-to-point communication between processes with MPI.
Definition: mpi_archive.h:53
std::enable_if< is_trivially_serializable< T >::value, void >::type store(const T *t, long n) const
Serialize data and send it to the destination process.
Definition: mpi_archive.h:77
World * world
The world.
Definition: mpi_archive.h:54
int tag
MPI communication tag.
Definition: mpi_archive.h:56
MPIRawOutputArchive(World &world, const ProcessID &dest, int tag=SafeMPI::MPIAR_TAG)
Construct an archive for sending data via MPI.
Definition: mpi_archive.h:64
ProcessID dest
The destination process.
Definition: mpi_archive.h:55
Wraps an archive around an STL vector for input.
Definition: vector_archive.h:101
std::enable_if< madness::is_trivially_serializable< T >::value, void >::type load(T *t, long n) const
Load data from the vector.
Definition: vector_archive.h:121
void rewind() const
Reset the read location to the beginning of the vector.
Definition: vector_archive.h:132
std::size_t nbyte_avail() const
Get the amount of space left to be read from the vector.
Definition: vector_archive.h:139
Wraps an archive around an STL vector for output.
Definition: vector_archive.h:55
std::enable_if< madness::is_trivially_serializable< T >::value, void >::type store(const T *t, long n) const
Appends data to the end of the vector.
Definition: vector_archive.h:79
const double m
Definition: gfit.cc:199
auto T(World &world, response_space &f) -> response_space
Definition: global_functions.cc:34
static const int MPIAR_TAG
Definition: safempi.h:105
File holds all helper structures necessary for the CC_Operator and CC2 class.
Definition: DFParameters.h:10
std::string type(const PairType &n)
Definition: PNOParameters.h:18
static void preamble_load(const MPIInputArchive &ar)
Load the preamble.
Definition: mpi_archive.h:280
static void postamble_load(const MPIInputArchive &ar)
Load the postamble.
Definition: mpi_archive.h:285
static void postamble_store(const MPIOutputArchive &ar)
Store the postamble.
Definition: mpi_archive.h:268
static void preamble_store(const MPIOutputArchive &ar)
Store the preamble.
Definition: mpi_archive.h:263
static void preamble_load(const MPIRawInputArchive &ar)
Load the preamble.
Definition: mpi_archive.h:246
static void postamble_load(const MPIRawInputArchive &ar)
Load the postamble.
Definition: mpi_archive.h:251
static void preamble_store(const MPIRawOutputArchive &ar)
Store the preamble.
Definition: mpi_archive.h:229
static void postamble_store(const MPIRawOutputArchive &ar)
Store the postamble.
Definition: mpi_archive.h:234
Default implementation of the pre/postamble for type checking.
Definition: archive.h:509
Implements an archive wrapping an STL vector.
Declares the World class for the parallel runtime environment.
int ProcessID
Used to clearly identify process number/rank.
Definition: worldtypes.h:43