OpenLB 1.8.1
Loading...
Searching...
No Matches
mpiManager.cpp
Go to the documentation of this file.
1/* This file is part of the OpenLB library
2 *
3 * Copyright (C) 2007 The OpenLB project
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version 2
8 * of the License, or (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public
16 * License along with this program; if not, write to the Free
17 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 * Boston, MA 02110-1301, USA.
19*/
20
21#include "mpiManager.h"
22
23#include <unistd.h>
24
25namespace olb {
26
27namespace singleton {
28
30{
31 static MpiManager instance;
32 return instance;
33}
34
35#ifdef PARALLEL_MODE_MPI
36
37MpiManager::MpiManager() : ok(false), clout(std::cout,"MpiManager")
38{ }
39
40MpiManager::~MpiManager()
41{
42 if (ok) {
43 MPI_Finalize();
44 ok = false;
45 }
46}
47
48void MpiManager::init(int *argc, char ***argv, bool verbose)
49{
50 int ok0{};
51 MPI_Initialized(&ok0);
52 if (ok0) {
53 return;
54 }
55 int ok1 = MPI_Init(argc, argv);
56 int ok2 = MPI_Comm_rank(MPI_COMM_WORLD, &taskId);
57 int ok3 = MPI_Comm_size(MPI_COMM_WORLD, &numTasks);
58 int ok4 = MPI_Comm_set_errhandler(MPI_COMM_WORLD, MPI_ERRORS_ARE_FATAL);
59 ok = (ok1 == MPI_SUCCESS && ok2 == MPI_SUCCESS && ok3 == MPI_SUCCESS && ok4 == MPI_SUCCESS);
60 if (verbose) {
61 clout << "Sucessfully initialized, numThreads=" << getSize() << std::endl;
62 }
63}
64
66{
67 return numTasks;
68}
69
71{
72 return taskId;
73}
74
76{
77 return 0;
78}
79
81{
82 return bossId() == getRank();
83}
84
85double MpiManager::getTime() const
86{
87 if (!ok) {
88 return 0.;
89 }
90 return MPI_Wtime();
91}
92
93void MpiManager::barrier(MPI_Comm comm)
94{
95 if (!ok) {
96 return;
97 }
98 MPI_Barrier(comm);
99}
100
101void MpiManager::synchronizeIO(unsigned tDelay, MPI_Comm comm)
102{
103 usleep(tDelay);
104 barrier(comm);
105}
106
107template <>
108void MpiManager::send<bool>(bool *buf, int count, int dest, int tag, MPI_Comm comm)
109{
110 if (!ok) {
111 return;
112 }
113 MPI_Send(static_cast<void*>(buf), count, MPI_BYTE, dest, tag, comm);
114}
115
116template <>
117void MpiManager::send<char>(char *buf, int count, int dest, int tag, MPI_Comm comm)
118{
119 if (!ok) {
120 return;
121 }
122 MPI_Send(static_cast<void*>(buf), count, MPI_CHAR, dest, tag, comm);
123}
124
125template <>
126void MpiManager::send<std::uint8_t>(std::uint8_t *buf, int count, int dest, int tag, MPI_Comm comm)
127{
128 if (!ok) {
129 return;
130 }
131 MPI_Send(static_cast<void*>(buf), count, MPI_BYTE, dest, tag, comm);
132}
133
134template <>
135void MpiManager::send<int>(int *buf, int count, int dest, int tag, MPI_Comm comm)
136{
137 if (!ok) {
138 return;
139 }
140 MPI_Send(static_cast<void*>(buf), count, MPI_INT, dest, tag, comm);
141}
142
143template <>
144void MpiManager::send<float>(float *buf, int count, int dest, int tag, MPI_Comm comm)
145{
146 if (!ok) {
147 return;
148 }
149 MPI_Send(static_cast<void*>(buf), count, MPI_FLOAT, dest, tag, comm);
150}
151
152template <>
153void MpiManager::send<double>(double *buf, int count, int dest, int tag, MPI_Comm comm)
154{
155 if (!ok) {
156 return;
157 }
158 MPI_Send(static_cast<void*>(buf), count, MPI_DOUBLE, dest, tag, comm);
159}
160
161template <>
162void MpiManager::sendInit<double>(double *buf, int count, int dest, MPI_Request* request, int tag, MPI_Comm comm)
163{
164 if (ok) {
165 MPI_Send_init(buf, count, MPI_DOUBLE, dest, tag, comm, request);
166 }
167}
168
169template <>
170void MpiManager::sendInit<std::size_t>(std::size_t *buf, int count, int dest, MPI_Request* request, int tag, MPI_Comm comm)
171{
172 if (ok) {
173 MPI_Send_init(buf, count, MPI_UNSIGNED_LONG, dest, tag, comm, request);
174 }
175}
176
177template <>
178void MpiManager::sendInit<std::uint32_t>(std::uint32_t *buf, int count, int dest, MPI_Request* request, int tag, MPI_Comm comm)
179{
180 if (ok) {
181 MPI_Send_init(buf, count, MPI_UNSIGNED, dest, tag, comm, request);
182 }
183}
184
185template <>
186void MpiManager::sendInit<std::uint8_t>(std::uint8_t *buf, int count, int dest, MPI_Request* request, int tag, MPI_Comm comm)
187{
188 if (ok) {
189 MPI_Send_init(buf, count, MPI_BYTE, dest, tag, comm, request);
190 }
191}
192
193template <>
194void MpiManager::sendInit<int>(int *buf, int count, int dest, MPI_Request* request, int tag, MPI_Comm comm)
195{
196 if (ok) {
197 MPI_Send_init(buf, count, MPI_INT, dest, tag, comm, request);
198 }
199}
200
201template <>
202void MpiManager::sendInit<bool>(bool *buf, int count, int dest, MPI_Request* request, int tag, MPI_Comm comm)
203{
204 if (ok) {
205 MPI_Send_init(static_cast<void*>(buf), count, MPI_BYTE, dest, tag, comm, request);
206 }
207}
208
209template <>
211(bool *buf, int count, int dest, MPI_Request* request, int tag, MPI_Comm comm)
212{
213 if (ok) {
214 MPI_Isend(static_cast<void*>(buf), count, MPI_BYTE, dest, tag, comm, request);
215 }
216}
217
218template <>
220(char *buf, int count, int dest, MPI_Request* request, int tag, MPI_Comm comm)
221{
222 if (ok) {
223 MPI_Isend(static_cast<void*>(buf), count, MPI_CHAR, dest, tag, comm, request);
224 }
225}
226
227template <>
228void MpiManager::iSend<std::uint8_t>
229(std::uint8_t *buf, int count, int dest, MPI_Request* request, int tag, MPI_Comm comm)
230{
231 if (ok) {
232 MPI_Isend(static_cast<void*>(buf), count, MPI_BYTE, dest, tag, comm, request);
233 }
234}
235
236template <>
238(int *buf, int count, int dest, MPI_Request* request, int tag, MPI_Comm comm)
239{
240 if (ok) {
241 MPI_Isend(static_cast<void*>(buf), count, MPI_INT, dest, tag, comm, request);
242 }
243}
244
245template <>
246void MpiManager::iSend<std::size_t>
247(std::size_t *buf, int count, int dest, MPI_Request* request, int tag, MPI_Comm comm)
248{
249 if (ok) {
250 MPI_Isend(static_cast<void*>(buf), count, MPI_UNSIGNED_LONG, dest, tag, comm, request);
251 }
252}
253
254template <>
255void MpiManager::iSend<std::uint32_t>
256(std::uint32_t *buf, int count, int dest, MPI_Request* request, int tag, MPI_Comm comm)
257{
258 if (ok) {
259 MPI_Isend(static_cast<void*>(buf), count, MPI_UNSIGNED, dest, tag, comm, request);
260 }
261}
262
263template <>
265(float *buf, int count, int dest, MPI_Request* request, int tag, MPI_Comm comm)
266{
267 if (ok) {
268 MPI_Isend(static_cast<void*>(buf), count, MPI_FLOAT, dest, tag, comm, request);
269 }
270}
271
272template <>
274(double *buf, int count, int dest, MPI_Request* request, int tag, MPI_Comm comm)
275{
276 if (ok) {
277 MPI_Isend(static_cast<void*>(buf), count, MPI_DOUBLE, dest, tag, comm, request);
278 }
279}
280
281template <>
283(long double *buf, int count, int dest, MPI_Request* request, int tag, MPI_Comm comm)
284{
285 if (ok) {
286 MPI_Isend(static_cast<void*>(buf), count, MPI_LONG_DOUBLE, dest, tag, comm, request);
287 }
288}
289
290
291template <>
293(bool *buf, int count, int dest, MPI_Request* request, int tag, MPI_Comm comm)
294{
295 if (ok) {
296 MPI_Ibsend(static_cast<void*>(buf), count, MPI_BYTE, dest, tag, comm, request);
297 }
298}
299
300template <>
302(char *buf, int count, int dest, MPI_Request* request, int tag, MPI_Comm comm)
303{
304 if (ok) {
305 MPI_Ibsend(static_cast<void*>(buf), count, MPI_CHAR, dest, tag, comm, request);
306 }
307}
308
309template <>
311(int *buf, int count, int dest, MPI_Request* request, int tag, MPI_Comm comm)
312{
313 if (ok) {
314 MPI_Ibsend(static_cast<void*>(buf), count, MPI_INT, dest, tag, comm, request);
315 }
316}
317
318template <>
320(float *buf, int count, int dest, MPI_Request* request, int tag, MPI_Comm comm)
321{
322 if (ok) {
323 MPI_Ibsend(static_cast<void*>(buf), count, MPI_FLOAT, dest, tag, comm, request);
324 }
325}
326
327template <>
329(double *buf, int count, int dest, MPI_Request* request, int tag, MPI_Comm comm)
330{
331 if (ok) {
332 MPI_Ibsend(static_cast<void*>(buf), count, MPI_DOUBLE, dest, tag, comm, request);
333 }
334}
335
336std::size_t MpiManager::probeReceiveSize(int source, MPI_Datatype type, int tag, MPI_Comm comm)
337{
338 MPI_Status status;
339 if (MPI_Probe(source, tag, comm, &status) == MPI_SUCCESS) {
340 int requestSize;
341 MPI_Get_count(&status, type, &requestSize);
342 if (requestSize == MPI_UNDEFINED) {
343 throw std::runtime_error("MPI_UNDEFINED in probeReceiveSize(" + std::to_string(source) + "," + std::to_string(tag) + ")" + " ranks " + std::to_string(source) + " -> " + std::to_string(singleton::mpi().getRank()));
344 }
345 return requestSize;
346 } else {
347 throw std::runtime_error("MPI_Probe failed in probeReceiveSize");
348 }
349}
350
351template <>
352std::size_t MpiManager::probeReceiveSize<std::uint32_t>(int source, int tag, MPI_Comm comm)
353{
354 return probeReceiveSize(source, MPI_UNSIGNED, tag, comm);
355}
356
357template <>
358std::size_t MpiManager::probeReceiveSize<std::uint64_t>(int source, int tag, MPI_Comm comm)
359{
360 return probeReceiveSize(source, MPI_UNSIGNED_LONG, tag, comm);
361}
362
363template <>
364void MpiManager::receive<bool>(bool *buf, int count, int source, int tag, MPI_Comm comm)
365{
366 if (!ok) {
367 return;
368 }
369 MPI_Status status;
370 MPI_Recv(static_cast<void*>(buf), count, MPI_BYTE, source, tag, comm, &status);
371}
372
373
374template <>
375void MpiManager::receive<char>(char *buf, int count, int source, int tag, MPI_Comm comm)
376{
377 if (!ok) {
378 return;
379 }
380 MPI_Status status;
381 MPI_Recv(static_cast<void*>(buf), count, MPI_CHAR, source, tag, comm, &status);
382}
383
384template <>
385void MpiManager::receive<std::uint8_t>(std::uint8_t *buf, int count, int source, int tag, MPI_Comm comm)
386{
387 if (!ok) {
388 return;
389 }
390 MPI_Status status;
391 MPI_Recv(static_cast<std::uint8_t*>(buf), count, MPI_BYTE, source, tag, comm, &status);
392}
393
394template <>
395void MpiManager::receive<int>(int *buf, int count, int source, int tag, MPI_Comm comm)
396{
397 if (!ok) {
398 return;
399 }
400 MPI_Status status;
401 MPI_Recv(static_cast<void*>(buf), count, MPI_INT, source, tag, comm, &status);
402}
403
404template <>
405void MpiManager::receive<std::size_t>(std::size_t *buf, int count, int source, int tag, MPI_Comm comm)
406{
407 if (!ok) {
408 return;
409 }
410 MPI_Status status;
411 MPI_Recv(static_cast<void*>(buf), count, MPI_UNSIGNED_LONG, source, tag, comm, &status);
412}
413
414template <>
415void MpiManager::receive<std::uint32_t>(std::uint32_t *buf, int count, int source, int tag, MPI_Comm comm)
416{
417 if (!ok) {
418 return;
419 }
420 MPI_Status status;
421 MPI_Recv(static_cast<void*>(buf), count, MPI_UNSIGNED, source, tag, comm, &status);
422}
423
424template <>
425void MpiManager::receive<float>(float *buf, int count, int source, int tag, MPI_Comm comm)
426{
427 if (!ok) {
428 return;
429 }
430 MPI_Status status;
431 MPI_Recv(static_cast<void*>(buf), count, MPI_FLOAT, source, tag, comm, &status);
432}
433
434template <>
435void MpiManager::receive<double>(double *buf, int count, int source, int tag, MPI_Comm comm)
436{
437 if (!ok) {
438 return;
439 }
440 MPI_Status status;
441 MPI_Recv(static_cast<void*>(buf), count, MPI_DOUBLE, source, tag, comm, &status);
442}
443
444template <>
445void MpiManager::receive<long double>(long double *buf, int count, int source, int tag, MPI_Comm comm)
446{
447 if (!ok) {
448 return;
449 }
450 MPI_Status status;
451 MPI_Recv(static_cast<void*>(buf), count, MPI_LONG_DOUBLE, source, tag, comm, &status);
452}
453
454template <>
455void MpiManager::sendToMaster<bool>(bool* sendBuf, int sendCount, bool iAmRoot, MPI_Comm comm)
456{
457 if (!ok) {
458 return;
459 }
460 if (iAmRoot && !isMainProcessor()) {
461 send(sendBuf, sendCount, 0);
462 }
463 if (isMainProcessor() && !iAmRoot) {
464 receive(sendBuf, sendCount, MPI_ANY_SOURCE);
465 }
466}
467
468template <>
469void MpiManager::sendToMaster<char>(char* sendBuf, int sendCount, bool iAmRoot, MPI_Comm comm)
470{
471 if (!ok) {
472 return;
473 }
474 if (iAmRoot && !isMainProcessor()) {
475 send(sendBuf, sendCount, 0);
476 }
477 if (isMainProcessor() && !iAmRoot) {
478 receive(sendBuf, sendCount, MPI_ANY_SOURCE);
479 }
480}
481
482template <>
483void MpiManager::sendToMaster<int>(int* sendBuf, int sendCount, bool iAmRoot, MPI_Comm comm)
484{
485 if (!ok) {
486 return;
487 }
488 if (iAmRoot && !isMainProcessor()) {
489 send(sendBuf, sendCount, 0);
490 }
491 if (isMainProcessor() && !iAmRoot) {
492 receive(sendBuf, sendCount, MPI_ANY_SOURCE);
493 }
494}
495
496template <>
497void MpiManager::sendToMaster<float>(float* sendBuf, int sendCount, bool iAmRoot, MPI_Comm comm)
498{
499 if (!ok) {
500 return;
501 }
502 if (iAmRoot && !isMainProcessor()) {
503 send(sendBuf, sendCount, 0);
504 }
505 if (isMainProcessor() && !iAmRoot) {
506 receive(sendBuf, sendCount, MPI_ANY_SOURCE);
507 }
508}
509
510template <>
511void MpiManager::sendToMaster<double>(double* sendBuf, int sendCount, bool iAmRoot, MPI_Comm comm)
512{
513 if (!ok) {
514 return;
515 }
516 if (iAmRoot && !isMainProcessor()) {
517 send(sendBuf, sendCount, 0);
518 }
519 if (isMainProcessor() && !iAmRoot) {
520 receive(sendBuf, sendCount, MPI_ANY_SOURCE);
521 }
522}
523
524template <>
525void MpiManager::recvInit<double>(double *buf, int count, int dest, MPI_Request* request, int tag, MPI_Comm comm)
526{
527 if (ok) {
528 MPI_Recv_init(buf, count, MPI_DOUBLE, dest, tag, comm, request);
529 }
530}
531
532template <>
533void MpiManager::recvInit<int>(int *buf, int count, int dest, MPI_Request* request, int tag, MPI_Comm comm)
534{
535 if (ok) {
536 MPI_Recv_init(buf, count, MPI_INT, dest, tag, comm, request);
537 }
538}
539
540template <>
541void MpiManager::recvInit<std::uint8_t>(std::uint8_t *buf, int count, int dest, MPI_Request* request, int tag, MPI_Comm comm)
542{
543 if (ok) {
544 MPI_Recv_init(buf, count, MPI_BYTE, dest, tag, comm, request);
545 }
546}
547
548template <>
549void MpiManager::iRecv<bool>(bool *buf, int count, int source, MPI_Request* request, int tag, MPI_Comm comm)
550{
551 if (ok) {
552 MPI_Irecv(static_cast<void*>(buf), count, MPI_BYTE, source, tag, comm, request);
553 }
554}
555
556template <>
557void MpiManager::iRecv<char>(char *buf, int count, int source, MPI_Request* request, int tag, MPI_Comm comm)
558{
559 if (ok) {
560 MPI_Irecv(static_cast<void*>(buf), count, MPI_CHAR, source, tag, comm, request);
561 }
562}
563
564template <>
565void MpiManager::iRecv<int>(int *buf, int count, int source, MPI_Request* request, int tag, MPI_Comm comm)
566{
567 if (ok) {
568 MPI_Irecv(static_cast<void*>(buf), count, MPI_INT, source, tag, comm, request);
569 }
570}
571
572template <>
573void MpiManager::iRecv<float>(float *buf, int count, int source, MPI_Request* request, int tag, MPI_Comm comm)
574{
575 if (ok) {
576 MPI_Irecv(static_cast<void*>(buf), count, MPI_FLOAT, source, tag, comm, request);
577 }
578}
579
580template <>
581void MpiManager::iRecv<double>(double *buf, int count, int source, MPI_Request* request, int tag, MPI_Comm comm)
582{
583 if (ok) {
584 MPI_Irecv(static_cast<void*>(buf), count, MPI_DOUBLE, source, tag, comm, request);
585 }
586}
587
588template <>
590(bool *sendBuf, bool *recvBuf, int count, int dest, int source, int tag, MPI_Comm comm)
591{
592 if (!ok) {
593 return;
594 }
595 MPI_Status status;
596 MPI_Sendrecv(static_cast<void*>(sendBuf),
597 count,
598 MPI_BYTE, dest, tag,
599 static_cast<void*>(recvBuf),
600 count,
601 MPI_BYTE, source, tag, comm, &status);
602}
603
604template <>
606(char *sendBuf, char *recvBuf, int count, int dest, int source, int tag, MPI_Comm comm)
607{
608 if (!ok) {
609 return;
610 }
611 MPI_Status status;
612 MPI_Sendrecv(static_cast<void*>(sendBuf),
613 count,
614 MPI_CHAR, dest, tag,
615 static_cast<void*>(recvBuf),
616 count,
617 MPI_CHAR, source, tag, comm, &status);
618}
619
620template <>
622(int *sendBuf, int *recvBuf, int count, int dest, int source, int tag, MPI_Comm comm)
623{
624 if (!ok) {
625 return;
626 }
627 MPI_Status status;
628 MPI_Sendrecv(static_cast<void*>(sendBuf),
629 count,
630 MPI_INT, dest, tag,
631 static_cast<void*>(recvBuf),
632 count,
633 MPI_INT, source, tag, comm, &status);
634}
635
636template <>
638(float *sendBuf, float *recvBuf, int count, int dest, int source, int tag, MPI_Comm comm)
639{
640 if (!ok) {
641 return;
642 }
643 MPI_Status status;
644 MPI_Sendrecv(static_cast<void*>(sendBuf),
645 count,
646 MPI_FLOAT, dest, tag,
647 static_cast<void*>(recvBuf),
648 count,
649 MPI_FLOAT, source, tag, comm, &status);
650}
651
652template <>
654(long *sendBuf, long *recvBuf, int count, int dest, int source, int tag, MPI_Comm comm)
655{
656 if (!ok) {
657 return;
658 }
659 MPI_Status status;
660 MPI_Sendrecv(static_cast<void*>(sendBuf),
661 count,
662 MPI_LONG, dest, tag,
663 static_cast<void*>(recvBuf),
664 count,
665 MPI_LONG, source, tag, comm, &status);
666}
667
668template <>
670(double *sendBuf, double *recvBuf, int count, int dest, int source, int tag, MPI_Comm comm)
671{
672 if (!ok) {
673 return;
674 }
675 MPI_Status status;
676 MPI_Sendrecv(static_cast<void*>(sendBuf),
677 count,
678 MPI_DOUBLE, dest, tag,
679 static_cast<void*>(recvBuf),
680 count,
681 MPI_DOUBLE, source, tag, comm, &status);
682}
683
684template <>
686(long double *sendBuf, long double *recvBuf, int count, int dest, int source, int tag, MPI_Comm comm)
687{
688 if (!ok) {
689 return;
690 }
691 MPI_Status status;
692 MPI_Sendrecv(static_cast<void*>(sendBuf),
693 count,
694 MPI_LONG_DOUBLE, dest, tag,
695 static_cast<void*>(recvBuf),
696 count,
697 MPI_LONG_DOUBLE, source, tag, comm, &status);
698}
699
700template <>
701void MpiManager::scatterv<bool>(bool* sendBuf, int* sendCounts, int* displs,
702 bool* recvBuf, int recvCount, int root, MPI_Comm comm)
703{
704 if (!ok) {
705 return;
706 }
707 MPI_Scatterv(static_cast<void*>(sendBuf),
708 sendCounts, displs, MPI_BYTE,
709 static_cast<void*>(recvBuf),
710 recvCount, MPI_BYTE, root, comm);
711}
712
713template <>
714void MpiManager::scatterv<char>(char* sendBuf, int* sendCounts, int* displs,
715 char* recvBuf, int recvCount, int root, MPI_Comm comm)
716{
717 if (!ok) {
718 return;
719 }
720 MPI_Scatterv(static_cast<void*>(sendBuf),
721 sendCounts, displs, MPI_CHAR,
722 static_cast<void*>(recvBuf),
723 recvCount, MPI_CHAR, root, comm);
724}
725
726template <>
727void MpiManager::scatterv<int>(int *sendBuf, int* sendCounts, int* displs,
728 int* recvBuf, int recvCount, int root, MPI_Comm comm)
729{
730 if (!ok) {
731 return;
732 }
733 MPI_Scatterv(static_cast<void*>(sendBuf),
734 sendCounts, displs, MPI_INT,
735 static_cast<void*>(recvBuf),
736 recvCount, MPI_INT, root, comm);
737}
738
739template <>
740void MpiManager::scatterv<float>(float *sendBuf, int* sendCounts, int* displs,
741 float* recvBuf, int recvCount, int root, MPI_Comm comm)
742{
743 if (!ok) {
744 return;
745 }
746 MPI_Scatterv(static_cast<void*>(sendBuf),
747 sendCounts, displs, MPI_FLOAT,
748 static_cast<void*>(recvBuf),
749 recvCount, MPI_FLOAT, root, comm);
750}
751
752template <>
753void MpiManager::scatterv<double>(double *sendBuf, int* sendCounts, int* displs,
754 double* recvBuf, int recvCount, int root, MPI_Comm comm)
755{
756 if (!ok) {
757 return;
758 }
759 MPI_Scatterv(static_cast<void*>(sendBuf),
760 sendCounts, displs, MPI_DOUBLE,
761 static_cast<void*>(recvBuf),
762 recvCount, MPI_DOUBLE, root, comm);
763}
764
765template <>
766void MpiManager::gather<int>(int* sendBuf, int sendCount,
767 int* recvBuf, int recvCount,
768 int root, MPI_Comm comm)
769{
770 if (!ok) {
771 return;
772 }
773 MPI_Gather(static_cast<void*>(sendBuf), sendCount, MPI_INT,
774 static_cast<void*>(recvBuf), recvCount, MPI_INT,
775 root, comm);
776}
777
778template <>
779void MpiManager::allGather<bool>(bool* sendBuf, int sendCount,
780 bool* recvBuf, int recvCount,
781 MPI_Comm comm)
782{
783 if (!ok) {
784 return;
785 }
786 MPI_Allgather(static_cast<void*>(sendBuf), sendCount, MPI_BYTE,
787 static_cast<void*>(recvBuf), recvCount, MPI_BYTE,
788 comm);
789}
790
791template <>
792void MpiManager::allGather<char>(char* sendBuf, int sendCount,
793 char* recvBuf, int recvCount,
794 MPI_Comm comm)
795{
796 if (!ok) {
797 return;
798 }
799 MPI_Allgather(static_cast<void*>(sendBuf), sendCount, MPI_CHAR,
800 static_cast<void*>(recvBuf), recvCount, MPI_CHAR,
801 comm);
802}
803
804template <>
805void MpiManager::allGather<int>(int* sendBuf, int sendCount,
806 int* recvBuf, int recvCount,
807 MPI_Comm comm)
808{
809 if (!ok) {
810 return;
811 }
812 MPI_Allgather(static_cast<void*>(sendBuf), sendCount, MPI_INT,
813 static_cast<void*>(recvBuf), recvCount, MPI_INT,
814 comm);
815}
816
817template <>
818void MpiManager::allGather<float>(float* sendBuf, int sendCount,
819 float* recvBuf, int recvCount,
820 MPI_Comm comm)
821{
822 if (!ok) {
823 return;
824 }
825 MPI_Allgather(static_cast<void*>(sendBuf), sendCount, MPI_FLOAT,
826 static_cast<void*>(recvBuf), recvCount, MPI_FLOAT,
827 comm);
828}
829
830template <>
831void MpiManager::allGather<double>(double* sendBuf, int sendCount,
832 double* recvBuf, int recvCount,
833 MPI_Comm comm)
834{
835 if (!ok) {
836 return;
837 }
838 MPI_Allgather(static_cast<void*>(sendBuf), sendCount, MPI_DOUBLE,
839 static_cast<void*>(recvBuf), recvCount, MPI_DOUBLE,
840 comm);
841}
842
843template <>
844void MpiManager::allGather<std::size_t>(std::size_t* sendBuf, int sendCount,
845 std::size_t* recvBuf, int recvCount,
846 MPI_Comm comm)
847{
848 if (!ok) {
849 return;
850 }
851 MPI_Allgather(static_cast<void*>(sendBuf), sendCount, MPI_UNSIGNED_LONG,
852 static_cast<void*>(recvBuf), recvCount, MPI_UNSIGNED_LONG,
853 comm);
854}
855
856#if defined(__x86_64__) || defined(_M_X64) || defined(__ppc64__) || defined(__aarch64__)
857template <>
858void MpiManager::allGather<std::uint32_t>(std::uint32_t* sendBuf, int sendCount,
859 std::uint32_t* recvBuf, int recvCount,
860 MPI_Comm comm)
861{
862 if (!ok) {
863 return;
864 }
865 MPI_Allgather(static_cast<void*>(sendBuf), sendCount, MPI_UINT32_T,
866 static_cast<void*>(recvBuf), recvCount, MPI_UINT32_T,
867 comm);
868}
869#else
870template <>
871void MpiManager::allGather<std::uint64_t>(std::uint64_t* sendBuf, int sendCount,
872 std::uint64_t* recvBuf, int recvCount,
873 MPI_Comm comm)
874{
875 if (!ok) {
876 return;
877 }
878 MPI_Allgather(static_cast<void*>(sendBuf), sendCount, MPI_UINT64_T,
879 static_cast<void*>(recvBuf), recvCount, MPI_UINT64_T,
880 comm);
881}
882#endif
883
884template <>
885void MpiManager::gatherv<bool>(bool* sendBuf, int sendCount,
886 bool* recvBuf, int* recvCounts, int* displs,
887 int root, MPI_Comm comm)
888{
889 if (!ok) {
890 return;
891 }
892 MPI_Gatherv(static_cast<void*>(sendBuf), sendCount, MPI_BYTE,
893 static_cast<void*>(recvBuf), recvCounts, displs, MPI_BYTE,
894 root, comm);
895}
896
897template <>
898void MpiManager::gatherv<char>(char* sendBuf, int sendCount,
899 char* recvBuf, int* recvCounts, int* displs,
900 int root, MPI_Comm comm)
901{
902 if (!ok) {
903 return;
904 }
905 MPI_Gatherv(static_cast<void*>(sendBuf), sendCount, MPI_CHAR,
906 static_cast<void*>(recvBuf), recvCounts, displs, MPI_CHAR,
907 root, comm);
908}
909
910template <>
911void MpiManager::gatherv<int>(int* sendBuf, int sendCount,
912 int* recvBuf, int* recvCounts, int* displs,
913 int root, MPI_Comm comm)
914{
915 if (!ok) {
916 return;
917 }
918 MPI_Gatherv(static_cast<void*>(sendBuf), sendCount, MPI_INT,
919 static_cast<void*>(recvBuf), recvCounts, displs, MPI_INT,
920 root, comm);
921}
922
923template <>
924void MpiManager::gatherv<float>(float* sendBuf, int sendCount,
925 float* recvBuf, int* recvCounts, int* displs,
926 int root, MPI_Comm comm)
927{
928 if (!ok) {
929 return;
930 }
931 MPI_Gatherv(static_cast<void*>(sendBuf), sendCount, MPI_FLOAT,
932 static_cast<void*>(recvBuf), recvCounts, displs, MPI_FLOAT,
933 root, comm);
934}
935
936template <>
937void MpiManager::gatherv<double>(double* sendBuf, int sendCount,
938 double* recvBuf, int* recvCounts, int* displs,
939 int root, MPI_Comm comm)
940{
941 if (!ok) {
942 return;
943 }
944 MPI_Gatherv(static_cast<void*>(sendBuf), sendCount, MPI_DOUBLE,
945 static_cast<void*>(recvBuf), recvCounts, displs, MPI_DOUBLE,
946 root, comm);
947}
948
949template <>
950void MpiManager::gatherv<std::size_t>(std::size_t* sendBuf, int sendCount,
951 std::size_t* recvBuf, int* recvCounts, int* displs,
952 int root, MPI_Comm comm)
953{
954 if (!ok) {
955 return;
956 }
957 MPI_Gatherv(static_cast<void*>(sendBuf), sendCount, MPI_UNSIGNED_LONG,
958 static_cast<void*>(recvBuf), recvCounts, displs, MPI_UNSIGNED_LONG,
959 root, comm);
960}
961
962template <>
963void MpiManager::allGatherv<bool>(bool* sendBuf, int sendCount,
964 bool* recvBuf, int* recvCounts, int* displs,
965 MPI_Comm comm)
966{
967 if (!ok) {
968 return;
969 }
970 MPI_Allgatherv(static_cast<void*>(sendBuf), sendCount, MPI_BYTE,
971 static_cast<void*>(recvBuf), recvCounts, displs,
972 MPI_BYTE, comm);
973}
974
975template <>
976void MpiManager::allGatherv<char>(char* sendBuf, int sendCount,
977 char* recvBuf, int* recvCounts, int* displs,
978 MPI_Comm comm)
979{
980 if (!ok) {
981 return;
982 }
983 MPI_Allgatherv(static_cast<void*>(sendBuf), sendCount, MPI_CHAR,
984 static_cast<void*>(recvBuf), recvCounts, displs,
985 MPI_CHAR, comm);
986}
987
988template <>
989void MpiManager::allGatherv<int>(int* sendBuf, int sendCount,
990 int* recvBuf, int* recvCounts, int* displs,
991 MPI_Comm comm)
992{
993 if (!ok) {
994 return;
995 }
996 MPI_Allgatherv(static_cast<void*>(sendBuf), sendCount, MPI_INT,
997 static_cast<void*>(recvBuf), recvCounts, displs,
998 MPI_INT, comm);
999}
1000
1001template <>
1002void MpiManager::allGatherv<float>(float* sendBuf, int sendCount,
1003 float* recvBuf, int* recvCounts, int* displs,
1004 MPI_Comm comm)
1005{
1006 if (!ok) {
1007 return;
1008 }
1009 MPI_Allgatherv(static_cast<void*>(sendBuf), sendCount, MPI_FLOAT,
1010 static_cast<void*>(recvBuf), recvCounts, displs,
1011 MPI_FLOAT, comm);
1012}
1013
1014template <>
1015void MpiManager::allGatherv<double>(double* sendBuf, int sendCount,
1016 double* recvBuf, int* recvCounts, int* displs,
1017 MPI_Comm comm)
1018{
1019 if (!ok) {
1020 return;
1021 }
1022 MPI_Allgatherv(static_cast<void*>(sendBuf), sendCount, MPI_DOUBLE,
1023 static_cast<void*>(recvBuf), recvCounts, displs,
1024 MPI_DOUBLE, comm);
1025}
1026
1027template <>
1028void MpiManager::allGatherv<std::size_t>(std::size_t* sendBuf, int sendCount,
1029 std::size_t* recvBuf, int* recvCounts, int* displs,
1030 MPI_Comm comm)
1031{
1032 if (!ok) {
1033 return;
1034 }
1035 MPI_Allgatherv(static_cast<void*>(sendBuf), sendCount, MPI_UNSIGNED_LONG,
1036 static_cast<void*>(recvBuf), recvCounts, displs,
1037 MPI_UNSIGNED_LONG, comm);
1038}
1039
1040#if defined(__x86_64__) || defined(_M_X64) || defined(__ppc64__) || defined(__aarch64__)
1041template <>
1042void MpiManager::allGatherv<std::uint32_t>(std::uint32_t* sendBuf, int sendCount,
1043 std::uint32_t* recvBuf, int* recvCounts, int* displs,
1044 MPI_Comm comm)
1045{
1046 if (!ok) {
1047 return;
1048 }
1049 MPI_Allgatherv(static_cast<void*>(sendBuf), sendCount, MPI_UINT32_T,
1050 static_cast<void*>(recvBuf), recvCounts, displs,
1051 MPI_UINT32_T, comm);
1052}
1053#else
1054template <>
1055void MpiManager::allGatherv<std::uint64_t>(std::uint64_t* sendBuf, int sendCount,
1056 std::uint64_t* recvBuf, int* recvCounts, int* displs,
1057 MPI_Comm comm)
1058{
1059 if (!ok) {
1060 return;
1061 }
1062 MPI_Allgatherv(static_cast<void*>(sendBuf), sendCount, MPI_UINT64_T,
1063 static_cast<void*>(recvBuf), recvCounts, displs,
1064 MPI_UINT64_T, comm);
1065}
1066#endif
1067
1068template <>
1069void MpiManager::bCast<bool>(bool* sendBuf, int sendCount, int root, MPI_Comm comm)
1070{
1071 if (!ok) {
1072 return;
1073 }
1074 MPI_Bcast(static_cast<void*>(sendBuf),
1075 sendCount, MPI_BYTE, root, comm);
1076}
1077
1078template <>
1079void MpiManager::bCast<char>(char* sendBuf, int sendCount, int root, MPI_Comm comm)
1080{
1081 if (!ok) {
1082 return;
1083 }
1084 MPI_Bcast(static_cast<void*>(sendBuf),
1085 sendCount, MPI_CHAR, root, comm);
1086}
1087
1088template <>
1089void MpiManager::bCast<unsigned char>(unsigned char* sendBuf, int sendCount, int root, MPI_Comm comm)
1090{
1091 if (!ok) {
1092 return;
1093 }
1094 MPI_Bcast(static_cast<void*>(sendBuf),
1095 sendCount, MPI_UNSIGNED_CHAR, root, comm);
1096}
1097
1098template <>
1099void MpiManager::bCast<int>(int* sendBuf, int sendCount, int root, MPI_Comm comm)
1100{
1101 if (!ok) {
1102 return;
1103 }
1104 MPI_Bcast(static_cast<void*>(sendBuf),
1105 sendCount, MPI_INT, root, comm);
1106}
1107
1108template <>
1109void MpiManager::bCast<unsigned long>(unsigned long* sendBuf, int sendCount, int root, MPI_Comm comm)
1110{
1111 if (!ok) {
1112 return;
1113 }
1114 MPI_Bcast(static_cast<void*>(sendBuf),
1115 sendCount, MPI_UNSIGNED_LONG, root, comm);
1116}
1117
1118template <>
1119void MpiManager::bCast<float>(float* sendBuf, int sendCount, int root, MPI_Comm comm)
1120{
1121 if (!ok) {
1122 return;
1123 }
1124 MPI_Bcast(static_cast<void*>(sendBuf),
1125 sendCount, MPI_FLOAT, root, comm);
1126}
1127
1128template <>
1129void MpiManager::bCast<double>(double* sendBuf, int sendCount, int root, MPI_Comm comm)
1130{
1131 if (!ok) {
1132 return;
1133 }
1134 MPI_Bcast(static_cast<void*>(sendBuf),
1135 sendCount, MPI_DOUBLE, root, comm);
1136}
1137
1138
1139template <>
1140void MpiManager::bCast<std::string>(std::string* sendBuf, int sendCount, int root, MPI_Comm comm)
1141{
1142 if (!ok) {
1143 return;
1144 }
1145 int length = (int) sendBuf->size();
1146 MPI_Bcast(static_cast<void*>(&length), 1, MPI_INT, root, comm);
1147 char* buffer = new char[length+1];
1148 if (getRank()==root) {
1149 std::copy(sendBuf->c_str(), sendBuf->c_str()+length+1, buffer);
1150 }
1151 MPI_Bcast(static_cast<void*>(buffer), length+1, MPI_CHAR, root, comm);
1152 if (getRank()!=root) {
1153 *sendBuf = buffer;
1154 }
1155 delete [] buffer;
1156}
1157
1158template <>
1159void MpiManager::bCast<bool>(bool& sendVal, int root, MPI_Comm comm)
1160{
1161 if (!ok) {
1162 return;
1163 }
1164 MPI_Bcast(&sendVal, 1, MPI_BYTE, root, comm);
1165}
1166template <>
1167void MpiManager::bCast<char>(char& sendVal, int root, MPI_Comm comm)
1168{
1169 if (!ok) {
1170 return;
1171 }
1172 MPI_Bcast(&sendVal, 1, MPI_CHAR, root, comm);
1173}
1174
1175template <>
1176void MpiManager::bCast<unsigned char>(unsigned char& sendVal, int root, MPI_Comm comm)
1177{
1178 if (!ok) {
1179 return;
1180 }
1181 MPI_Bcast(&sendVal, 1, MPI_UNSIGNED_CHAR, root, comm);
1182}
1183
1184template <>
1185void MpiManager::bCast<int>(int& sendVal, int root, MPI_Comm comm)
1186{
1187 if (!ok) {
1188 return;
1189 }
1190 MPI_Bcast(&sendVal, 1, MPI_INT, root, comm);
1191}
1192
1193template <>
1194void MpiManager::bCast<unsigned long>(unsigned long& sendVal, int root, MPI_Comm comm)
1195{
1196 if (!ok) {
1197 return;
1198 }
1199 MPI_Bcast(&sendVal, 1, MPI_UNSIGNED_LONG, root, comm);
1200}
1201
1202template <>
1203void MpiManager::bCast<float>(float& sendVal, int root, MPI_Comm comm)
1204{
1205 if (!ok) {
1206 return;
1207 }
1208 MPI_Bcast(&sendVal, 1, MPI_FLOAT, root, comm);
1209}
1210
1211template <>
1212void MpiManager::bCast<double>(double& sendVal, int root, MPI_Comm comm)
1213{
1214 if (!ok) {
1215 return;
1216 }
1217 MPI_Bcast(&sendVal, 1, MPI_DOUBLE, root, comm);
1218}
1219
1220template <>
1221void MpiManager::bCastThroughMaster<bool>(bool* sendBuf, int sendCount, bool iAmRoot, MPI_Comm comm)
1222{
1223 if (!ok) {
1224 return;
1225 }
1226 if (iAmRoot && !isMainProcessor()) {
1227 send(sendBuf, sendCount, 0);
1228 }
1229 if (isMainProcessor() && !iAmRoot) {
1230 receive(sendBuf, sendCount, MPI_ANY_SOURCE);
1231 }
1232 bCast(sendBuf, sendCount, 0);
1233}
1234
1235template <>
1236void MpiManager::bCastThroughMaster<char>(char* sendBuf, int sendCount, bool iAmRoot, MPI_Comm comm)
1237{
1238 if (!ok) {
1239 return;
1240 }
1241 if (iAmRoot && !isMainProcessor()) {
1242 send(sendBuf, sendCount, 0);
1243 }
1244 if (isMainProcessor() && !iAmRoot) {
1245 receive(sendBuf, sendCount, MPI_ANY_SOURCE);
1246 }
1247 bCast(sendBuf, sendCount, 0);
1248}
1249
1250template <>
1251void MpiManager::bCastThroughMaster<int>(int* sendBuf, int sendCount, bool iAmRoot, MPI_Comm comm)
1252{
1253 if (!ok) {
1254 return;
1255 }
1256 if (iAmRoot && !isMainProcessor()) {
1257 send(sendBuf, sendCount, 0);
1258 }
1259 if (isMainProcessor() && !iAmRoot) {
1260 receive(sendBuf, sendCount, MPI_ANY_SOURCE);
1261 }
1262 bCast(sendBuf, sendCount, 0);
1263}
1264
1265template <>
1266void MpiManager::bCastThroughMaster<float>(float* sendBuf, int sendCount, bool iAmRoot, MPI_Comm comm)
1267{
1268 if (!ok) {
1269 return;
1270 }
1271 if (iAmRoot && !isMainProcessor()) {
1272 send(sendBuf, sendCount, 0);
1273 }
1274 if (isMainProcessor() && !iAmRoot) {
1275 receive(sendBuf, sendCount, MPI_ANY_SOURCE);
1276 }
1277 bCast(sendBuf, sendCount, 0);
1278}
1279
1280template <>
1281void MpiManager::bCastThroughMaster<double>(double* sendBuf, int sendCount, bool iAmRoot, MPI_Comm comm)
1282{
1283 if (!ok) {
1284 return;
1285 }
1286 if (iAmRoot && !isMainProcessor()) {
1287 send(sendBuf, sendCount, 0);
1288 }
1289 if (isMainProcessor() && !iAmRoot) {
1290 receive(sendBuf, sendCount, MPI_ANY_SOURCE);
1291 }
1292 bCast(sendBuf, sendCount, 0);
1293}
1294
1295template <>
1296void MpiManager::reduce<bool>(bool& sendVal, bool& recvVal, MPI_Op op, int root, MPI_Comm comm)
1297{
1298 if (!ok) {
1299 return;
1300 }
1301 MPI_Reduce(static_cast<void*>(&sendVal),
1302 static_cast<void*>(&recvVal), 1, MPI_BYTE, op, root, comm);
1303}
1304
1305template <>
1306void MpiManager::reduce<char>(char& sendVal, char& recvVal, MPI_Op op, int root, MPI_Comm comm)
1307{
1308 if (!ok) {
1309 return;
1310 }
1311 MPI_Reduce(static_cast<void*>(&sendVal),
1312 static_cast<void*>(&recvVal), 1, MPI_CHAR, op, root, comm);
1313}
1314
1315template <>
1316void MpiManager::reduce<int>(int& sendVal, int& recvVal, MPI_Op op, int root, MPI_Comm comm)
1317{
1318 if (!ok) {
1319 return;
1320 }
1321 MPI_Reduce(static_cast<void*>(&sendVal),
1322 static_cast<void*>(&recvVal), 1, MPI_INT, op, root, comm);
1323}
1324
1325template <>
1326void MpiManager::reduce<float>(float& sendVal, float& recvVal, MPI_Op op, int root, MPI_Comm comm)
1327{
1328 if (!ok) {
1329 return;
1330 }
1331 MPI_Reduce(static_cast<void*>(&sendVal),
1332 static_cast<void*>(&recvVal), 1, MPI_FLOAT, op, root, comm);
1333}
1334
1335template <>
1336void MpiManager::reduce<float>(float* sendVal, float* recvVal, int count, MPI_Op op, int root, MPI_Comm comm)
1337{
1338 if (!ok) {
1339 return;
1340 }
1341 MPI_Reduce(sendVal, recvVal, count, MPI_FLOAT, op, root, comm);
1342}
1343
1344template <>
1345void MpiManager::reduce<double>(double& sendVal, double& recvVal, MPI_Op op, int root, MPI_Comm comm)
1346{
1347 if (!ok) {
1348 return;
1349 }
1350 MPI_Reduce(static_cast<void*>(&sendVal),
1351 static_cast<void*>(&recvVal), 1, MPI_DOUBLE, op, root, comm);
1352}
1353
1354template <>
1355void MpiManager::reduce<std::size_t>(std::size_t& sendVal, std::size_t& recvVal, MPI_Op op, int root, MPI_Comm comm)
1356{
1357 if (!ok) {
1358 return;
1359 }
1360 MPI_Reduce(static_cast<void*>(&sendVal),
1361 static_cast<void*>(&recvVal), 1, MPI_UNSIGNED_LONG, op, root, comm);
1362}
1363
1364template <>
1365void MpiManager::reduceVect<char>(std::vector<char>& sendVal, std::vector<char>& recvVal,
1366 MPI_Op op, int root, MPI_Comm comm)
1367{
1368 if (!ok) {
1369 return;
1370 }
1371 MPI_Reduce(static_cast<void*>(&(sendVal[0])),
1372 static_cast<void*>(&(recvVal[0])),
1373 sendVal.size(), MPI_CHAR, op, root, comm);
1374}
1375
1376template <>
1377void MpiManager::reduceVect<int>(std::vector<int>& sendVal, std::vector<int>& recvVal,
1378 MPI_Op op, int root, MPI_Comm comm)
1379{
1380 if (!ok) {
1381 return;
1382 }
1383 MPI_Reduce(static_cast<void*>(&(sendVal[0])),
1384 static_cast<void*>(&(recvVal[0])),
1385 sendVal.size(), MPI_INT, op, root, comm);
1386}
1387
1388template <>
1389void MpiManager::reduceVect<float>(std::vector<float>& sendVal, std::vector<float>& recvVal,
1390 MPI_Op op, int root, MPI_Comm comm)
1391{
1392 if (!ok) {
1393 return;
1394 }
1395 MPI_Reduce(static_cast<void*>(&(sendVal[0])),
1396 static_cast<void*>(&(recvVal[0])),
1397 sendVal.size(), MPI_FLOAT, op, root, comm);
1398}
1399
1400template <>
1401void MpiManager::reduceVect<double>(std::vector<double>& sendVal, std::vector<double>& recvVal,
1402 MPI_Op op, int root, MPI_Comm comm)
1403{
1404 if (!ok) {
1405 return;
1406 }
1407 MPI_Reduce(static_cast<void*>(&(sendVal[0])),
1408 static_cast<void*>(&(recvVal[0])),
1409 sendVal.size(), MPI_DOUBLE, op, root, comm);
1410}
1411
1412template <>
1413void MpiManager::reduceAndBcast<bool>(bool& reductVal, MPI_Op op, int root, MPI_Comm comm)
1414{
1415 if (!ok) {
1416 return;
1417 }
1418 char recvVal;
1419 MPI_Reduce(static_cast<void*>(&reductVal), static_cast<void*>(&recvVal), 1, MPI_BYTE, op, root, comm);
1420 reductVal = recvVal;
1421 MPI_Bcast(&reductVal, 1, MPI_BYTE, root, comm);
1422
1423}
1424
1425template <>
1426void MpiManager::reduceAndBcast<char>(char& reductVal, MPI_Op op, int root, MPI_Comm comm)
1427{
1428 if (!ok) {
1429 return;
1430 }
1431 char recvVal;
1432 MPI_Reduce(&reductVal, &recvVal, 1, MPI_CHAR, op, root, comm);
1433 reductVal = recvVal;
1434 MPI_Bcast(&reductVal, 1, MPI_CHAR, root, comm);
1435
1436}
1437
1438template <>
1439void MpiManager::reduceAndBcast<int>(int& reductVal, MPI_Op op, int root, MPI_Comm comm)
1440{
1441 if (!ok) {
1442 return;
1443 }
1444 int recvVal;
1445 MPI_Reduce(&reductVal, &recvVal, 1, MPI_INT, op, root, comm);
1446 reductVal = recvVal;
1447 MPI_Bcast(&reductVal, 1, MPI_INT, root, comm);
1448}
1449
1450
1451template <>
1452void MpiManager::reduceAndBcast<float>(float& reductVal, MPI_Op op, int root, MPI_Comm comm)
1453{
1454 if (!ok) {
1455 return;
1456 }
1457 float recvVal;
1458 MPI_Reduce(&reductVal, &recvVal, 1, MPI_FLOAT, op, root, comm);
1459 reductVal = recvVal;
1460 MPI_Bcast(&reductVal, 1, MPI_FLOAT, root, comm);
1461}
1462
1463template <>
1464void MpiManager::reduceAndBcast<double>(double& reductVal, MPI_Op op, int root, MPI_Comm comm)
1465{
1466 if (!ok) {
1467 return;
1468 }
1469 double recvVal;
1470 MPI_Reduce(&reductVal, &recvVal, 1, MPI_DOUBLE, op, root, comm);
1471 reductVal = recvVal;
1472 MPI_Bcast(&reductVal, 1, MPI_DOUBLE, root, comm);
1473
1474}
1475
1476template <>
1477void MpiManager::reduceAndBcast<long double>(long double& reductVal, MPI_Op op, int root, MPI_Comm comm)
1478{
1479 if (!ok) {
1480 return;
1481 }
1482 long double recvVal;
1483 MPI_Reduce(&reductVal, &recvVal, 1, MPI_LONG_DOUBLE, op, root, comm);
1484 reductVal = recvVal;
1485 MPI_Bcast(&reductVal, 1, MPI_LONG_DOUBLE, root, comm);
1486
1487}
1488
1489template <>
1490void MpiManager::reduceAndBcast<long>(long& reductVal, MPI_Op op, int root, MPI_Comm comm)
1491{
1492 if (!ok) {
1493 return;
1494 }
1495 long recvVal;
1496 MPI_Reduce(&reductVal, &recvVal, 1, MPI_LONG, op, root, comm);
1497 reductVal = recvVal;
1498 MPI_Bcast(&reductVal, 1, MPI_LONG, root, comm);
1499
1500}
1501
1502template <>
1503void MpiManager::reduceAndBcast<unsigned long>(unsigned long& reductVal, MPI_Op op, int root, MPI_Comm comm)
1504{
1505 if (!ok) {
1506 return;
1507 }
1508 unsigned long recvVal;
1509 MPI_Reduce(&reductVal, &recvVal, 1, MPI_UNSIGNED_LONG, op, root, comm);
1510 reductVal = recvVal;
1511 MPI_Bcast(&reductVal, 1, MPI_UNSIGNED_LONG, root, comm);
1512
1513}
1514
1515template <>
1516void MpiManager::allreduce<float>(const float* in, float* out, int count, MPI_Op op, MPI_Comm comm)
1517{
1518 if (!ok) {
1519 return;
1520 }
1521 MPI_Allreduce(in, out, count, MPI_FLOAT, op, comm);
1522}
1523
1524template <>
1525void MpiManager::allreduce<double>(const double* in, double* out, int count, MPI_Op op, MPI_Comm comm)
1526{
1527 if (!ok) {
1528 return;
1529 }
1530 MPI_Allreduce(in, out, count, MPI_DOUBLE, op, comm);
1531}
1532
1533template <>
1534void MpiManager::allreduce<unsigned>(const unsigned* in, unsigned* out, int count, MPI_Op op, MPI_Comm comm)
1535{
1536 if (!ok) {
1537 return;
1538 }
1539 MPI_Allreduce(in, out, count, MPI_UNSIGNED, op, comm);
1540}
1541
1542template <>
1543void MpiManager::allreduce<int>(const int* in, int* out, int count, MPI_Op op, MPI_Comm comm)
1544{
1545 if (!ok) {
1546 return;
1547 }
1548 MPI_Allreduce(in, out, count, MPI_INT, op, comm);
1549}
1550
1551template <>
1552void MpiManager::allReduce<bool>(bool& reductVal, MPI_Op op, MPI_Comm comm)
1553{
1554 if (!ok) {
1555 return;
1556 }
1557 bool recvVal;
1558 MPI_Allreduce(static_cast<void*>(&reductVal), static_cast<void*>(&recvVal), 1, MPI_BYTE, op, comm);
1559 reductVal = recvVal;
1560}
1561
1562template <>
1563void MpiManager::allReduce<char>(char& reductVal, MPI_Op op, MPI_Comm comm)
1564{
1565 if (!ok) {
1566 return;
1567 }
1568 char recvVal;
1569 MPI_Allreduce(static_cast<void*>(&reductVal), static_cast<void*>(&recvVal), 1, MPI_CHAR, op, comm);
1570 reductVal = recvVal;
1571}
1572
1573template <>
1574void MpiManager::allReduce<int>(int& reductVal, MPI_Op op, MPI_Comm comm)
1575{
1576 if (!ok) {
1577 return;
1578 }
1579 int recvVal;
1580 MPI_Allreduce(static_cast<void*>(&reductVal), static_cast<void*>(&recvVal), 1, MPI_INT, op, comm);
1581 reductVal = recvVal;
1582}
1583
1584template <>
1585void MpiManager::allReduce<float>(float& reductVal, MPI_Op op, MPI_Comm comm)
1586{
1587 if (!ok) {
1588 return;
1589 }
1590 float recvVal;
1591 MPI_Allreduce(static_cast<void*>(&reductVal), static_cast<void*>(&recvVal), 1, MPI_FLOAT, op, comm);
1592 reductVal = recvVal;
1593}
1594
1595template <>
1596void MpiManager::allReduce<double>(double& reductVal, MPI_Op op, MPI_Comm comm)
1597{
1598 if (!ok) {
1599 return;
1600 }
1601 double recvVal;
1602 MPI_Allreduce(static_cast<void*>(&reductVal), static_cast<void*>(&recvVal), 1, MPI_DOUBLE, op, comm);
1603 reductVal = recvVal;
1604}
1605
1606template <>
1607void MpiManager::allReduce<long double>(long double& reductVal, MPI_Op op, MPI_Comm comm)
1608{
1609 if (!ok) {
1610 return;
1611 }
1612 long double recvVal;
1613 MPI_Allreduce(static_cast<void*>(&reductVal), static_cast<void*>(&recvVal), 1, MPI_LONG_DOUBLE, op, comm);
1614 reductVal = recvVal;
1615}
1616
1617template <>
1618void MpiManager::allReduce<std::size_t>(std::size_t& reductVal, MPI_Op op, MPI_Comm comm)
1619{
1620 if (!ok) {
1621 return;
1622 }
1623 std::size_t recvVal;
1624 MPI_Allreduce(static_cast<void*>(&reductVal), static_cast<void*>(&recvVal), 1, MPI_UNSIGNED_LONG, op, comm);
1625 reductVal = recvVal;
1626}
1627
1628#if defined(__x86_64__) || defined(_M_X64) || defined(__ppc64__) || defined(__aarch64__)
1629template <>
1630void MpiManager::allReduce<std::uint32_t>(std::uint32_t& reductVal, MPI_Op op, MPI_Comm comm)
1631{
1632 if (!ok) {
1633 return;
1634 }
1635 std::uint32_t recvVal;
1636 MPI_Allreduce(static_cast<void*>(&reductVal), static_cast<void*>(&recvVal), 1, MPI_UNSIGNED, op, comm);
1637 reductVal = recvVal;
1638}
1639#else
1640template <>
1641void MpiManager::allReduce<std::uint64_t>(std::uint64_t& reductVal, MPI_Op op, MPI_Comm comm)
1642{
1643 if (!ok) {
1644 return;
1645 }
1646 std::uint64_t recvVal;
1647 MPI_Allreduce(static_cast<void*>(&reductVal), static_cast<void*>(&recvVal), 1, MPI_UNSIGNED_LONG, op, comm);
1648 reductVal = recvVal;
1649}
1650#endif
1651
1652template <>
1653void MpiManager::allReduceVect<char>(std::vector<char>& reductVal, MPI_Op op, MPI_Comm comm)
1654{
1655 if (!ok) {
1656 return;
1657 }
1658 MPI_Allreduce(MPI_IN_PLACE, static_cast<void*>(reductVal.data()), static_cast<int>(reductVal.size()), MPI_CHAR, op, comm);
1659}
1660
1661template <>
1662void MpiManager::allReduceVect<int>(std::vector<int>& reductVal, MPI_Op op, MPI_Comm comm)
1663{
1664 if (!ok) {
1665 return;
1666 }
1667 MPI_Allreduce(MPI_IN_PLACE, static_cast<void*>(reductVal.data()), static_cast<int>(reductVal.size()), MPI_INT, op, comm);
1668}
1669
1670template <>
1671void MpiManager::allReduceVect<float>(std::vector<float>& reductVal, MPI_Op op, MPI_Comm comm)
1672{
1673 if (!ok) {
1674 return;
1675 }
1676 MPI_Allreduce(MPI_IN_PLACE, static_cast<void*>(reductVal.data()), static_cast<int>(reductVal.size()), MPI_FLOAT, op, comm);
1677}
1678
1679template <>
1680void MpiManager::allReduceVect<double>(std::vector<double>& reductVal, MPI_Op op, MPI_Comm comm)
1681{
1682 if (!ok) {
1683 return;
1684 }
1685 MPI_Allreduce(MPI_IN_PLACE, static_cast<void*>(reductVal.data()), static_cast<int>(reductVal.size()), MPI_DOUBLE, op, comm);
1686}
1687
1688template <>
1689void MpiManager::allReduceVect<long double>(std::vector<long double>& reductVal, MPI_Op op, MPI_Comm comm)
1690{
1691 if (!ok) {
1692 return;
1693 }
1694 MPI_Allreduce(MPI_IN_PLACE, static_cast<void*>(reductVal.data()), static_cast<int>(reductVal.size()), MPI_LONG_DOUBLE, op, comm);
1695}
1696
1697template <>
1698void MpiManager::allReduceVect<std::size_t>(std::vector<std::size_t>& reductVal, MPI_Op op, MPI_Comm comm)
1699{
1700 if (!ok) {
1701 return;
1702 }
1703 MPI_Allreduce(MPI_IN_PLACE, static_cast<void*>(reductVal.data()), static_cast<int>(reductVal.size()), MPI_UNSIGNED_LONG, op, comm);
1704}
1705
1706#if defined(__x86_64__) || defined(_M_X64) || defined(__ppc64__) || defined(__aarch64__)
1707template <>
1708void MpiManager::allReduceVect<std::uint32_t>(std::vector<std::uint32_t>& reductVal, MPI_Op op, MPI_Comm comm)
1709{
1710 if (!ok) {
1711 return;
1712 }
1713 MPI_Allreduce(MPI_IN_PLACE, static_cast<void*>(reductVal.data()), static_cast<int>(reductVal.size()), MPI_UNSIGNED, op, comm);
1714}
1715#else
1716template <>
1717void MpiManager::allReduceVect<std::uint64_t>(std::vector<std::uint64_t>& reductVal, MPI_Op op, MPI_Comm comm)
1718{
1719 if (!ok) {
1720 return;
1721 }
1722 MPI_Allreduce(MPI_IN_PLACE, static_cast<void*>(reductVal.data()), static_cast<int>(reductVal.size()), MPI_UNSIGNED_LONG, op, comm);
1723}
1724#endif
1725
1726void MpiManager::wait(MPI_Request* request, MPI_Status* status)
1727{
1728 if (!ok) {
1729 return;
1730 }
1731 MPI_Wait(request, status);
1732}
1733
1735{
1736 if (!ok || mpiNbHelper.get_size() == 0) {
1737 return;
1738 }
1739 MPI_Waitall(mpiNbHelper.get_size(), mpiNbHelper.get_mpiRequest(), mpiNbHelper.get_mpiStatus());
1740}
1741
1742
1746
1748{
1749 std::swap(_size, rhs._size);
1750 std::swap(_mpiRequest, rhs._mpiRequest);
1751 std::swap(_mpiStatus, rhs._mpiStatus);
1752}
1753
1755{
1756 free();
1757 _mpiRequest.reset(new MPI_Request[n] { });
1758 _mpiStatus.reset(new MPI_Status[n] { });
1759 _size = n;
1760}
1761
1763{
1764 _size = 0;
1765}
1766
1768{
1769 return _size;
1770}
1771
1773{
1774 OLB_PRECONDITION(size_t(i) < _size);
1775 return &_mpiRequest[i];
1776}
1777
1779{
1780 OLB_PRECONDITION(size_t(i) < _size);
1781 return &_mpiStatus[i];
1782}
1783
1785{
1786 MPI_Start(get_mpiRequest(i));
1787}
1788
1790{
1791 MPI_Wait(get_mpiRequest(i), get_mpiStatus(i));
1792}
1793
1795{
1796 int done;
1797 MPI_Test(get_mpiRequest(i), &done, MPI_STATUS_IGNORE);
1798 return done;
1799}
1800
1801#endif // PARALLEL_MODE_MPI
1802
1803} // namespace singleton
1804
1805} // namespace olb
Wrapper functions that simplify the use of MPI.
Definition mpiManager.h:90
void gather(T *sendBuf, int sendCount, T *recvBuf, int recvCount, int root=0, MPI_Comm comm=MPI_COMM_WORLD)
Gather data from multiple processors to one processor.
void wait(MPI_Request *request, MPI_Status *status)
Complete a non-blocking MPI operation.
void send(T *buf, int count, int dest, int tag=0, MPI_Comm comm=MPI_COMM_WORLD)
Sends data at *buf, blocking.
void bCast(T *sendBuf, int sendCount, int root=0, MPI_Comm comm=MPI_COMM_WORLD)
Broadcast data from one processor to multiple processors.
int getSize() const
Returns the number of processes.
void iSend(T *buf, int count, int dest, MPI_Request *request, int tag=0, MPI_Comm comm=MPI_COMM_WORLD)
Sends data at *buf, non blocking.
void allreduce(const T *in, T *out, int count, MPI_Op op, MPI_Comm comm=MPI_COMM_WORLD)
void reduce(T &sendVal, T &recvVal, MPI_Op op, int root=0, MPI_Comm=MPI_COMM_WORLD)
Reduction operation toward one processor.
double getTime() const
Returns universal MPI-time in seconds.
bool isMainProcessor() const
Tells whether current processor is main processor.
void gatherv(T *sendBuf, int sendCount, T *recvBuf, int *recvCounts, int *displs, int root=0, MPI_Comm comm=MPI_COMM_WORLD)
Gather data from multiple processors to one processor.
void synchronizeIO(unsigned tDelay=100, MPI_Comm comm=MPI_COMM_WORLD)
Synchronizes the processes and wait to ensure correct cout order.
void reduceVect(std::vector< T > &sendVal, std::vector< T > &recvVal, MPI_Op op, int root=0, MPI_Comm comm=MPI_COMM_WORLD)
Element-per-element reduction of a vector of data.
void ibSend(T *buf, int count, int dest, MPI_Request *request, int tag=0, MPI_Comm comm=MPI_COMM_WORLD)
Sends data at *buf, non blocking and buffered.
void reduceAndBcast(T &reductVal, MPI_Op op, int root=0, MPI_Comm comm=MPI_COMM_WORLD)
Reduction operation, followed by a broadcast.
int getRank() const
Returns the process ID.
std::size_t probeReceiveSize(int source, MPI_Datatype type, int tag=0, MPI_Comm comm=MPI_COMM_WORLD)
Probe size of incoming message.
void allReduceVect(std::vector< T > &reductVal, MPI_Op op, MPI_Comm comm=MPI_COMM_WORLD)
Element-per-element all-reduction of a vector of data (in-place)
void allGatherv(T *sendBuf, int sendCount, T *recvBuf, int *recvCounts, int *displs, MPI_Comm comm=MPI_COMM_WORLD)
Gather data from multiple processors to every processor.
void waitAll(MpiNonBlockingHelper &mpiNbHelper)
Complete a series of non-blocking MPI operations.
void barrier(MPI_Comm comm=MPI_COMM_WORLD)
Synchronizes the processes.
void bCastThroughMaster(T *sendBuf, int sendCount, bool iAmRoot, MPI_Comm comm=MPI_COMM_WORLD)
Broadcast data when root is unknown to other processors.
void allGather(T *sendBuf, int sendCount, T *recvBuf, int recvCount, MPI_Comm comm=MPI_COMM_WORLD)
Gather data from multiple processors to every processor.
void iRecv(T *buf, int count, int source, MPI_Request *request, int tag=0, MPI_Comm comm=MPI_COMM_WORLD)
Receives data at *buf, non blocking.
void init(int *argc, char ***argv, bool verbose=true)
Initializes the mpi manager.
void recvInit(T *buf, int count, int dest, MPI_Request *request, int tag=0, MPI_Comm comm=MPI_COMM_WORLD)
Initialize persistent non-blocking receive.
void scatterv(T *sendBuf, int *sendCounts, int *displs, T *recvBuf, int recvCount, int root=0, MPI_Comm comm=MPI_COMM_WORLD)
Scatter data from one processor over multiple processors.
void allReduce(T &reductVal, MPI_Op op, MPI_Comm comm=MPI_COMM_WORLD)
All reduction operation of a vector data.
void sendInit(T *buf, int count, int dest, MPI_Request *request, int tag=0, MPI_Comm comm=MPI_COMM_WORLD)
Initialize persistent non-blocking send.
int bossId() const
Returns process ID of main processor.
void sendToMaster(T *sendBuf, int sendCount, bool iAmRoot, MPI_Comm comm=MPI_COMM_WORLD)
Sends data to master processor.
void sendRecv(T *sendBuf, T *recvBuf, int count, int dest, int source, int tag=0, MPI_Comm comm=MPI_COMM_WORLD)
Send and receive data between two partners.
void receive(T *buf, int count, int source, int tag=0, MPI_Comm comm=MPI_COMM_WORLD)
Receives data at *buf, blocking.
Helper class for non blocking MPI communication.
Definition mpiManager.h:51
void allocate(unsigned i)
Allocates memory.
MPI_Status * get_mpiStatus(int i=0) const
Get the specified status object.
MPI_Request * get_mpiRequest(int i=0) const
Get the specified request object.
void swap(MpiNonBlockingHelper &rhs)
Swap method.
unsigned get_size() const
Returns the size of the vector _mpiRequest/_mpiStatus.
Wrapper functions that simplify the use of MPI.
MpiManager & mpi()
Top level namespace for all of OpenLB.
#define OLB_PRECONDITION(COND)
Definition olbDebug.h:46