13 #ifndef SST_CORE_OBJECTCOMMS_H
14 #define SST_CORE_OBJECTCOMMS_H
16 #ifdef SST_CONFIG_HAVE_MPI
20 #include <sst/core/serialization/serializer.h>
29 template <
typename dataType>
30 std::vector<char> serialize(dataType &data)
37 int size = ser.size();
39 std::vector<char> buffer;
42 ser.start_packing(buffer.data(),size);
73 template <
typename dataType>
74 dataType* deserialize(std::vector<char> &buffer)
80 ser.start_unpacking(buffer.data(), buffer.size());
86 template <
typename dataType>
87 void deserialize(std::vector<char> &buffer, dataType &tgt)
91 ser.start_unpacking(buffer.data(), buffer.size());
95 template <
typename dataType>
96 void deserialize(
char *buffer,
int blen, dataType &tgt)
100 ser.start_unpacking(buffer, blen);
104 #ifdef SST_CONFIG_HAVE_MPI
105 template <
typename dataType>
106 void broadcast(dataType& data,
int root) {
108 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
109 if ( root == rank ) {
111 std::vector<char> buffer = Comms::serialize(data);
114 int size = buffer.size();
115 MPI_Bcast(&size, 1, MPI_INT, root, MPI_COMM_WORLD);
118 MPI_Bcast(buffer.data(), buffer.size(), MPI_BYTE, root, MPI_COMM_WORLD);
123 MPI_Bcast(&size, 1, MPI_INT, root, MPI_COMM_WORLD);
126 char* buffer =
new char[size];
127 MPI_Bcast(buffer, size, MPI_BYTE, root, MPI_COMM_WORLD);
130 Comms::deserialize(buffer, size, data);
134 template <
typename dataType>
135 void send(
int dest,
int tag, dataType& data) {
137 std::vector<char> buffer = Comms::serialize<dataType>(data);
141 int64_t size = buffer.size();
142 MPI_Send(&size, 1, MPI_INT64_T, dest, tag, MPI_COMM_WORLD);
144 int32_t fragment_size = 1000000000;
147 while ( size >= fragment_size ) {
148 MPI_Send(buffer.data() + offset, fragment_size, MPI_BYTE, dest, tag, MPI_COMM_WORLD);
149 size -= fragment_size;
150 offset += fragment_size;
152 MPI_Send(buffer.data() + offset, size, MPI_BYTE, dest, tag, MPI_COMM_WORLD);
155 template <
typename dataType>
156 void recv(
int src,
int tag, dataType& data) {
160 MPI_Recv(&size, 1, MPI_INT64_T, src, tag, MPI_COMM_WORLD, &status);
163 char* buffer =
new char[size];
165 int32_t fragment_size = 1000000000;
166 int64_t rem_size = size;
168 while ( rem_size >= fragment_size ) {
169 MPI_Recv(buffer + offset, fragment_size, MPI_BYTE, src, tag, MPI_COMM_WORLD, &status);
170 rem_size -= fragment_size;
171 offset += fragment_size;
173 MPI_Recv(buffer + offset, rem_size, MPI_BYTE, src, tag, MPI_COMM_WORLD, &status);
177 Comms::deserialize(buffer, size, data);
181 template <
typename dataType>
182 void all_gather(dataType& data, std::vector<dataType> &out_data) {
183 int rank = 0, world = 0;
184 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
185 MPI_Comm_size(MPI_COMM_WORLD, &world);
188 std::vector<char> buffer = Comms::serialize(data);
191 size_t sendSize = buffer.size();
195 memset(allSizes,
'\0', world *
sizeof(
int));
196 memset(displ,
'\0', world *
sizeof(
int));
198 MPI_Allgather(&sendSize,
sizeof(
int), MPI_BYTE,
199 &allSizes,
sizeof(
int), MPI_BYTE, MPI_COMM_WORLD);
202 for (
int i = 0 ; i < world ; i++ ) {
203 totalBuf += allSizes[i];
205 displ[i] = displ[i-1] + allSizes[i-1];
208 char *bigBuff =
new char[totalBuf];
210 MPI_Allgatherv(buffer.data(), buffer.size(), MPI_BYTE,
211 bigBuff, allSizes, displ, MPI_BYTE, MPI_COMM_WORLD);
213 out_data.resize(world);
214 for (
int i = 0 ; i < world ; i++ ) {
215 Comms::deserialize(&bigBuff[displ[i]], allSizes[i], out_data[i]);
231 #endif // SST_CORE_OBJECTCOMMS_H
This class is basically a wrapper for objects to declare the order in which their members should be s...
Definition: serializer.h:35