5 #ifndef GKO_PUBLIC_CORE_BASE_MPI_HPP_
6 #define GKO_PUBLIC_CORE_BASE_MPI_HPP_
10 #include <type_traits>
13 #include <ginkgo/config.hpp>
14 #include <ginkgo/core/base/exception.hpp>
15 #include <ginkgo/core/base/exception_helpers.hpp>
16 #include <ginkgo/core/base/executor.hpp>
17 #include <ginkgo/core/base/half.hpp>
18 #include <ginkgo/core/base/types.hpp>
19 #include <ginkgo/core/base/utils_helper.hpp>
29 namespace experimental {
44 #if GINKGO_HAVE_GPU_AWARE_MPI
62 #define GKO_REGISTER_MPI_TYPE(input_type, mpi_type) \
64 struct type_impl<input_type> { \
65 static MPI_Datatype get_type() { return mpi_type; } \
80 GKO_REGISTER_MPI_TYPE(
char, MPI_CHAR);
81 GKO_REGISTER_MPI_TYPE(
unsigned char, MPI_UNSIGNED_CHAR);
82 GKO_REGISTER_MPI_TYPE(
unsigned, MPI_UNSIGNED);
83 GKO_REGISTER_MPI_TYPE(
int, MPI_INT);
84 GKO_REGISTER_MPI_TYPE(
unsigned short, MPI_UNSIGNED_SHORT);
85 GKO_REGISTER_MPI_TYPE(
unsigned long, MPI_UNSIGNED_LONG);
86 GKO_REGISTER_MPI_TYPE(
long, MPI_LONG);
87 GKO_REGISTER_MPI_TYPE(
long long, MPI_LONG_LONG_INT);
88 GKO_REGISTER_MPI_TYPE(
unsigned long long, MPI_UNSIGNED_LONG_LONG);
89 GKO_REGISTER_MPI_TYPE(
float, MPI_FLOAT);
90 GKO_REGISTER_MPI_TYPE(
double, MPI_DOUBLE);
91 GKO_REGISTER_MPI_TYPE(
long double, MPI_LONG_DOUBLE);
92 #if GINKGO_ENABLE_HALF
96 GKO_REGISTER_MPI_TYPE(
half, MPI_UNSIGNED_SHORT);
97 GKO_REGISTER_MPI_TYPE(std::complex<half>, MPI_FLOAT);
98 #endif // GKO_ENABLE_HALF
99 #if GINKGO_ENABLE_BFLOAT16
100 GKO_REGISTER_MPI_TYPE(
bfloat16, MPI_UNSIGNED_SHORT);
101 GKO_REGISTER_MPI_TYPE(std::complex<bfloat16>, MPI_FLOAT);
102 #endif // GKO_ENABLE_BFLOAT16
103 GKO_REGISTER_MPI_TYPE(std::complex<float>, MPI_C_FLOAT_COMPLEX);
104 GKO_REGISTER_MPI_TYPE(std::complex<double>, MPI_C_DOUBLE_COMPLEX);
123 GKO_ASSERT_NO_MPI_ERRORS(MPI_Type_contiguous(count, old_type, &type_));
124 GKO_ASSERT_NO_MPI_ERRORS(MPI_Type_commit(&type_));
149 *
this = std::move(other);
161 if (
this != &other) {
162 this->type_ = std::exchange(other.type_, MPI_DATATYPE_NULL);
172 if (type_ != MPI_DATATYPE_NULL) {
173 MPI_Type_free(&type_);
182 MPI_Datatype
get()
const {
return type_; }
194 serialized = MPI_THREAD_SERIALIZED,
195 funneled = MPI_THREAD_FUNNELED,
196 single = MPI_THREAD_SINGLE,
197 multiple = MPI_THREAD_MULTIPLE
212 static bool is_finalized()
215 GKO_ASSERT_NO_MPI_ERRORS(MPI_Finalized(&flag));
219 static bool is_initialized()
222 GKO_ASSERT_NO_MPI_ERRORS(MPI_Initialized(&flag));
242 const thread_type thread_t = thread_type::serialized)
244 this->required_thread_support_ = static_cast<int>(thread_t);
245 GKO_ASSERT_NO_MPI_ERRORS(
246 MPI_Init_thread(&argc, &argv, this->required_thread_support_,
247 &(this->provided_thread_support_)));
261 int required_thread_support_;
262 int provided_thread_support_;
275 using pointer = MPI_Comm*;
276 void operator()(pointer comm)
const
278 GKO_ASSERT(*comm != MPI_COMM_NULL);
279 GKO_ASSERT_NO_MPI_ERRORS(MPI_Comm_free(comm));
302 MPI_Status*
get() {
return &this->status_; }
314 template <
typename T>
348 this->req_ = std::exchange(o.req_, MPI_REQUEST_NULL);
355 if (req_ != MPI_REQUEST_NULL) {
356 if (MPI_Request_free(&req_) != MPI_SUCCESS) {
368 MPI_Request*
get() {
return &this->req_; }
379 GKO_ASSERT_NO_MPI_ERRORS(MPI_Wait(&req_,
status.
get()));
395 inline std::vector<status>
wait_all(std::vector<request>& req)
397 std::vector<status> stat;
398 for (std::size_t i = 0; i < req.size(); ++i) {
399 stat.emplace_back(req[i].wait());
432 : comm_(), force_host_buffer_(force_host_buffer)
434 this->comm_.reset(
new MPI_Comm(comm));
448 GKO_ASSERT_NO_MPI_ERRORS(MPI_Comm_split(comm, color, key, &comm_out));
449 this->comm_.reset(
new MPI_Comm(comm_out), comm_deleter{});
463 GKO_ASSERT_NO_MPI_ERRORS(
464 MPI_Comm_split(comm.
get(), color, key, &comm_out));
465 this->comm_.reset(
new MPI_Comm(comm_out), comm_deleter{});
478 bool force_host_buffer =
false)
480 communicator comm_out(MPI_COMM_NULL, force_host_buffer);
481 comm_out.comm_.reset(
new MPI_Comm(comm), comm_deleter{});
510 if (
this != &other) {
511 comm_ = std::exchange(other.comm_,
512 std::make_shared<MPI_Comm>(MPI_COMM_NULL));
513 force_host_buffer_ = other.force_host_buffer_;
523 const MPI_Comm&
get()
const {
return *(this->comm_.get()); }
525 bool force_host_buffer()
const {
return force_host_buffer_; }
532 int size()
const {
return get_num_ranks(); }
539 int rank()
const {
return get_my_rank(); };
573 if (
get() == MPI_COMM_NULL || rhs.get() == MPI_COMM_NULL) {
574 return get() == rhs.get();
577 GKO_ASSERT_NO_MPI_ERRORS(MPI_Comm_compare(
get(), rhs.get(), &flag));
578 return flag == MPI_IDENT;
595 if (
get() == MPI_COMM_NULL || rhs.get() == MPI_COMM_NULL) {
596 return get() == rhs.get();
599 GKO_ASSERT_NO_MPI_ERRORS(MPI_Comm_compare(
get(), rhs.get(), &flag));
600 return flag == MPI_CONGRUENT;
609 GKO_ASSERT_NO_MPI_ERRORS(MPI_Barrier(this->
get()));
625 template <
typename SendType>
626 void send(std::shared_ptr<const Executor> exec,
const SendType* send_buffer,
627 const int send_count,
const int destination_rank,
628 const int send_tag)
const
630 auto guard = exec->get_scoped_device_id_guard();
631 GKO_ASSERT_NO_MPI_ERRORS(
633 destination_rank, send_tag, this->
get()));
652 template <
typename SendType>
654 const SendType* send_buffer,
const int send_count,
655 const int destination_rank,
const int send_tag)
const
657 auto guard = exec->get_scoped_device_id_guard();
659 GKO_ASSERT_NO_MPI_ERRORS(
661 destination_rank, send_tag, this->
get(), req.
get()));
680 template <
typename RecvType>
681 status recv(std::shared_ptr<const Executor> exec, RecvType* recv_buffer,
682 const int recv_count,
const int source_rank,
683 const int recv_tag)
const
685 auto guard = exec->get_scoped_device_id_guard();
687 GKO_ASSERT_NO_MPI_ERRORS(
689 source_rank, recv_tag, this->
get(), st.
get()));
708 template <
typename RecvType>
710 const int recv_count,
const int source_rank,
711 const int recv_tag)
const
713 auto guard = exec->get_scoped_device_id_guard();
715 GKO_ASSERT_NO_MPI_ERRORS(
717 source_rank, recv_tag, this->
get(), req.
get()));
733 template <
typename BroadcastType>
734 void broadcast(std::shared_ptr<const Executor> exec, BroadcastType* buffer,
735 int count,
int root_rank)
const
737 auto guard = exec->get_scoped_device_id_guard();
738 GKO_ASSERT_NO_MPI_ERRORS(MPI_Bcast(buffer, count,
740 root_rank, this->
get()));
758 template <
typename BroadcastType>
760 BroadcastType* buffer,
int count,
int root_rank)
const
762 auto guard = exec->get_scoped_device_id_guard();
764 GKO_ASSERT_NO_MPI_ERRORS(
766 root_rank, this->
get(), req.
get()));
784 template <
typename ReduceType>
785 void reduce(std::shared_ptr<const Executor> exec,
786 const ReduceType* send_buffer, ReduceType* recv_buffer,
787 int count, MPI_Op operation,
int root_rank)
const
789 auto guard = exec->get_scoped_device_id_guard();
790 GKO_ASSERT_NO_MPI_ERRORS(MPI_Reduce(send_buffer, recv_buffer, count,
792 operation, root_rank, this->
get()));
811 template <
typename ReduceType>
813 const ReduceType* send_buffer, ReduceType* recv_buffer,
814 int count, MPI_Op operation,
int root_rank)
const
816 auto guard = exec->get_scoped_device_id_guard();
818 GKO_ASSERT_NO_MPI_ERRORS(MPI_Ireduce(
820 operation, root_rank, this->
get(), req.
get()));
837 template <
typename ReduceType>
839 ReduceType* recv_buffer,
int count, MPI_Op operation)
const
841 auto guard = exec->get_scoped_device_id_guard();
842 GKO_ASSERT_NO_MPI_ERRORS(MPI_Allreduce(
844 operation, this->
get()));
862 template <
typename ReduceType>
864 ReduceType* recv_buffer,
int count,
865 MPI_Op operation)
const
867 auto guard = exec->get_scoped_device_id_guard();
869 GKO_ASSERT_NO_MPI_ERRORS(MPI_Iallreduce(
871 operation, this->
get(), req.
get()));
889 template <
typename ReduceType>
891 const ReduceType* send_buffer, ReduceType* recv_buffer,
892 int count, MPI_Op operation)
const
894 auto guard = exec->get_scoped_device_id_guard();
895 GKO_ASSERT_NO_MPI_ERRORS(MPI_Allreduce(
897 operation, this->
get()));
916 template <
typename ReduceType>
918 const ReduceType* send_buffer, ReduceType* recv_buffer,
919 int count, MPI_Op operation)
const
921 auto guard = exec->get_scoped_device_id_guard();
923 GKO_ASSERT_NO_MPI_ERRORS(MPI_Iallreduce(
925 operation, this->
get(), req.
get()));
945 template <
typename SendType,
typename RecvType>
946 void gather(std::shared_ptr<const Executor> exec,
947 const SendType* send_buffer,
const int send_count,
948 RecvType* recv_buffer,
const int recv_count,
951 auto guard = exec->get_scoped_device_id_guard();
952 GKO_ASSERT_NO_MPI_ERRORS(
955 root_rank, this->
get()));
977 template <
typename SendType,
typename RecvType>
979 const SendType* send_buffer,
const int send_count,
980 RecvType* recv_buffer,
const int recv_count,
983 auto guard = exec->get_scoped_device_id_guard();
985 GKO_ASSERT_NO_MPI_ERRORS(MPI_Igather(
1010 template <
typename SendType,
typename RecvType>
1012 const SendType* send_buffer,
const int send_count,
1013 RecvType* recv_buffer,
const int* recv_counts,
1014 const int* displacements,
int root_rank)
const
1016 auto guard = exec->get_scoped_device_id_guard();
1017 GKO_ASSERT_NO_MPI_ERRORS(MPI_Gatherv(
1019 recv_buffer, recv_counts, displacements,
1043 template <
typename SendType,
typename RecvType>
1045 const SendType* send_buffer,
const int send_count,
1046 RecvType* recv_buffer,
const int* recv_counts,
1047 const int* displacements,
int root_rank)
const
1049 auto guard = exec->get_scoped_device_id_guard();
1051 GKO_ASSERT_NO_MPI_ERRORS(MPI_Igatherv(
1053 recv_buffer, recv_counts, displacements,
1074 template <
typename SendType,
typename RecvType>
1076 const SendType* send_buffer,
const int send_count,
1077 RecvType* recv_buffer,
const int recv_count)
const
1079 auto guard = exec->get_scoped_device_id_guard();
1080 GKO_ASSERT_NO_MPI_ERRORS(MPI_Allgather(
1104 template <
typename SendType,
typename RecvType>
1106 const SendType* send_buffer,
const int send_count,
1107 RecvType* recv_buffer,
const int recv_count)
const
1109 auto guard = exec->get_scoped_device_id_guard();
1111 GKO_ASSERT_NO_MPI_ERRORS(MPI_Iallgather(
1114 this->
get(), req.
get()));
1133 template <
typename SendType,
typename RecvType>
1134 void scatter(std::shared_ptr<const Executor> exec,
1135 const SendType* send_buffer,
const int send_count,
1136 RecvType* recv_buffer,
const int recv_count,
1137 int root_rank)
const
1139 auto guard = exec->get_scoped_device_id_guard();
1140 GKO_ASSERT_NO_MPI_ERRORS(MPI_Scatter(
1164 template <
typename SendType,
typename RecvType>
1166 const SendType* send_buffer,
const int send_count,
1167 RecvType* recv_buffer,
const int recv_count,
1168 int root_rank)
const
1170 auto guard = exec->get_scoped_device_id_guard();
1172 GKO_ASSERT_NO_MPI_ERRORS(MPI_Iscatter(
1175 this->
get(), req.
get()));
1197 template <
typename SendType,
typename RecvType>
1199 const SendType* send_buffer,
const int* send_counts,
1200 const int* displacements, RecvType* recv_buffer,
1201 const int recv_count,
int root_rank)
const
1203 auto guard = exec->get_scoped_device_id_guard();
1204 GKO_ASSERT_NO_MPI_ERRORS(MPI_Scatterv(
1205 send_buffer, send_counts, displacements,
1230 template <
typename SendType,
typename RecvType>
1232 const SendType* send_buffer,
const int* send_counts,
1233 const int* displacements, RecvType* recv_buffer,
1234 const int recv_count,
int root_rank)
const
1236 auto guard = exec->get_scoped_device_id_guard();
1238 GKO_ASSERT_NO_MPI_ERRORS(
1239 MPI_Iscatterv(send_buffer, send_counts, displacements,
1242 root_rank, this->
get(), req.
get()));
1262 template <
typename RecvType>
1263 void all_to_all(std::shared_ptr<const Executor> exec, RecvType* recv_buffer,
1264 const int recv_count)
const
1266 auto guard = exec->get_scoped_device_id_guard();
1267 GKO_ASSERT_NO_MPI_ERRORS(MPI_Alltoall(
1291 template <
typename RecvType>
1293 RecvType* recv_buffer,
const int recv_count)
const
1295 auto guard = exec->get_scoped_device_id_guard();
1297 GKO_ASSERT_NO_MPI_ERRORS(MPI_Ialltoall(
1300 this->
get(), req.
get()));
1320 template <
typename SendType,
typename RecvType>
1322 const SendType* send_buffer,
const int send_count,
1323 RecvType* recv_buffer,
const int recv_count)
const
1325 auto guard = exec->get_scoped_device_id_guard();
1326 GKO_ASSERT_NO_MPI_ERRORS(MPI_Alltoall(
1350 template <
typename SendType,
typename RecvType>
1352 const SendType* send_buffer,
const int send_count,
1353 RecvType* recv_buffer,
const int recv_count)
const
1355 auto guard = exec->get_scoped_device_id_guard();
1357 GKO_ASSERT_NO_MPI_ERRORS(MPI_Ialltoall(
1360 this->
get(), req.
get()));
1383 template <
typename SendType,
typename RecvType>
1385 const SendType* send_buffer,
const int* send_counts,
1386 const int* send_offsets, RecvType* recv_buffer,
1387 const int* recv_counts,
const int* recv_offsets)
const
1389 this->
all_to_all_v(std::move(exec), send_buffer, send_counts,
1391 recv_buffer, recv_counts, recv_offsets,
1411 const void* send_buffer,
const int* send_counts,
1412 const int* send_offsets, MPI_Datatype send_type,
1413 void* recv_buffer,
const int* recv_counts,
1414 const int* recv_offsets, MPI_Datatype recv_type)
const
1416 auto guard = exec->get_scoped_device_id_guard();
1417 GKO_ASSERT_NO_MPI_ERRORS(MPI_Alltoallv(
1418 send_buffer, send_counts, send_offsets, send_type, recv_buffer,
1419 recv_counts, recv_offsets, recv_type, this->
get()));
1442 const void* send_buffer,
const int* send_counts,
1443 const int* send_offsets, MPI_Datatype send_type,
1444 void* recv_buffer,
const int* recv_counts,
1445 const int* recv_offsets,
1446 MPI_Datatype recv_type)
const
1448 auto guard = exec->get_scoped_device_id_guard();
1450 GKO_ASSERT_NO_MPI_ERRORS(MPI_Ialltoallv(
1451 send_buffer, send_counts, send_offsets, send_type, recv_buffer,
1452 recv_counts, recv_offsets, recv_type, this->
get(), req.
get()));
1476 template <
typename SendType,
typename RecvType>
1478 const SendType* send_buffer,
const int* send_counts,
1479 const int* send_offsets, RecvType* recv_buffer,
1480 const int* recv_counts,
1481 const int* recv_offsets)
const
1484 std::move(exec), send_buffer, send_counts, send_offsets,
1503 template <
typename ScanType>
1504 void scan(std::shared_ptr<const Executor> exec,
const ScanType* send_buffer,
1505 ScanType* recv_buffer,
int count, MPI_Op operation)
const
1507 auto guard = exec->get_scoped_device_id_guard();
1508 GKO_ASSERT_NO_MPI_ERRORS(MPI_Scan(send_buffer, recv_buffer, count,
1510 operation, this->
get()));
1529 template <
typename ScanType>
1531 const ScanType* send_buffer, ScanType* recv_buffer,
1532 int count, MPI_Op operation)
const
1534 auto guard = exec->get_scoped_device_id_guard();
1536 GKO_ASSERT_NO_MPI_ERRORS(MPI_Iscan(send_buffer, recv_buffer, count,
1538 operation, this->
get(), req.
get()));
1543 std::shared_ptr<MPI_Comm> comm_;
1544 bool force_host_buffer_;
1546 int get_my_rank()
const
1549 GKO_ASSERT_NO_MPI_ERRORS(MPI_Comm_rank(
get(), &my_rank));
1553 int get_node_local_rank()
const
1555 MPI_Comm local_comm;
1557 GKO_ASSERT_NO_MPI_ERRORS(MPI_Comm_split_type(
1558 this->
get(), MPI_COMM_TYPE_SHARED, 0, MPI_INFO_NULL, &local_comm));
1559 GKO_ASSERT_NO_MPI_ERRORS(MPI_Comm_rank(local_comm, &
rank));
1560 MPI_Comm_free(&local_comm);
1564 int get_num_ranks()
const
1567 GKO_ASSERT_NO_MPI_ERRORS(MPI_Comm_size(this->
get(), &size));
1578 const communicator& comm);
1597 template <
typename ValueType>
1603 enum class create_type { allocate = 1, create = 2, dynamic_create = 3 };
1625 window(
window&& other) : window_{std::exchange(other.window_, MPI_WIN_NULL)}
1636 window_ = std::exchange(other.window_, MPI_WIN_NULL);
1651 window(std::shared_ptr<const Executor> exec, ValueType* base,
int num_elems,
1652 const communicator& comm,
const int disp_unit =
sizeof(ValueType),
1653 MPI_Info input_info = MPI_INFO_NULL,
1656 auto guard = exec->get_scoped_device_id_guard();
1657 unsigned size = num_elems *
sizeof(ValueType);
1658 if (c_type == create_type::create) {
1659 GKO_ASSERT_NO_MPI_ERRORS(MPI_Win_create(
1660 base, size, disp_unit, input_info, comm.
get(), &this->window_));
1661 }
else if (c_type == create_type::dynamic_create) {
1662 GKO_ASSERT_NO_MPI_ERRORS(
1663 MPI_Win_create_dynamic(input_info, comm.
get(), &this->window_));
1664 }
else if (c_type == create_type::allocate) {
1665 GKO_ASSERT_NO_MPI_ERRORS(MPI_Win_allocate(
1666 size, disp_unit, input_info, comm.
get(), base, &this->window_));
1668 GKO_NOT_IMPLEMENTED;
1687 GKO_ASSERT_NO_MPI_ERRORS(MPI_Win_fence(assert, this->window_));
1699 int assert = 0)
const
1701 if (lock_t == lock_type::shared) {
1702 GKO_ASSERT_NO_MPI_ERRORS(
1703 MPI_Win_lock(MPI_LOCK_SHARED, rank, assert, this->window_));
1704 }
else if (lock_t == lock_type::exclusive) {
1705 GKO_ASSERT_NO_MPI_ERRORS(
1706 MPI_Win_lock(MPI_LOCK_EXCLUSIVE, rank, assert, this->window_));
1708 GKO_NOT_IMPLEMENTED;
1720 GKO_ASSERT_NO_MPI_ERRORS(MPI_Win_unlock(rank, this->window_));
1731 GKO_ASSERT_NO_MPI_ERRORS(MPI_Win_lock_all(assert, this->window_));
1740 GKO_ASSERT_NO_MPI_ERRORS(MPI_Win_unlock_all(this->window_));
1751 GKO_ASSERT_NO_MPI_ERRORS(MPI_Win_flush(rank, this->window_));
1762 GKO_ASSERT_NO_MPI_ERRORS(MPI_Win_flush_local(rank, this->window_));
1771 GKO_ASSERT_NO_MPI_ERRORS(MPI_Win_flush_all(this->window_));
1780 GKO_ASSERT_NO_MPI_ERRORS(MPI_Win_flush_local_all(this->window_));
1786 void sync()
const { GKO_ASSERT_NO_MPI_ERRORS(MPI_Win_sync(this->window_)); }
1793 if (this->window_ && this->window_ != MPI_WIN_NULL) {
1794 MPI_Win_free(&this->window_);
1808 template <
typename PutType>
1809 void put(std::shared_ptr<const Executor> exec,
const PutType* origin_buffer,
1810 const int origin_count,
const int target_rank,
1811 const unsigned int target_disp,
const int target_count)
const
1813 auto guard = exec->get_scoped_device_id_guard();
1814 GKO_ASSERT_NO_MPI_ERRORS(
1816 target_rank, target_disp, target_count,
1832 template <
typename PutType>
1834 const PutType* origin_buffer,
const int origin_count,
1835 const int target_rank,
const unsigned int target_disp,
1836 const int target_count)
const
1838 auto guard = exec->get_scoped_device_id_guard();
1840 GKO_ASSERT_NO_MPI_ERRORS(MPI_Rput(
1842 target_rank, target_disp, target_count,
1858 template <
typename PutType>
1860 const PutType* origin_buffer,
const int origin_count,
1861 const int target_rank,
const unsigned int target_disp,
1862 const int target_count, MPI_Op operation)
const
1864 auto guard = exec->get_scoped_device_id_guard();
1865 GKO_ASSERT_NO_MPI_ERRORS(MPI_Accumulate(
1867 target_rank, target_disp, target_count,
1884 template <
typename PutType>
1886 const PutType* origin_buffer,
const int origin_count,
1887 const int target_rank,
const unsigned int target_disp,
1888 const int target_count, MPI_Op operation)
const
1890 auto guard = exec->get_scoped_device_id_guard();
1892 GKO_ASSERT_NO_MPI_ERRORS(MPI_Raccumulate(
1894 target_rank, target_disp, target_count,
1910 template <
typename GetType>
1911 void get(std::shared_ptr<const Executor> exec, GetType* origin_buffer,
1912 const int origin_count,
const int target_rank,
1913 const unsigned int target_disp,
const int target_count)
const
1915 auto guard = exec->get_scoped_device_id_guard();
1916 GKO_ASSERT_NO_MPI_ERRORS(
1918 target_rank, target_disp, target_count,
1934 template <
typename GetType>
1935 request r_get(std::shared_ptr<const Executor> exec, GetType* origin_buffer,
1936 const int origin_count,
const int target_rank,
1937 const unsigned int target_disp,
const int target_count)
const
1939 auto guard = exec->get_scoped_device_id_guard();
1941 GKO_ASSERT_NO_MPI_ERRORS(MPI_Rget(
1943 target_rank, target_disp, target_count,
1961 template <
typename GetType>
1963 GetType* origin_buffer,
const int origin_count,
1964 GetType* result_buffer,
const int result_count,
1965 const int target_rank,
const unsigned int target_disp,
1966 const int target_count, MPI_Op operation)
const
1968 auto guard = exec->get_scoped_device_id_guard();
1969 GKO_ASSERT_NO_MPI_ERRORS(MPI_Get_accumulate(
1972 target_rank, target_disp, target_count,
1991 template <
typename GetType>
1993 GetType* origin_buffer,
const int origin_count,
1994 GetType* result_buffer,
const int result_count,
1995 const int target_rank,
1996 const unsigned int target_disp,
1997 const int target_count, MPI_Op operation)
const
1999 auto guard = exec->get_scoped_device_id_guard();
2001 GKO_ASSERT_NO_MPI_ERRORS(MPI_Rget_accumulate(
2004 target_rank, target_disp, target_count,
2020 template <
typename GetType>
2022 GetType* origin_buffer, GetType* result_buffer,
2023 const int target_rank,
const unsigned int target_disp,
2024 MPI_Op operation)
const
2026 auto guard = exec->get_scoped_device_id_guard();
2027 GKO_ASSERT_NO_MPI_ERRORS(MPI_Fetch_and_op(
2029 target_rank, target_disp, operation, this->
get_window()));
2042 #endif // GKO_HAVE_MPI
2045 #endif // GKO_PUBLIC_CORE_BASE_MPI_HPP_