FEAT 3
Finite Element Analysis Toolbox
Loading...
Searching...
No Matches
dist.hpp
1// FEAT3: Finite Element Analysis Toolbox, Version 3
2// Copyright (C) 2010 by Stefan Turek & the FEAT group
3// FEAT3 is released under the GNU General Public License version 3,
4// see the file 'copyright.txt' in the top level directory for details.
5
6#pragma once
7
8// includes, FEAT
12#include <kernel/util/binary_stream.hpp>
13#include <kernel/util/type_traits.hpp>
14
15// includes, system
16#include <vector>
17#include <sstream>
18
19// includes, MPI
20#ifdef FEAT_HAVE_MPI
21#include <mpi.h>
22#endif // FEAT_HAVE_MPI
23
24namespace FEAT
25{
32 namespace Dist
33 {
52 bool initialize(int& argc, char**& argv);
53
64 void finalize();
65
74 struct Datatype
75 {
76#if defined(FEAT_HAVE_MPI) || defined(DOXYGEN)
78 MPI_Datatype dt;
80 std::size_t bytes;
81
91 explicit Datatype(MPI_Datatype dt_, std::size_t bytes_) : dt(dt_), bytes(bytes_) {}
92#else
93 private:
94 int dt;
95 std::size_t bytes;
96
97 public:
98 explicit Datatype(int dt_, std::size_t bytes_) : dt(dt_), bytes(bytes_) {}
99#endif // FEAT_HAVE_MPI
100
101 public:
103 bool operator==(const Datatype& other) const
104 {
105 return this->dt == other.dt;
106 }
107
109 bool operator!=(const Datatype& other) const
110 {
111 return this->dt != other.dt;
112 }
113
117 std::size_t size() const
118 {
119 return bytes;
120 }
121 }; // class Datatype
122
124 extern const Datatype dt_byte;
126 extern const Datatype dt_char;
128 extern const Datatype dt_wchar;
150 extern const Datatype dt_float;
152 extern const Datatype dt_double;
171
172#if defined(FEAT_HAVE_QUADMATH) || defined(DOXYGEN)
174 extern const Datatype dt__float128;
175#endif
176
177#if defined(FEAT_HAVE_HALFMATH) || defined(DOXYGEN)
179 extern const Datatype dt__half;
180#endif
181
193 template<typename T_> const Datatype& autotype();
194
196 template<> inline const Datatype& autotype<char>() {return dt_char;}
197 template<> inline const Datatype& autotype<wchar_t>() {return dt_wchar;}
198 template<> inline const Datatype& autotype<signed char>() {return dt_signed_char;}
199 template<> inline const Datatype& autotype<signed short>() {return dt_signed_short;}
200 template<> inline const Datatype& autotype<signed int>() {return dt_signed_int;}
201 template<> inline const Datatype& autotype<signed long>() {return dt_signed_long;}
202 template<> inline const Datatype& autotype<signed long long>() {return dt_signed_long_long;}
203 template<> inline const Datatype& autotype<unsigned char>() {return dt_unsigned_char;}
204 template<> inline const Datatype& autotype<unsigned short>() {return dt_unsigned_short;}
205 template<> inline const Datatype& autotype<unsigned int>() {return dt_unsigned_int;}
206 template<> inline const Datatype& autotype<unsigned long>() {return dt_unsigned_long;}
207 template<> inline const Datatype& autotype<unsigned long long>(){return dt_unsigned_long_long;}
208 template<> inline const Datatype& autotype<float>() {return dt_float;}
209 template<> inline const Datatype& autotype<double>() {return dt_double;}
210 template<> inline const Datatype& autotype<long double>() {return dt_long_double;}
211
212#if defined(FEAT_HAVE_QUADMATH) || defined(DOXYGEN)
213 template<> inline const Datatype& autotype<__float128>() {return dt__float128;}
214#endif
215
216#if defined(FEAT_HAVE_HALFMATH) || defined(DOXYGEN)
217 template<> inline const Datatype& autotype<__half>() {return dt__half;}
218#endif
219
221
222 /* ************************************************************************************************************* */
223 /* ************************************************************************************************************* */
224 /* ************************************************************************************************************* */
225 /* ************************************************************************************************************* */
226 /* ************************************************************************************************************* */
227
237 {
238#if defined(FEAT_HAVE_MPI) || defined(DOXYGEN)
240 MPI_Op op;
241
248 explicit Operation(MPI_Op op_) : op(op_) {}
249#else
250 private:
251 int op;
252 public:
253 explicit Operation(int op_) : op(op_) {}
254#endif // FEAT_HAVE_MPI
255
256 public:
258 bool operator==(const Operation& other) const
259 {
260 return this->op == other.op;
261 }
262
264 bool operator!=(const Operation& other) const
265 {
266 return this->op != other.op;
267 }
268 }; // class Operation
269
271 extern const Operation op_sum;
273 extern const Operation op_max;
275 extern const Operation op_min;
276
277 /* ************************************************************************************************************* */
278 /* ************************************************************************************************************* */
279 /* ************************************************************************************************************* */
280 /* ************************************************************************************************************* */
281 /* ************************************************************************************************************* */
282
294 class Status
295 {
296#if defined(FEAT_HAVE_MPI) || defined(DOXYGEN)
297 public:
299 MPI_Status status;
300
303 status()
304 {
305 status.MPI_SOURCE = MPI_PROC_NULL;
306 }
307
309 Status(const Status&) = default;
311 Status& operator=(const Status&) = default;
312
314 MPI_Status* mpi_status()
315 {
316 return &status;
317 }
318
324 bool is_null() const
325 {
326 return status.MPI_SOURCE == MPI_PROC_NULL;
327 }
328
332 int source() const
333 {
334 return status.MPI_SOURCE;
335 }
336
340 int tag() const
341 {
342 return status.MPI_TAG;
343 }
344
348 int error() const
349 {
350 return status.MPI_ERROR;
351 }
352
364 std::size_t get_count(const Datatype& datatype) const
365 {
366 int c(0);
367 MPI_Get_count(&status, datatype.dt, &c);
368 return std::size_t(c);
369 }
370
372 std::size_t get_size() const
373 {
374 int c(0);
375 MPI_Get_count(&status, MPI_BYTE, &c);
376 return std::size_t(c);
377 }
378#else // non-MPI implementation
379 public:
381 int status;
382
383 Status() :
384 status(0)
385 {
386 }
387#endif // FEAT_HAVE_MPI
388 }; // class Status
389
390#ifdef FEAT_HAVE_MPI
391 // Ensure that 'Status' is a POD container for 'MPI_Status',
392 // as this is required by the RequestVector class.
393 static_assert(sizeof(Status) == sizeof(MPI_Status), "invalid Status class size; class Status must be a POD");
394#endif
395
396 /* ************************************************************************************************************* */
397 /* ************************************************************************************************************* */
398 /* ************************************************************************************************************* */
399 /* ************************************************************************************************************* */
400 /* ************************************************************************************************************* */
401
423 {
424#if defined(FEAT_HAVE_MPI) || defined(DOXYGEN)
425 public:
427 MPI_Request request;
428#else
429 private:
431 int request;
432#endif // FEAT_HAVE_MPI
433
434 public:
441 Request();
442
443#if defined(FEAT_HAVE_MPI) || defined(DOXYGEN)
445 explicit Request(MPI_Request req_);
446
448 MPI_Request* mpi_request()
449 {
450 return &request;
451 }
452#endif // FEAT_HAVE_MPI
453
455 Request(const Request&) = delete;
457 Request& operator=(const Request&) = delete;
458
468 Request(Request&& other);
469
485 Request& operator=(Request&& other);
486
489 {
490 XASSERTM(is_null(), "You are trying to destroy an active request!");
491 }
492
502 bool is_null() const;
503
514 void free();
515
529 void cancel();
530
547 bool test(Status& status);
548
556 bool test()
557 {
558 Status status;
559 return test(status);
560 }
561
577 bool wait(Status& status);
578
588 bool wait()
589 {
590 Status status;
591 return wait(status);
592 }
593 }; // class Request
594
595#ifdef FEAT_HAVE_MPI
596 // Ensure that 'Request' is a POD container for 'MPI_Request',
597 // as this is required by the RequestVector class.
598 static_assert(sizeof(Request) == sizeof(MPI_Request), "invalid Request class size; class Request must be a POD");
599#endif
600
601 /* ************************************************************************************************************* */
602 /* ************************************************************************************************************* */
603 /* ************************************************************************************************************* */
604 /* ************************************************************************************************************* */
605 /* ************************************************************************************************************* */
606
640 {
641 private:
643 std::vector<Request> _reqs;
645 std::vector<Status> _stats;
646
647#if defined(FEAT_HAVE_MPI)
648 int _isize() const
649 {
650 return int(_reqs.size());
651 }
652
653 MPI_Request* _reqs_array()
654 {
655 return reinterpret_cast<MPI_Request*>(_reqs.data());
656 }
657
658 MPI_Status* _stats_array()
659 {
660 return reinterpret_cast<MPI_Status*>(_stats.data());
661 }
662#endif // FEAT_HAVE_MPI
663
664 public:
671 _reqs(),
672 _stats()
673 {
674 }
675
685 explicit RequestVector(std::size_t size_) :
686 _reqs(size_),
687 _stats(size_)
688 {
689 }
690
692 RequestVector(const RequestVector&) = delete;
695
706 _reqs(std::forward<std::vector<Request>>(other._reqs)),
707 _stats(std::forward<std::vector<Status>>(other._stats))
708 {
709 other.clear();
710 }
711
729 {
730 if(this != &other)
731 {
732 XASSERT(is_null());
733 _reqs = std::forward<std::vector<Request>>(other._reqs);
734 _stats = std::forward<std::vector<Status>>(other._stats);
735 other.clear();
736 }
737 return *this;
738 }
739
742 {
743 XASSERTM(is_null(), "You are trying to destroy an active request vector!");
744 }
745
755 Request& get_request(std::size_t idx)
756 {
757 XASSERT(idx < _reqs.size());
758 return _reqs[idx];
759 }
760
762 const Request& get_request(std::size_t idx) const
763 {
764 XASSERT(idx < _reqs.size());
765 return _reqs[idx];
766 }
767
777 Status& get_status(std::size_t idx)
778 {
779 XASSERT(idx < _stats.size());
780 return _stats[idx];
781 }
782
784 const Status& get_status(std::size_t idx) const
785 {
786 XASSERT(idx < _stats.size());
787 return _stats[idx];
788 }
789
791 Request& operator[](std::size_t idx)
792 {
793 XASSERT(idx < _reqs.size());
794 return _reqs[idx];
795 }
796
798 const Request& operator[](std::size_t idx) const
799 {
800 XASSERT(idx < _reqs.size());
801 return _reqs[idx];
802 }
803
813 void reserve(std::size_t size_)
814 {
815 if(size_ <= _reqs.size())
816 return;
817 _reqs.reserve(size_);
818 _stats.reserve(size_);
819 }
820
834 void resize(std::size_t size_)
835 {
836 // make sure that all to-be-removed requests are null
837 for(std::size_t i(size_); i < _reqs.size(); ++i)
838 {
839 XASSERT(_reqs.at(i).is_null());
840 }
841 _reqs.resize(size_);
842 _stats.resize(size_);
843 }
844
858 std::size_t compress()
859 {
860 std::size_t i(0), j(0), n = _reqs.size();
861 while(i+j < n)
862 {
863 if(_reqs[i+j].is_null())
864 ++j;
865 else
866 {
867 _reqs[i] = std::move(_reqs[i+j]);
868 _stats[i] = std::move(_stats[i+j]);
869 ++i;
870 }
871 }
872 _reqs.resize(n-j);
873 _stats.resize(n-j);
874 return n-j;
875 }
876
886 void push_back(Request&& request)
887 {
888 _reqs.emplace_back(std::forward<Request>(request));
889 _stats.emplace_back(Status());
890 }
891
901 std::size_t size() const
902 {
903 return _reqs.size();
904 }
905
915 std::size_t active_count() const
916 {
917 std::size_t count(0);
918 for(const auto& r : _reqs)
919 {
920 if(!r.is_null())
921 ++count;
922 }
923 return count;
924 }
925
937 bool empty() const
938 {
939 return _reqs.empty();
940 }
941
954 bool is_null() const
955 {
956 for(const auto& r : _reqs)
957 {
958 if(!r.is_null())
959 return false;
960 }
961 return true;
962 }
963
974 void free()
975 {
976 for(auto& r : _reqs)
977 {
978 if(!r.is_null())
979 r.free();
980 }
981 }
982
992 void cancel()
993 {
994 for(auto& r : _reqs)
995 {
996 if(!r.is_null())
997 r.cancel();
998 }
999 }
1000
1015 void clear()
1016 {
1017 XASSERT(is_null());
1018 _reqs.clear();
1019 _stats.clear();
1020 }
1021
1033 bool test_for(std::size_t idx)
1034 {
1035 return get_request(idx).test(get_status(idx));
1036 }
1037
1054 bool test_for(std::size_t idx, Status& status)
1055 {
1056 return get_request(idx).test(status);
1057 }
1058
1071 bool test_all();
1072
1095 bool test_any(std::size_t& idx, Status& status);
1096
1112 bool test_any(std::size_t& idx)
1113 {
1114 Status status;
1115 if(!test_any(idx, status))
1116 return false;
1117 _stats[idx] = status;
1118 return true;
1119 }
1120
1137 bool test_any(Status& status)
1138 {
1139 std::size_t idx;
1140 return test_any(idx, status);
1141 }
1142
1156 bool wait_for(std::size_t idx)
1157 {
1158 return get_request(idx).wait(get_status(idx));
1159 }
1160
1179 bool wait_for(std::size_t idx, Status& status)
1180 {
1181 return get_request(idx).wait(status);
1182 }
1183
1192 void wait_all();
1193
1219 bool wait_any(std::size_t& idx, Status& status);
1220
1239 bool wait_any(std::size_t& idx)
1240 {
1241 Status status;
1242 if(!wait_any(idx, status))
1243 return false;
1244 _stats[idx] = status;
1245 return true;
1246 }
1247
1267 bool wait_any(Status& status)
1268 {
1269 std::size_t idx;
1270 return wait_any(idx, status);
1271 }
1272 }; // class RequestVector
1273
1274 /* ************************************************************************************************************* */
1275 /* ************************************************************************************************************* */
1276 /* ************************************************************************************************************* */
1277 /* ************************************************************************************************************* */
1278 /* ************************************************************************************************************* */
1279
1348 class Comm
1349 {
1350#if defined(FEAT_HAVE_MPI) || defined(DOXYGEN)
1351 public:
1353 MPI_Comm comm;
1354#endif // FEAT_HAVE_MPI
1355
1356 protected:
1361
1362#if !defined(FEAT_HAVE_MPI) && !defined(DOXYGEN)
1363 explicit Comm(int);
1364#endif
1365
1366 public:
1372 Comm();
1373
1374#if defined(FEAT_HAVE_MPI) || defined(DOXYGEN)
1387 explicit Comm(MPI_Comm comm_);
1388#endif // FEAT_HAVE_MPI
1389
1391 Comm(const Comm&) = delete;
1393 Comm& operator=(const Comm&) = delete;
1394
1408 Comm(Comm&& other);
1409
1427 Comm& operator=(Comm&& other);
1428
1435 virtual ~Comm();
1436
1437#if defined(FEAT_HAVE_MPI) || defined(DOXYGEN)
1439 const MPI_Comm& mpi_comm() const
1440 {
1441 return comm;
1442 }
1443
1445 MPI_Comm& mpi_comm()
1446 {
1447 return comm;
1448 }
1449#endif //FEAT_HAVE_MPI
1450
1454 static Comm world();
1455
1459 static Comm self();
1460
1464 static Comm null();
1465
1471 bool is_world() const;
1472
1478 bool is_self() const;
1479
1485 bool is_null() const;
1486
1494 int rank() const
1495 {
1496 return _rank;
1497 }
1498
1506 int size() const
1507 {
1508 return _size;
1509 }
1510
1515
1523 Comm comm_dup() const;
1524
1550 Comm comm_create_range_incl(int count, int first = 0, int stride = 1) const;
1551
1572 Comm comm_create_incl(int n, const int* ranks) const;
1573
1590 Comm comm_split(int color, int key) const;
1591
1593
1598
1604 void barrier() const;
1605
1613 Request ibarrier() const;
1614
1615 // end of barrier synchronization group
1617
1622
1643 void send(const void* buffer, std::size_t count, const Datatype& datatype, int dest, int tag = 0) const;
1644
1664 template<typename T_>
1665 void send(const T_* buffer, std::size_t count, int dest, int tag = 0) const
1666 {
1667 send(buffer, count, autotype<T_>(), dest, tag);
1668 }
1669
1693 void recv(void* buffer, std::size_t count, const Datatype& datatype, int source, int tag, Status& status) const;
1694
1717 void recv(void* buffer, std::size_t count, const Datatype& datatype, int source, int tag = 0) const
1718 {
1719 Status status;
1720 recv(buffer, count, datatype, source, tag, status);
1721 }
1722
1745 template<typename T_>
1746 void recv(T_* buffer, std::size_t count, int source, int tag, Status& status) const
1747 {
1748 recv(buffer, count, autotype<T_>(), source, tag, status);
1749 }
1750
1771 template<typename T_>
1772 void recv(T_* buffer, std::size_t count, int source, int tag = 0) const
1773 {
1774 Status status;
1775 recv(buffer, count, autotype<T_>(), source, tag, status);
1776 }
1777
1778 // end of blocking point-to-point group
1780
1785
1809 Request isend(const void* buffer, std::size_t count, const Datatype& datatype, int dest, int tag = 0) const;
1810
1833 template<typename T_>
1834 Request isend(const T_* buffer, std::size_t count, int dest, int tag = 0) const
1835 {
1836 return isend(buffer, count, autotype<T_>(), dest, tag);
1837 }
1838
1862 Request irecv(void* buffer, std::size_t count, const Datatype& datatype, int source, int tag = 0) const;
1863
1886 template<typename T_>
1887 Request irecv(T_* buffer, std::size_t count, int source, int tag = 0) const
1888 {
1889 return irecv(buffer, count, autotype<T_>(), source, tag);
1890 }
1891
1892 // end of nonblocking point-to-point group
1894
1899
1917 void bcast(void* buffer, std::size_t count, const Datatype& datatype, int root) const;
1918
1935 template<typename T_>
1936 void bcast(T_* buffer, std::size_t count, int root) const
1937 {
1938 bcast(buffer, count, autotype<T_>(), root);
1939 }
1940
1961 Request ibcast(void* buffer, std::size_t count, const Datatype& datatype, int root) const;
1962
1982 template<typename T_>
1983 Request ibcast(T_* buffer, std::size_t count, int root) const
1984 {
1985 return ibcast(buffer, count, autotype<T_>(), root);
1986 }
1987
1988 // end of broadcast group
1990
1995
2026 void gather(const void* sendbuf, std::size_t sendcount, const Datatype& sendtype, void* recvbuf, std::size_t recvcount, const Datatype& recvtype, int root) const;
2027
2054 template<typename ST_, typename RT_>
2055 void gather(const ST_* sendbuf, std::size_t sendcount, RT_* recvbuf, std::size_t recvcount, int root) const
2056 {
2057 gather(sendbuf, sendcount, autotype<ST_>(), recvbuf, recvcount, autotype<RT_>(), root);
2058 }
2059
2094 Request igather(const void* sendbuf, std::size_t sendcount, const Datatype& sendtype, void* recvbuf, std::size_t recvcount, const Datatype& recvtype, int root) const;
2095
2126 template<typename ST_, typename RT_>
2127 Request igather(const ST_* sendbuf, std::size_t sendcount, RT_* recvbuf, std::size_t recvcount, int root) const
2128 {
2129 return igather(sendbuf, sendcount, autotype<ST_>(), recvbuf, recvcount, autotype<RT_>(), root);
2130 }
2131
2162 void scatter(const void* sendbuf, std::size_t sendcount, const Datatype& sendtype, void* recvbuf, std::size_t recvcount, const Datatype& recvtype, int root) const;
2163
2190 template<typename ST_, typename RT_>
2191 void scatter(const ST_* sendbuf, std::size_t sendcount, RT_* recvbuf, std::size_t recvcount, int root) const
2192 {
2193 scatter(sendbuf, sendcount, autotype<ST_>(), recvbuf, recvcount, autotype<RT_>(), root);
2194 }
2195
2230 Request iscatter(const void* sendbuf, std::size_t sendcount, const Datatype& sendtype, void* recvbuf, std::size_t recvcount, const Datatype& recvtype, int root) const;
2231
2262 template<typename ST_, typename RT_>
2263 Request iscatter(const ST_* sendbuf, std::size_t sendcount, RT_* recvbuf, std::size_t recvcount, int root) const
2264 {
2265 return iscatter(sendbuf, sendcount, autotype<ST_>(), recvbuf, recvcount, autotype<RT_>(), root);
2266 }
2267
2295 void allgather(const void* sendbuf, std::size_t sendcount, const Datatype& sendtype, void* recvbuf, std::size_t recvcount, const Datatype& recvtype) const;
2296
2320 template<typename ST_, typename RT_>
2321 void allgather(const ST_* sendbuf, std::size_t sendcount, RT_* recvbuf, std::size_t recvcount) const
2322 {
2323 allgather(sendbuf, sendcount, autotype<ST_>(), recvbuf, recvcount, autotype<RT_>());
2324 }
2325
2357 Request iallgather(const void* sendbuf, std::size_t sendcount, const Datatype& sendtype, void* recvbuf, std::size_t recvcount, const Datatype& recvtype) const;
2358
2386 template<typename ST_, typename RT_>
2387 Request iallgather(const ST_* sendbuf, std::size_t sendcount, RT_* recvbuf, std::size_t recvcount) const
2388 {
2389 return iallgather(sendbuf, sendcount, autotype<ST_>(), recvbuf, recvcount, autotype<RT_>());
2390 }
2391
2426 void allgatherv(const void* sendbuf, std::size_t sendcount, const Datatype& sendtype, void* recvbuf, const int* recvcounts, const int* displs, const Datatype& recvtype) const;
2427
2458 template<typename ST_, typename RT_>
2459 void allgatherv(const ST_* sendbuf, std::size_t sendcount, RT_* recvbuf, const int* recvcounts, const int* displs) const
2460 {
2461 allgatherv(sendbuf, sendcount, autotype<ST_>(), recvbuf, recvcounts, displs, autotype<RT_>());
2462 }
2463
2491 void alltoall(const void* sendbuf, std::size_t sendcount, const Datatype& sendtype, void* recvbuf, std::size_t recvcount, const Datatype& recvtype) const;
2492
2516 template<typename ST_, typename RT_>
2517 void alltoall(const ST_* sendbuf, std::size_t sendcount, RT_* recvbuf, std::size_t recvcount) const
2518 {
2519 alltoall(sendbuf, sendcount, autotype<ST_>(), recvbuf, recvcount, autotype<RT_>());
2520 }
2521
2553 Request ialltoall(const void* sendbuf, std::size_t sendcount, const Datatype& sendtype, void* recvbuf, std::size_t recvcount, const Datatype& recvtype) const;
2554
2582 template<typename ST_, typename RT_>
2583 Request ialltoall(const ST_* sendbuf, std::size_t sendcount, RT_* recvbuf, std::size_t recvcount) const
2584 {
2585 return ialltoall(sendbuf, sendcount, autotype<ST_>(), recvbuf, recvcount, autotype<RT_>());
2586 }
2587
2625 void alltoallv(const void* sendbuf, const int* sendcounts, const int* sdispls, const Datatype& sendtype, void* recvbuf, const int* recvcounts, const int* rdispls, const Datatype& recvtype) const;
2626
2660 template<typename ST_, typename RT_>
2661 void alltoallv(const ST_* sendbuf, const int* sendcounts, const int* sdispls, RT_* recvbuf, const int* recvcounts, const int* rdispls) const
2662 {
2663 alltoallv(sendbuf, sendcounts, sdispls, autotype<ST_>(), recvbuf, recvcounts, rdispls, autotype<RT_>());
2664 }
2665
2666 // end of gather/scatter group
2668
2673
2701 void reduce(const void* sendbuf, void* recvbuf, std::size_t count, const Datatype& datatype, const Operation& op, int root) const;
2702
2729 template<typename T_>
2730 void reduce(const T_* sendbuf, T_* recvbuf, std::size_t count, const Operation& op, int root) const
2731 {
2732 reduce(sendbuf, recvbuf, count, autotype<T_>(), op, root);
2733 }
2734
2766 Request ireduce(const void* sendbuf, void* recvbuf, std::size_t count, const Datatype& datatype, const Operation& op, int root) const;
2767
2798 template<typename T_>
2799 Request ireduce(const T_* sendbuf, T_* recvbuf, std::size_t count, const Operation& op, int root) const
2800 {
2801 return ireduce(sendbuf, recvbuf, count, autotype<T_>(), op, root);
2802 }
2803
2828 void allreduce(const void* sendbuf, void* recvbuf, std::size_t count, const Datatype& datatype, const Operation& op) const;
2829
2853 template<typename T_>
2854 void allreduce(const T_* sendbuf, T_* recvbuf, std::size_t count, const Operation& op) const
2855 {
2856 allreduce(sendbuf, recvbuf, count, autotype<T_>(), op);
2857 }
2858
2887 Request iallreduce(const void* sendbuf, void* recvbuf, std::size_t count, const Datatype& datatype, const Operation& op) const;
2888
2916 template<typename T_>
2917 Request iallreduce(const T_* sendbuf, T_* recvbuf, std::size_t count, const Operation& op) const
2918 {
2919 return iallreduce(sendbuf, recvbuf, count, autotype<T_>(), op);
2920 }
2921
2946 void scan(const void* sendbuf, void* recvbuf, std::size_t count, const Datatype& datatype, const Operation& op) const;
2947
2971 template<typename T_>
2972 void scan(const T_* sendbuf, T_* recvbuf, std::size_t count, const Operation& op) const
2973 {
2974 scan(sendbuf, recvbuf, count, autotype<T_>(), op);
2975 }
2976
2977 /*Request iscan(const void* sendbuf, void* recvbuf, std::size_t count, const Datatype& datatype, const Operation& op) const;
2978
2979 template<typename T_>
2980 Request iscan(const T_* sendbuf, T_* recvbuf, std::size_t count, const Operation& op) const
2981 {
2982 return iscan(sendbuf, recvbuf, count, autotype<T_>(), op);
2983 }*/
2984
3009 void exscan(const void* sendbuf, void* recvbuf, std::size_t count, const Datatype& datatype, const Operation& op) const;
3010
3034 template<typename T_>
3035 void exscan(const T_* sendbuf, T_* recvbuf, std::size_t count, const Operation& op) const
3036 {
3037 exscan(sendbuf, recvbuf, count, autotype<T_>(), op);
3038 }
3039
3040 /*Request iexscan(const void* sendbuf, void* recvbuf, std::size_t count, const Datatype& datatype, const Operation& op) const;
3041
3042 template<typename T_>
3043 Request iexscan(const T_* sendbuf, T_* recvbuf, std::size_t count, const Operation& op) const
3044 {
3045 return iexscan(sendbuf, recvbuf, count, autotype<T_>(), op);
3046 }*/
3047
3048 // end of reductions group
3050
3058
3068 void bcast_stringstream(std::stringstream& stream, int root = 0) const;
3069
3079 void bcast_binarystream(BinaryStream& stream, int root = 0) const;
3080
3094 void print(std::ostream& os, const String& msg, int root = 0) const;
3095
3106 void print(const String& msg, int root = 0) const
3107 {
3108 print(std::cout, msg, root);
3109 }
3110
3125 void allprint(std::ostream& os, const String& msg, int root = 0) const;
3126
3138 void allprint(const String& msg, int root = 0) const
3139 {
3140 allprint(std::cout, msg, root);
3141 }
3142
3152 void print_flush(std::ostream& os, int root = 0) const;
3153
3160 void print_flush(int root = 0) const
3161 {
3162 print_flush(std::cout, root);
3163 }
3164
3165 // end of extended comm group
3167 }; // class Comm
3168 } // namespace Dist
3169} // namespace FEAT
#define XASSERT(expr)
Assertion macro definition.
Definition: assertion.hpp:262
#define XASSERTM(expr, msg)
Assertion macro definition with custom message.
Definition: assertion.hpp:263
FEAT Kernel base header.
Binary Stream class.
Communicator class.
Definition: dist.hpp:1349
void scatter(const void *sendbuf, std::size_t sendcount, const Datatype &sendtype, void *recvbuf, std::size_t recvcount, const Datatype &recvtype, int root) const
Blocking scatter.
Definition: dist.cpp:571
Comm & operator=(const Comm &)=delete
communicators are non-copyable
void bcast(void *buffer, std::size_t count, const Datatype &datatype, int root) const
Blocking broadcast.
Definition: dist.cpp:541
void reduce(const void *sendbuf, void *recvbuf, std::size_t count, const Datatype &datatype, const Operation &op, int root) const
Blocking Reduce.
Definition: dist.cpp:641
Request iallgather(const void *sendbuf, std::size_t sendcount, const Datatype &sendtype, void *recvbuf, std::size_t recvcount, const Datatype &recvtype) const
Nonblocking gather-to-all.
Definition: dist.cpp:597
Comm comm_create_range_incl(int count, int first=0, int stride=1) const
Creates a new sub-communicator from a strided range of ranks.
Definition: dist.cpp:472
void allreduce(const void *sendbuf, void *recvbuf, std::size_t count, const Datatype &datatype, const Operation &op) const
Blocking All-Reduce.
Definition: dist.cpp:655
void barrier() const
Blocking barrier.
Definition: dist.cpp:529
Request ibcast(void *buffer, std::size_t count, const Datatype &datatype, int root) const
Nonblocking broadcast.
Definition: dist.cpp:546
int size() const
Returns the size of this communicator.
Definition: dist.hpp:1506
void exscan(const void *sendbuf, void *recvbuf, std::size_t count, const Datatype &datatype, const Operation &op) const
Blocking Exclusive Scan.
Definition: dist.cpp:683
Comm comm_create_incl(int n, const int *ranks) const
Creates a new sub-communicator for a given set of ranks.
Definition: dist.cpp:498
void recv(void *buffer, std::size_t count, const Datatype &datatype, int source, int tag=0) const
Blocking Receive.
Definition: dist.hpp:1717
Request igather(const void *sendbuf, std::size_t sendcount, const Datatype &sendtype, void *recvbuf, std::size_t recvcount, const Datatype &recvtype, int root) const
Nonblocking gather.
Definition: dist.cpp:561
Request isend(const T_ *buffer, std::size_t count, int dest, int tag=0) const
Nonblocking Send.
Definition: dist.hpp:1834
static Comm null()
Returns a null communicator.
Definition: dist.cpp:439
Request ibarrier() const
Nonblocking barrier.
Definition: dist.cpp:534
void print(const String &msg, int root=0) const
Prints a message line to the standard output stream cout.
Definition: dist.hpp:3106
void allreduce(const T_ *sendbuf, T_ *recvbuf, std::size_t count, const Operation &op) const
Blocking All-Reduce.
Definition: dist.hpp:2854
int _rank
our rank
Definition: dist.hpp:1358
Request igather(const ST_ *sendbuf, std::size_t sendcount, RT_ *recvbuf, std::size_t recvcount, int root) const
Nonblocking gather.
Definition: dist.hpp:2127
virtual ~Comm()
virtual destructor
Definition: dist.cpp:422
void exscan(const T_ *sendbuf, T_ *recvbuf, std::size_t count, const Operation &op) const
Blocking Exclusive Scan.
Definition: dist.hpp:3035
void gather(const ST_ *sendbuf, std::size_t sendcount, RT_ *recvbuf, std::size_t recvcount, int root) const
Blocking gather.
Definition: dist.hpp:2055
Request iallreduce(const void *sendbuf, void *recvbuf, std::size_t count, const Datatype &datatype, const Operation &op) const
Nonblocking All-Reduce.
Definition: dist.cpp:660
Request irecv(void *buffer, std::size_t count, const Datatype &datatype, int source, int tag=0) const
Nonblocking Receive.
Definition: dist.cpp:716
Comm()
Standard constructor.
Definition: dist.cpp:372
void print_flush(int root=0) const
Explicitly flushes cout.
Definition: dist.hpp:3160
Comm comm_split(int color, int key) const
Creates a new sub-communicator by splitting this communicator.
Definition: dist.cpp:522
void recv(T_ *buffer, std::size_t count, int source, int tag=0) const
Blocking Receive.
Definition: dist.hpp:1772
bool is_world() const
Checks whether this communicator is the world communicator.
Definition: dist.cpp:444
void recv(T_ *buffer, std::size_t count, int source, int tag, Status &status) const
Blocking Receive.
Definition: dist.hpp:1746
void bcast_binarystream(BinaryStream &stream, int root=0) const
Blocking broadcast of a BinaryStream.
Definition: dist.cpp:757
void recv(void *buffer, std::size_t count, const Datatype &datatype, int source, int tag, Status &status) const
Blocking Receive.
Definition: dist.cpp:711
void bcast(T_ *buffer, std::size_t count, int root) const
Blocking broadcast.
Definition: dist.hpp:1936
Request isend(const void *buffer, std::size_t count, const Datatype &datatype, int dest, int tag=0) const
Nonblocking Send.
Definition: dist.cpp:704
int _size
the communicator size
Definition: dist.hpp:1360
MPI_Comm comm
our MPI communicator handle
Definition: dist.hpp:1353
Request iscatter(const void *sendbuf, std::size_t sendcount, const Datatype &sendtype, void *recvbuf, std::size_t recvcount, const Datatype &recvtype, int root) const
Nonblocking scatter.
Definition: dist.cpp:579
void scatter(const ST_ *sendbuf, std::size_t sendcount, RT_ *recvbuf, std::size_t recvcount, int root) const
Blocking scatter.
Definition: dist.hpp:2191
Comm(const Comm &)=delete
communicators are non-copyable
void gather(const void *sendbuf, std::size_t sendcount, const Datatype &sendtype, void *recvbuf, std::size_t recvcount, const Datatype &recvtype, int root) const
Blocking gather.
Definition: dist.cpp:553
static Comm self()
Returns a copy of the self communicator.
Definition: dist.cpp:434
Request iallgather(const ST_ *sendbuf, std::size_t sendcount, RT_ *recvbuf, std::size_t recvcount) const
Nonblocking gather-to-all.
Definition: dist.hpp:2387
MPI_Comm & mpi_comm()
Definition: dist.hpp:1445
bool is_self() const
Checks whether this communicator is the self communicator.
Definition: dist.cpp:449
const MPI_Comm & mpi_comm() const
Definition: dist.hpp:1439
void allgatherv(const ST_ *sendbuf, std::size_t sendcount, RT_ *recvbuf, const int *recvcounts, const int *displs) const
Blocking gather-to-all.
Definition: dist.hpp:2459
void alltoallv(const void *sendbuf, const int *sendcounts, const int *sdispls, const Datatype &sendtype, void *recvbuf, const int *recvcounts, const int *rdispls, const Datatype &recvtype) const
Blocking All-to-All Scatter/Gather.
Definition: dist.cpp:633
void allgather(const ST_ *sendbuf, std::size_t sendcount, RT_ *recvbuf, std::size_t recvcount) const
Blocking gather-to-all.
Definition: dist.hpp:2321
Request iscatter(const ST_ *sendbuf, std::size_t sendcount, RT_ *recvbuf, std::size_t recvcount, int root) const
Nonblocking scatter.
Definition: dist.hpp:2263
void alltoall(const void *sendbuf, std::size_t sendcount, const Datatype &sendtype, void *recvbuf, std::size_t recvcount, const Datatype &recvtype) const
Blocking All-to-All Scatter/Gather.
Definition: dist.cpp:615
void alltoallv(const ST_ *sendbuf, const int *sendcounts, const int *sdispls, RT_ *recvbuf, const int *recvcounts, const int *rdispls) const
Blocking All-to-All Scatter/Gather.
Definition: dist.hpp:2661
void send(const void *buffer, std::size_t count, const Datatype &datatype, int dest, int tag=0) const
Blocking Send.
Definition: dist.cpp:699
void print_flush(std::ostream &os, int root=0) const
Explicitly flushes the output stream.
Definition: dist.cpp:847
Request ibcast(T_ *buffer, std::size_t count, int root) const
Nonblocking broadcast.
Definition: dist.hpp:1983
void reduce(const T_ *sendbuf, T_ *recvbuf, std::size_t count, const Operation &op, int root) const
Blocking Reduce.
Definition: dist.hpp:2730
void send(const T_ *buffer, std::size_t count, int dest, int tag=0) const
Blocking Send.
Definition: dist.hpp:1665
Comm comm_dup() const
Creates a copy of this communicator.
Definition: dist.cpp:459
void allprint(std::ostream &os, const String &msg, int root=0) const
Prints the ordered messages of all processes to an output stream.
Definition: dist.cpp:789
Request ireduce(const void *sendbuf, void *recvbuf, std::size_t count, const Datatype &datatype, const Operation &op, int root) const
Nonblocking Reduce.
Definition: dist.cpp:647
Request ireduce(const T_ *sendbuf, T_ *recvbuf, std::size_t count, const Operation &op, int root) const
Nonblocking Reduce.
Definition: dist.hpp:2799
void scan(const T_ *sendbuf, T_ *recvbuf, std::size_t count, const Operation &op) const
Blocking Inclusive Scan.
Definition: dist.hpp:2972
void allgatherv(const void *sendbuf, std::size_t sendcount, const Datatype &sendtype, void *recvbuf, const int *recvcounts, const int *displs, const Datatype &recvtype) const
Blocking gather-to-all.
Definition: dist.cpp:607
void allprint(const String &msg, int root=0) const
Prints the ordered messages of all processes to the standard output stream cout.
Definition: dist.hpp:3138
Request ialltoall(const void *sendbuf, std::size_t sendcount, const Datatype &sendtype, void *recvbuf, std::size_t recvcount, const Datatype &recvtype) const
Nonblocking All-to-All Scatter/Gather.
Definition: dist.cpp:623
int rank() const
Returns the rank of this process in this communicator.
Definition: dist.hpp:1494
Request iallreduce(const T_ *sendbuf, T_ *recvbuf, std::size_t count, const Operation &op) const
Nonblocking All-Reduce.
Definition: dist.hpp:2917
Request irecv(T_ *buffer, std::size_t count, int source, int tag=0) const
Nonblocking Receive.
Definition: dist.hpp:1887
void alltoall(const ST_ *sendbuf, std::size_t sendcount, RT_ *recvbuf, std::size_t recvcount) const
Blocking All-to-All Scatter/Gather.
Definition: dist.hpp:2517
void allgather(const void *sendbuf, std::size_t sendcount, const Datatype &sendtype, void *recvbuf, std::size_t recvcount, const Datatype &recvtype) const
Blocking gather-to-all.
Definition: dist.cpp:589
bool is_null() const
Checks whether this communicator is a null communicator.
Definition: dist.cpp:454
Request ialltoall(const ST_ *sendbuf, std::size_t sendcount, RT_ *recvbuf, std::size_t recvcount) const
Nonblocking All-to-All Scatter/Gather.
Definition: dist.hpp:2583
static Comm world()
Returns a copy of the world communicator.
Definition: dist.cpp:429
void print(std::ostream &os, const String &msg, int root=0) const
Prints a message line to an output stream.
Definition: dist.cpp:782
void scan(const void *sendbuf, void *recvbuf, std::size_t count, const Datatype &datatype, const Operation &op) const
Blocking Inclusive Scan.
Definition: dist.cpp:667
void bcast_stringstream(std::stringstream &stream, int root=0) const
Blocking broadcast of a std::stringstream.
Definition: dist.cpp:723
Communication Request class.
Definition: dist.hpp:423
MPI_Request request
our internal MPI request handle
Definition: dist.hpp:427
bool test(Status &status)
Tests whether the request is fulfilled (or null) without blocking.
Definition: dist.cpp:262
Request(const Request &)=delete
Request objects are non-copyable.
~Request()
non-virtual destructor
Definition: dist.hpp:488
Request()
Standard constructor.
Definition: dist.cpp:218
bool wait(Status &status)
Blocks until the request is fulfilled (or null).
Definition: dist.cpp:269
bool wait()
Blocks until the request is fulfilled (or null).
Definition: dist.hpp:588
bool test()
Tests whether the request is fulfilled (or null).
Definition: dist.hpp:556
void free()
Frees the request.
Definition: dist.cpp:250
MPI_Request * mpi_request()
Definition: dist.hpp:448
void cancel()
Cancels the request.
Definition: dist.cpp:256
Request & operator=(const Request &)=delete
Request objects are non-copyable.
bool is_null() const
Checks whether this request is null.
Definition: dist.cpp:245
Communication Request vector class.
Definition: dist.hpp:640
Status & get_status(std::size_t idx)
Returns a (const) reference to a single status in the vector.
Definition: dist.hpp:777
void resize(std::size_t size_)
Resizes the request vector.
Definition: dist.hpp:834
RequestVector(const RequestVector &)=delete
request vectors are non-copyable
void push_back(Request &&request)
Inserts a new request at the end of the request vector.
Definition: dist.hpp:886
RequestVector()
Standard constructor.
Definition: dist.hpp:670
void reserve(std::size_t size_)
Reserves sufficient space for a specified number of requests.
Definition: dist.hpp:813
bool test_for(std::size_t idx)
Tests whether a specific request is fulfilled (or null).
Definition: dist.hpp:1033
std::size_t active_count() const
Returns the number of active requests in the vector.
Definition: dist.hpp:915
void cancel()
Cancels all remaining active requests.
Definition: dist.hpp:992
const Request & get_request(std::size_t idx) const
Returns a (const) reference to a single request in the vector.
Definition: dist.hpp:762
Request & get_request(std::size_t idx)
Returns a (const) reference to a single request in the vector.
Definition: dist.hpp:755
Request & operator[](std::size_t idx)
Returns a (const) reference to a single request in the vector.
Definition: dist.hpp:791
bool wait_for(std::size_t idx, Status &status)
Blocks until a specific request is fulfilled (or null).
Definition: dist.hpp:1179
bool wait_for(std::size_t idx)
Blocks until a specific request is fulfilled (or null).
Definition: dist.hpp:1156
bool test_all()
Tests whether all active requests are fulfilled (or null).
Definition: dist.cpp:283
bool wait_any(Status &status)
Blocks until one of the active requests has been fulfilled.
Definition: dist.hpp:1267
RequestVector & operator=(RequestVector &&other)
Move-assignment operator.
Definition: dist.hpp:728
bool empty() const
Checks whether the request vector is empty.
Definition: dist.hpp:937
bool test_any(std::size_t &idx, Status &status)
Tests whether one of the active requests has been fulfilled.
Definition: dist.cpp:290
bool is_null() const
Checks whether all requests are null requests.
Definition: dist.hpp:954
std::vector< Request > _reqs
internal vector of Request objects
Definition: dist.hpp:643
RequestVector(RequestVector &&other)
Move constructor.
Definition: dist.hpp:705
const Request & operator[](std::size_t idx) const
Returns a (const) reference to a single request in the vector.
Definition: dist.hpp:798
bool wait_any(std::size_t &idx)
Blocks until one of the active requests has been fulfilled.
Definition: dist.hpp:1239
void free()
Frees all remaining active requests.
Definition: dist.hpp:974
bool test_any(Status &status)
Tests whether one of the active requests has been fulfilled.
Definition: dist.hpp:1137
std::size_t size() const
Returns the total number of (both active and null) requests in the vector.
Definition: dist.hpp:901
std::vector< Status > _stats
internal vector of Status objects
Definition: dist.hpp:645
std::size_t compress()
Compresses the request vector.
Definition: dist.hpp:858
void clear()
Clears the request vector.
Definition: dist.hpp:1015
bool wait_any(std::size_t &idx, Status &status)
Blocks until one of the active requests has been fulfilled.
Definition: dist.cpp:329
const Status & get_status(std::size_t idx) const
Returns a (const) reference to a single status in the vector.
Definition: dist.hpp:784
bool test_any(std::size_t &idx)
Tests whether one of the active requests has been fulfilled.
Definition: dist.hpp:1112
virtual ~RequestVector()
virtual destructor
Definition: dist.hpp:741
RequestVector & operator=(const RequestVector &)=delete
request vectors are non-copyable
RequestVector(std::size_t size_)
Sized constructor.
Definition: dist.hpp:685
void wait_all()
Blocks until all active requests are fulfilled.
Definition: dist.cpp:324
bool test_for(std::size_t idx, Status &status)
Tests whether a specific request is fulfilled (or null).
Definition: dist.hpp:1054
Communication Status class.
Definition: dist.hpp:295
std::size_t get_size() const
Definition: dist.hpp:372
Status()
standard constructor
Definition: dist.hpp:302
std::size_t get_count(const Datatype &datatype) const
Returns the size of the message.
Definition: dist.hpp:364
Status & operator=(const Status &)=default
status objects are copyable
bool is_null() const
Checks whether the source rank is MPI_PROC_NULL.
Definition: dist.hpp:324
MPI_Status status
the MPI status structure
Definition: dist.hpp:299
int source() const
Definition: dist.hpp:332
MPI_Status * mpi_status()
Definition: dist.hpp:314
Status(const Status &)=default
status objects are copyable
int error() const
Definition: dist.hpp:348
int tag() const
Definition: dist.hpp:340
String class implementation.
Definition: string.hpp:47
bool initialize(int &argc, char **&argv)
Initializes the distributed communication system.
Definition: dist.cpp:105
const Datatype dt_byte(MPI_BYTE, sizeof(char))
Datatype wrapper for MPI_BYTE.
Definition: dist.hpp:124
const Datatype dt_wchar(MPI_WCHAR, sizeof(wchar_t))
Datatype wrapper for MPI_WCHAR.
Definition: dist.hpp:128
const Datatype dt_signed_long(MPI_LONG, sizeof(long))
Datatype wrapper for MPI_LONG.
Definition: dist.hpp:136
const Datatype dt_float(MPI_FLOAT, sizeof(float))
Datatype wrapper for MPI_FLOAT.
Definition: dist.hpp:150
const Datatype dt_signed_char(MPI_SIGNED_CHAR, sizeof(signed char))
Datatype wrapper for MPI_SIGNED_CHAR.
Definition: dist.hpp:130
const Datatype dt_signed_short(MPI_SHORT, sizeof(short))
Datatype wrapper for MPI_SHORT.
Definition: dist.hpp:132
const Datatype dt_unsigned_long_long(MPI_UNSIGNED_LONG_LONG, sizeof(unsigned long long))
Datatype wrapper for MPI_UNSIGNED_LONG_LONG.
Definition: dist.hpp:148
const Datatype dt_signed_int32(MPI_INT32_T, sizeof(std::int32_t))
Datatype wrapper for MPI_INT32_T.
Definition: dist.hpp:160
const Datatype & autotype()
Automatic Datatype deduction function template.
const Datatype dt_unsigned_int32(MPI_UINT32_T, sizeof(std::uint32_t))
Datatype wrapper for MPI_UINT32_T.
Definition: dist.hpp:168
void finalize()
Finalizes the distributed communication system.
Definition: dist.cpp:148
const Datatype dt_signed_int8(MPI_INT8_T, sizeof(std::int8_t))
Datatype wrapper for MPI_INT8_T.
Definition: dist.hpp:156
const Datatype dt_char(MPI_CHAR, sizeof(char))
Datatype wrapper for MPI_CHAR.
Definition: dist.hpp:126
const Operation op_min(MPI_MIN)
Operation wrapper for MPI_MIN.
Definition: dist.hpp:275
const Datatype dt_unsigned_int(MPI_UNSIGNED, sizeof(unsigned int))
Datatype wrapper for MPI_UNSIGNED.
Definition: dist.hpp:144
const Datatype dt_unsigned_int16(MPI_UINT16_T, sizeof(std::uint16_t))
Datatype wrapper for MPI_UINT16_T.
Definition: dist.hpp:166
const Datatype dt_unsigned_int8(MPI_UINT8_T, sizeof(std::uint8_t))
Datatype wrapper for MPI_UINT8_T.
Definition: dist.hpp:164
const Datatype dt__half
custom Datatype for __half
const Datatype dt_signed_int(MPI_INT, sizeof(int))
Datatype wrapper for MPI_INT.
Definition: dist.hpp:134
const Datatype dt_signed_long_long(MPI_LONG_LONG, sizeof(long long))
Datatype wrapper for MPI_LONG_LONG.
Definition: dist.hpp:138
const Operation op_max(MPI_MAX)
Operation wrapper for MPI_MAX.
Definition: dist.hpp:273
const Datatype dt_double(MPI_DOUBLE, sizeof(double))
Datatype wrapper for MPI_DOUBLE.
Definition: dist.hpp:152
const Datatype dt_unsigned_char(MPI_UNSIGNED_CHAR, sizeof(unsigned char))
Datatype wrapper for MPI_UNSIGNED_CHAR.
Definition: dist.hpp:140
const Datatype dt_signed_int16(MPI_INT16_T, sizeof(std::int16_t))
Datatype wrapper for MPI_INT16_T.
Definition: dist.hpp:158
const Datatype dt_unsigned_short(MPI_UNSIGNED_SHORT, sizeof(unsigned short))
Datatype wrapper for MPI_UNSIGNED_SHORT.
Definition: dist.hpp:142
const Datatype dt_unsigned_int64(MPI_UINT64_T, sizeof(std::uint64_t))
Datatype wrapper for MPI_UINT64_T.
Definition: dist.hpp:170
const Datatype dt_long_double(MPI_LONG_DOUBLE, sizeof(long double))
Datatype wrapper for MPI_LONG_DOUBLE.
Definition: dist.hpp:154
const Operation op_sum(MPI_SUM)
Operation wrapper for MPI_SUM.
Definition: dist.hpp:271
const Datatype dt__float128
custom Datatype for __float128
const Datatype dt_unsigned_long(MPI_UNSIGNED_LONG, sizeof(unsigned long))
Datatype wrapper for MPI_UNSIGNED_LONG.
Definition: dist.hpp:146
const Datatype dt_signed_int64(MPI_INT64_T, sizeof(std::int64_t))
Datatype wrapper for MPI_INT64_T.
Definition: dist.hpp:162
FEAT namespace.
Definition: adjactor.hpp:12
Communication Datatype class.
Definition: dist.hpp:75
MPI_Datatype dt
the MPI datatype handle
Definition: dist.hpp:78
Datatype(MPI_Datatype dt_, std::size_t bytes_)
MPI_Datatype handle constructor
Definition: dist.hpp:91
bool operator!=(const Datatype &other) const
inequality comparison operator
Definition: dist.hpp:109
bool operator==(const Datatype &other) const
equality comparison operator
Definition: dist.hpp:103
std::size_t size() const
Returns the size of the datatype in bytes, as given in the constructor.
Definition: dist.hpp:117
std::size_t bytes
the size of the datatype in bytes
Definition: dist.hpp:80
Communication Operation class.
Definition: dist.hpp:237
bool operator==(const Operation &other) const
equality comparison operator
Definition: dist.hpp:258
Operation(MPI_Op op_)
MPI_Op handle constructor
Definition: dist.hpp:248
bool operator!=(const Operation &other) const
inequality comparison operator
Definition: dist.hpp:264
MPI_Op op
the MPI operation handle
Definition: dist.hpp:240