12 #ifndef SST_CORE_OBJECTCOMMS_H
13 #define SST_CORE_OBJECTCOMMS_H
15 #include "sst/core/serialization/serializer.h"
16 #include "sst/core/warnmacros.h"
18 #ifdef SST_CONFIG_HAVE_MPI
19 DISABLE_WARN_MISSING_OVERRIDE
31 template <
typename dataType>
33 serialize(dataType& data)
40 size_t size = ser.size();
42 std::vector<char> buffer;
45 ser.start_packing(buffer.data(), size);
75 template <
typename dataType>
77 deserialize(std::vector<char>& buffer)
79 dataType* tgt =
nullptr;
83 ser.start_unpacking(buffer.data(), buffer.size());
89 template <
typename dataType>
91 deserialize(std::vector<char>& buffer, dataType& tgt)
95 ser.start_unpacking(buffer.data(), buffer.size());
99 template <
typename dataType>
101 deserialize(
char* buffer,
int blen, dataType& tgt)
105 ser.start_unpacking(buffer, blen);
109 #ifdef SST_CONFIG_HAVE_MPI
110 template <
typename dataType>
112 broadcast(dataType& data,
int root)
115 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
116 if ( root == rank ) {
118 std::vector<char> buffer = Comms::serialize(data);
121 int size = buffer.size();
122 MPI_Bcast(&size, 1, MPI_INT, root, MPI_COMM_WORLD);
125 MPI_Bcast(buffer.data(), buffer.size(), MPI_BYTE, root, MPI_COMM_WORLD);
130 MPI_Bcast(&size, 1, MPI_INT, root, MPI_COMM_WORLD);
133 auto buffer = std::unique_ptr<char[]>(
new char[size]);
134 MPI_Bcast(buffer.get(), size, MPI_BYTE, root, MPI_COMM_WORLD);
137 Comms::deserialize(buffer.get(), size, data);
141 template <
typename dataType>
143 send(
int dest,
int tag, dataType& data)
146 std::vector<char> buffer = Comms::serialize<dataType>(data);
150 int64_t size = buffer.size();
151 MPI_Send(&size, 1, MPI_INT64_T, dest, tag, MPI_COMM_WORLD);
153 int32_t fragment_size = 1000000000;
156 while ( size >= fragment_size ) {
157 MPI_Send(buffer.data() + offset, fragment_size, MPI_BYTE, dest, tag, MPI_COMM_WORLD);
158 size -= fragment_size;
159 offset += fragment_size;
161 MPI_Send(buffer.data() + offset, size, MPI_BYTE, dest, tag, MPI_COMM_WORLD);
164 template <
typename dataType>
166 recv(
int src,
int tag, dataType& data)
171 MPI_Recv(&size, 1, MPI_INT64_T, src, tag, MPI_COMM_WORLD, &status);
174 auto buffer = std::unique_ptr<char[]>(
new char[size]);
176 int32_t fragment_size = 1000000000;
177 int64_t rem_size = size;
179 while ( rem_size >= fragment_size ) {
180 MPI_Recv(buffer.get() + offset, fragment_size, MPI_BYTE, src, tag, MPI_COMM_WORLD, &status);
181 rem_size -= fragment_size;
182 offset += fragment_size;
184 MPI_Recv(buffer.get() + offset, rem_size, MPI_BYTE, src, tag, MPI_COMM_WORLD, &status);
187 Comms::deserialize(buffer.get(), size, data);
190 template <
typename dataType>
192 all_gather(dataType& data, std::vector<dataType>& out_data)
194 int rank = 0, world = 0;
195 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
196 MPI_Comm_size(MPI_COMM_WORLD, &world);
199 std::vector<char> buffer = Comms::serialize(data);
201 size_t sendSize = buffer.size();
205 memset(allSizes,
'\0', world *
sizeof(
int));
206 memset(displ,
'\0', world *
sizeof(
int));
208 MPI_Allgather(&sendSize,
sizeof(
int), MPI_BYTE, &allSizes,
sizeof(
int), MPI_BYTE, MPI_COMM_WORLD);
211 for (
int i = 0; i < world; i++ ) {
212 totalBuf += allSizes[i];
213 if ( i > 0 ) displ[i] = displ[i - 1] + allSizes[i - 1];
216 auto bigBuff = std::unique_ptr<char[]>(
new char[totalBuf]);
218 MPI_Allgatherv(buffer.data(), buffer.size(), MPI_BYTE, bigBuff.get(), allSizes, displ, MPI_BYTE, MPI_COMM_WORLD);
220 out_data.resize(world);
221 for (
int i = 0; i < world; i++ ) {
222 auto* bbuf = bigBuff.get();
223 Comms::deserialize(&bbuf[displ[i]], allSizes[i], out_data[i]);
233 #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:34