OPAL (Object Oriented Parallel Accelerator Library)  2.2.0
OPAL
MPIHelper.cpp
Go to the documentation of this file.
1 #include <string.h>
2 
3 #include <boost/static_assert.hpp>
4 #include <boost/serialization/map.hpp>
5 
6 #include <boost/archive/text_oarchive.hpp>
7 #include <boost/archive/text_iarchive.hpp>
8 
9 #include "Util/MPIHelper.h"
10 
11 void serialize(Param_t params, std::ostringstream &os) {
12 
13  boost::archive::text_oarchive oa(os);
14  oa << params;
15 }
16 
17 void serialize(reqVarContainer_t reqvars, std::ostringstream &os) {
18 
19  boost::archive::text_oarchive oa(os);
20  oa << reqvars;
21 }
22 
23 void deserialize(char *buffer, Param_t &params) {
24 
25  params.clear();
26  std::istringstream is(buffer);
27  boost::archive::text_iarchive ia(is);
28  ia >> params;
29 }
30 
31 void deserialize(char *buffer, reqVarContainer_t &reqvars) {
32 
33  reqvars.clear();
34  std::istringstream is(buffer);
35  boost::archive::text_iarchive ia(is);
36  ia >> reqvars;
37 }
38 
39 void MPI_Bcast_params(Param_t &params, size_t root, MPI_Comm comm) {
40 
41  int pid = 0;
42  size_t my_pid = 0;
43  MPI_Comm_rank(comm, &pid);
44  my_pid = static_cast<size_t>(pid);
45 
46  size_t buf_size = 0;
47  std::ostringstream os;
48 
49  if(my_pid == root) {
50  serialize(params, os);
51  buf_size = os.str().length() + 1; // +1 for null-termination
52  }
53 
54  MPI_Bcast(&buf_size, 1, MPI_UNSIGNED_LONG, root, comm);
55 
56  char *buffer = new char[buf_size];
57  if(my_pid == root) memcpy(buffer, os.str().c_str(), buf_size);
58 
59  MPI_Bcast(buffer, buf_size, MPI_CHAR, root, comm);
60  if(my_pid != root) deserialize(buffer, params);
61 
62  delete[] buffer;
63 }
64 
65 
66 void MPI_Send_params(Param_t params, size_t pid, MPI_Comm comm) {
67 
68  std::ostringstream os;
69  serialize(params, os);
70  size_t buf_size = os.str().length() + 1; // +1 for null-termination
71 
72  MPI_Send(&buf_size, 1, MPI_UNSIGNED_LONG, pid,
74 
75  char *buffer = new char[buf_size];
76  memcpy(buffer, os.str().c_str(), buf_size);
77 
78  MPI_Send(buffer, buf_size, MPI_CHAR, pid,
80 
81  delete[] buffer;
82 }
83 
84 std::pair<size_t*, char*> MPI_ISend_params(Param_t params, size_t pid,
85  MPI_Comm comm, MPI_Request *req) {
86 
87  std::ostringstream os;
88  serialize(params, os);
89  size_t* buf_size = new size_t();
90  *buf_size = os.str().length() + 1; // +1 for null-termination
91 
92  MPI_Isend(buf_size, 1, MPI_UNSIGNED_LONG, pid,
94 
95  char *buffer = new char[*buf_size];
96  memcpy(buffer, os.str().c_str(), *buf_size);
97 
98  MPI_Isend(buffer, *buf_size, MPI_CHAR, pid,
100 
101  std::pair<size_t*, char*> p(buf_size, buffer);
102 
103  return p;
104 }
105 
106 
107 void MPI_Recv_params(Param_t &params, size_t pid, MPI_Comm comm) {
108 
109  MPI_Status status;
110  size_t buf_size = 0;
111  MPI_Recv(&buf_size, 1, MPI_UNSIGNED_LONG, pid,
112  MPI_EXCHANGE_SERIALIZED_DATA_TAG, comm, &status);
113 
114  char *buffer = new char[buf_size]();
115 
116  MPI_Recv(buffer, buf_size, MPI_CHAR, pid,
117  MPI_EXCHANGE_SERIALIZED_DATA_TAG, comm, &status);
118 
119  deserialize(buffer, params);
120 
121  delete[] buffer;
122 }
123 
124 
125 void MPI_Send_reqvars(reqVarContainer_t reqvars, size_t pid, MPI_Comm comm) {
126 
127  std::ostringstream os;
128  serialize(reqvars, os);
129  size_t buf_size = os.str().length() + 1; // +1 for null-termination
130 
131  MPI_Send(&buf_size, 1, MPI_UNSIGNED_LONG, pid,
133 
134  char *buffer = new char[buf_size];
135  memcpy(buffer, os.str().c_str(), buf_size);
136 
137  MPI_Send(buffer, buf_size, MPI_CHAR, pid,
139 
140  delete[] buffer;
141 }
142 
143 
144 void MPI_Recv_reqvars(reqVarContainer_t &reqvars, size_t pid, MPI_Comm comm) {
145 
146  MPI_Status status;
147  size_t buf_size = 0;
148  MPI_Recv(&buf_size, 1, MPI_UNSIGNED_LONG, pid,
149  MPI_EXCHANGE_SERIALIZED_DATA_TAG, comm, &status);
150 
151  char *buffer = new char[buf_size]();
152 
153  MPI_Recv(buffer, buf_size, MPI_CHAR, pid,
154  MPI_EXCHANGE_SERIALIZED_DATA_TAG, comm, &status);
155 
156  deserialize(buffer, reqvars);
157 
158  delete[] buffer;
159 }
160 
std::map< std::string, reqVarInfo_t > reqVarContainer_t
Definition: Types.h:64
std::pair< size_t *, char * > MPI_ISend_params(Param_t params, size_t pid, MPI_Comm comm, MPI_Request *req)
Definition: MPIHelper.cpp:84
#define MPI_EXCHANGE_SERIALIZED_DATA_TAG
tag for exchanging serialized data
Definition: MPIHelper.h:47
void serialize(Param_t params, std::ostringstream &os)
serializes params using Boost archive
Definition: MPIHelper.cpp:11
void MPI_Send_reqvars(reqVarContainer_t reqvars, size_t pid, MPI_Comm comm)
Definition: MPIHelper.cpp:125
namedVariableCollection_t Param_t
Definition: Types.h:33
void deserialize(char *buffer, Param_t &params)
deserializes params using Boost archive
Definition: MPIHelper.cpp:23
void MPI_Recv_params(Param_t &params, size_t pid, MPI_Comm comm)
Definition: MPIHelper.cpp:107
void MPI_Send_params(Param_t params, size_t pid, MPI_Comm comm)
Definition: MPIHelper.cpp:66
void MPI_Recv_reqvars(reqVarContainer_t &reqvars, size_t pid, MPI_Comm comm)
Definition: MPIHelper.cpp:144
void MPI_Bcast_params(Param_t &params, size_t root, MPI_Comm comm)
broadcast params to all entities in comm
Definition: MPIHelper.cpp:39