20 template<
typename cpp_t>
struct mpi_tt {};
22 #define define_mpi_tt(CT, ME) \ 23 template<> struct mpi_tt<CT> { static MPI_Datatype datatype(){ return ME; } }; 25 define_mpi_tt(
float, MPI_FLOAT)
26 define_mpi_tt(
double, MPI_DOUBLE)
27 define_mpi_tt(
char, MPI_CHAR)
28 define_mpi_tt(
signed char, MPI_CHAR)
29 define_mpi_tt(
short, MPI_SHORT)
30 define_mpi_tt(
int, MPI_INT)
31 define_mpi_tt(
long, MPI_LONG)
32 define_mpi_tt(
long long, MPI_LONG_LONG)
33 define_mpi_tt(
unsigned char, MPI_UNSIGNED_CHAR)
34 define_mpi_tt(
unsigned short, MPI_UNSIGNED_SHORT)
35 define_mpi_tt(
unsigned int, MPI_UNSIGNED)
36 define_mpi_tt(
unsigned long, MPI_UNSIGNED_LONG)
37 define_mpi_tt(
unsigned long long, MPI_UNSIGNED_LONG_LONG)
45 template<
typename cpp_t>
48 MPI_Allreduce(MPI_IN_PLACE, vec.data(), vec.size(),
49 mpi_tt<cpp_t>::datatype(), MPI_SUM, comm);
71 template <
typename cpp_t>
72 void GlobalBounds(MPI_Comm comm,
const std::vector<std::array<cpp_t,6>> &lbounds,
73 std::array<cpp_t,6> &gbounds)
75 int nLocal = lbounds.size();
77 gbounds = {std::numeric_limits<cpp_t>::max(), std::numeric_limits<cpp_t>::lowest(),
78 std::numeric_limits<cpp_t>::max(), std::numeric_limits<cpp_t>::lowest(),
79 std::numeric_limits<cpp_t>::max(), std::numeric_limits<cpp_t>::lowest()};
82 for (
int q = 0; q < nLocal; ++q)
84 const cpp_t *plbounds = lbounds[q].data();
85 for (
int i = 0; i < 6; ++i)
88 cpp_t lval = plbounds[i];
89 cpp_t gval = gbounds[i];
90 gbounds[i] = useMax ? std::max(gval, lval) : std::min(gval, lval);
95 for (
size_t i = 0; i < 6; i += 2)
96 gbounds[i] = -gbounds[i];
99 MPI_Allreduce(MPI_IN_PLACE, gbounds.data(), 6,
100 mpi_tt<cpp_t>::datatype(), MPI_MAX, comm);
103 for (
size_t i = 0; i < 6; i += 2)
104 gbounds[i] = -gbounds[i];
108 template <
typename cpp_t>
109 void GlobalRange(MPI_Comm comm,
const std::vector<std::array<cpp_t,2>> &lrange,
110 std::array<cpp_t,2> &grange)
112 int nLocal = lrange.size();
114 grange = {std::numeric_limits<cpp_t>::max(),
115 std::numeric_limits<cpp_t>::lowest()};
118 for (
int q = 0; q < nLocal; ++q)
120 const cpp_t *plrange = lrange[q].data();
121 grange[0] = std::min(grange[0], plrange[0]);
122 grange[1] = std::max(grange[1], plrange[1]);
126 grange[0] = -grange[0];
129 MPI_Allreduce(MPI_IN_PLACE, grange.data(), 2,
130 mpi_tt<cpp_t>::datatype(), MPI_MAX, comm);
133 grange[0] = -grange[0];
140 template <
typename cpp_t>
141 void GlobalView(MPI_Comm comm,
const std::vector<cpp_t> &ldata,
142 std::vector<cpp_t> &gdata)
147 MPI_Comm_rank(comm, &rank);
148 MPI_Comm_size(comm, &nRanks);
150 int nLocal = ldata.size();
152 gdata.resize(nRanks*nLocal);
153 for (
int i = 0; i < nLocal; ++i)
154 gdata[nLocal*rank+i] = ldata[i];
156 MPI_Allgather(MPI_IN_PLACE, 0, MPI_DATATYPE_NULL,
157 gdata.data(), nLocal, mpi_tt<cpp_t>::datatype(), comm);
167 template <
typename cpp_t>
168 void GlobalViewV(MPI_Comm comm,
const std::vector<cpp_t> &ldata,
169 std::vector<int> &gcounts, std::vector<int> &goffset,
170 std::vector<cpp_t> &gdata)
175 MPI_Comm_rank(comm, &rank);
176 MPI_Comm_size(comm, &nRanks);
179 gcounts.resize(nRanks);
181 int nLocal = ldata.size();
182 gcounts[rank] = nLocal;
184 MPI_Allgather(MPI_IN_PLACE, 0, MPI_DATATYPE_NULL,
185 gcounts.data(), 1, MPI_INT, comm);
188 goffset.resize(nRanks);
192 std::for_each(gcounts.begin(), gcounts.end(),
193 [&nTotal,&goffset,&q](
const int &n)
200 gdata.resize(nTotal);
202 const cpp_t *ld = ldata.data();
203 cpp_t *gd = gdata.data() + goffset[rank];
204 for (
int i = 0; i < nLocal; ++i)
207 MPI_Allgatherv(MPI_IN_PLACE, 0, MPI_DATATYPE_NULL, gdata.data(),
208 gcounts.data(), goffset.data(), mpi_tt<cpp_t>::datatype(), comm);
212 template <
typename cpp_t>
213 void GlobalViewV(MPI_Comm comm,
const std::vector<cpp_t> &ldata,
214 std::vector<cpp_t> &gdata)
216 std::vector<int> counts, offsets;
217 GlobalViewV(comm, ldata, counts, offsets, gdata);
223 template <
typename cpp_t>
224 void GlobalViewV(MPI_Comm comm, std::vector<cpp_t> &ldata)
226 std::vector<int> counts, offsets;
227 std::vector<cpp_t> gdata;
228 GlobalViewV(comm, ldata, counts, offsets, gdata);
229 ldata = std::move(gdata);
239 template <
typename cpp_t, std::
size_t N>
240 void GlobalViewV(MPI_Comm comm,
const std::vector<std::array<cpp_t,N>> &ldata,
241 std::vector<std::array<cpp_t,N>> &gdata)
244 size_t n = ldata.size();
245 std::vector<cpp_t> ld(n*N);
246 for (
size_t i = 0; i < n; ++i)
248 const std::array<cpp_t,N> &lda = ldata[i];
249 for (
size_t j = 0; j < N; ++j)
251 ld[i*N + j] = lda[j];
256 std::vector<cpp_t> gd;
257 std::vector<int> counts, offsets;
258 GlobalViewV(comm, ld, counts, offsets, gd);
263 for (
size_t i = 0; i < n; ++i)
265 std::array<cpp_t,N> &gda = gdata[i];
266 for (
size_t j = 0; j < N; ++j)
268 gda[j] = gd[i*N + j];
276 template <
typename cpp_t, std::
size_t N>
277 void GlobalViewV(MPI_Comm comm, std::vector<std::array<cpp_t,N>> &ldata)
279 std::vector<std::array<cpp_t,N>> gdata;
280 GlobalViewV(comm, ldata, gdata);
281 ldata = std::move(gdata);
287 template <
typename cpp_t>
288 void GlobalViewV(MPI_Comm comm, std::vector<std::vector<cpp_t>> &ldata)
291 std::vector<long> lsizes;
292 int nLocal = ldata.size();
293 for (
int i = 0; i < nLocal; ++i)
294 lsizes.push_back(ldata[i].size());
296 std::vector<int> scounts, soffsets;
297 std::vector<long> gsizes;
299 GlobalViewV(comm, lsizes, scounts, soffsets, gsizes);
302 std::vector<cpp_t> lfdata;
303 for (
int i = 0; i < nLocal; ++i)
305 const std::vector<cpp_t> &elem = ldata[i];
306 long nElem = elem.size();
307 for (
int j = 0; j < nElem; ++j)
308 lfdata.push_back(elem[j]);
312 std::vector<cpp_t> gfdata;
313 GlobalViewV(comm, lfdata, gfdata);
316 std::vector<std::vector<cpp_t>> gdata;
317 unsigned int nranks = scounts.size();
318 for (
unsigned int i = 0, q = 0; i < nranks; ++i)
320 int nVec = scounts[i];
321 int vecOffs = soffsets[i];
322 for (
int j = 0; j < nVec; ++j)
324 long nElem = gsizes[vecOffs + j];
325 std::vector<cpp_t> vec;
326 for (
long k = 0; k < nElem; ++k,++q)
328 vec.push_back(gfdata[q]);
330 gdata.push_back(vec);
void GlobalBounds(MPI_Comm comm, const std::vector< std::array< cpp_t, 6 >> &lbounds, std::array< cpp_t, 6 > &gbounds)
helper function to compute an axis aligned bounding box that bounds a collection of distrubted axis a...
Definition: MPIUtils.h:72
void GlobalCounts(MPI_Comm comm, std::vector< cpp_t > &vec)
helper to recuce by summation elements in a vector it's assumed that the vector is the same size on a...
Definition: MPIUtils.h:46
SENSEI.
Definition: ADIOS2AnalysisAdaptor.h:27
void GlobalRange(MPI_Comm comm, const std::vector< std::array< cpp_t, 2 >> &lrange, std::array< cpp_t, 2 > &grange)
helper function to compute glpbal array range
Definition: MPIUtils.h:109