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 {
43 #if GINKGO_HAVE_GPU_AWARE_MPI
61 #define GKO_REGISTER_MPI_TYPE(input_type, mpi_type) \
63 struct type_impl<input_type> { \
64 static MPI_Datatype get_type() { return mpi_type; } \
79 GKO_REGISTER_MPI_TYPE(
char, MPI_CHAR);
80 GKO_REGISTER_MPI_TYPE(
unsigned char, MPI_UNSIGNED_CHAR);
81 GKO_REGISTER_MPI_TYPE(
unsigned, MPI_UNSIGNED);
82 GKO_REGISTER_MPI_TYPE(
int, MPI_INT);
83 GKO_REGISTER_MPI_TYPE(
unsigned short, MPI_UNSIGNED_SHORT);
84 GKO_REGISTER_MPI_TYPE(
unsigned long, MPI_UNSIGNED_LONG);
85 GKO_REGISTER_MPI_TYPE(
long, MPI_LONG);
86 GKO_REGISTER_MPI_TYPE(
long long, MPI_LONG_LONG_INT);
87 GKO_REGISTER_MPI_TYPE(
unsigned long long, MPI_UNSIGNED_LONG_LONG);
88 GKO_REGISTER_MPI_TYPE(
float, MPI_FLOAT);
89 GKO_REGISTER_MPI_TYPE(
double, MPI_DOUBLE);
90 GKO_REGISTER_MPI_TYPE(
long double, MPI_LONG_DOUBLE);
91 #if GINKGO_ENABLE_HALF
95 GKO_REGISTER_MPI_TYPE(
half, MPI_UNSIGNED_SHORT);
96 GKO_REGISTER_MPI_TYPE(std::complex<half>, MPI_FLOAT);
97 #endif // GKO_ENABLE_HALF
98 #if GINKGO_ENABLE_BFLOAT16
99 GKO_REGISTER_MPI_TYPE(
bfloat16, MPI_UNSIGNED_SHORT);
100 GKO_REGISTER_MPI_TYPE(std::complex<bfloat16>, MPI_FLOAT);
101 #endif // GKO_ENABLE_BFLOAT16
102 GKO_REGISTER_MPI_TYPE(std::complex<float>, MPI_C_FLOAT_COMPLEX);
103 GKO_REGISTER_MPI_TYPE(std::complex<double>, MPI_C_DOUBLE_COMPLEX);
122 GKO_ASSERT_NO_MPI_ERRORS(MPI_Type_contiguous(count, old_type, &type_));
123 GKO_ASSERT_NO_MPI_ERRORS(MPI_Type_commit(&type_));
148 *
this = std::move(other);
160 if (
this != &other) {
161 this->type_ = std::exchange(other.type_, MPI_DATATYPE_NULL);
171 if (type_ != MPI_DATATYPE_NULL) {
172 MPI_Type_free(&type_);
181 MPI_Datatype
get()
const {
return type_; }
193 serialized = MPI_THREAD_SERIALIZED,
194 funneled = MPI_THREAD_FUNNELED,
195 single = MPI_THREAD_SINGLE,
196 multiple = MPI_THREAD_MULTIPLE
211 static bool is_finalized()
214 GKO_ASSERT_NO_MPI_ERRORS(MPI_Finalized(&flag));
218 static bool is_initialized()
221 GKO_ASSERT_NO_MPI_ERRORS(MPI_Initialized(&flag));
241 const thread_type thread_t = thread_type::serialized)
243 this->required_thread_support_ = static_cast<int>(thread_t);
244 GKO_ASSERT_NO_MPI_ERRORS(
245 MPI_Init_thread(&argc, &argv, this->required_thread_support_,
246 &(this->provided_thread_support_)));
260 int required_thread_support_;
261 int provided_thread_support_;
274 using pointer = MPI_Comm*;
275 void operator()(pointer comm)
const
277 GKO_ASSERT(*comm != MPI_COMM_NULL);
278 GKO_ASSERT_NO_MPI_ERRORS(MPI_Comm_free(comm));
301 MPI_Status*
get() {
return &this->status_; }
313 template <
typename T>
347 this->req_ = std::exchange(o.req_, MPI_REQUEST_NULL);
354 if (req_ != MPI_REQUEST_NULL) {
355 if (MPI_Request_free(&req_) != MPI_SUCCESS) {
367 MPI_Request*
get() {
return &this->req_; }
378 GKO_ASSERT_NO_MPI_ERRORS(MPI_Wait(&req_,
status.
get()));
394 inline std::vector<status>
wait_all(std::vector<request>& req)
396 std::vector<status> stat;
397 for (std::size_t i = 0; i < req.size(); ++i) {
398 stat.emplace_back(req[i].wait());
431 : comm_(), force_host_buffer_(force_host_buffer)
433 this->comm_.reset(
new MPI_Comm(comm));
445 : force_host_buffer_(false)
448 GKO_ASSERT_NO_MPI_ERRORS(MPI_Comm_split(comm, color, key, &comm_out));
449 this->comm_.reset(
new MPI_Comm(comm_out), detail::comm_deleter{});
461 : force_host_buffer_(comm.force_host_buffer())
464 GKO_ASSERT_NO_MPI_ERRORS(
465 MPI_Comm_split(comm.
get(), color, key, &comm_out));
466 this->comm_.reset(
new MPI_Comm(comm_out), detail::comm_deleter{});
479 bool force_host_buffer =
false)
481 communicator comm_out(MPI_COMM_NULL, force_host_buffer);
482 comm_out.comm_.reset(
new MPI_Comm(comm), detail::comm_deleter{});
511 if (
this != &other) {
512 comm_ = std::exchange(other.comm_,
513 std::make_shared<MPI_Comm>(MPI_COMM_NULL));
514 force_host_buffer_ = other.force_host_buffer_;
524 const MPI_Comm&
get()
const {
return *(this->comm_.get()); }
526 bool force_host_buffer()
const {
return force_host_buffer_; }
533 int size()
const {
return get_num_ranks(); }
540 int rank()
const {
return get_my_rank(); };
574 if (
get() == MPI_COMM_NULL || rhs.get() == MPI_COMM_NULL) {
575 return get() == rhs.get();
578 GKO_ASSERT_NO_MPI_ERRORS(MPI_Comm_compare(
get(), rhs.get(), &flag));
579 return flag == MPI_IDENT;
596 if (
get() == MPI_COMM_NULL || rhs.get() == MPI_COMM_NULL) {
597 return get() == rhs.get();
600 GKO_ASSERT_NO_MPI_ERRORS(MPI_Comm_compare(
get(), rhs.get(), &flag));
601 return flag == MPI_CONGRUENT;
610 GKO_ASSERT_NO_MPI_ERRORS(MPI_Barrier(this->
get()));
626 template <
typename SendType>
627 void send(std::shared_ptr<const Executor> exec,
const SendType* send_buffer,
628 const int send_count,
const int destination_rank,
629 const int send_tag)
const
631 auto guard = exec->get_scoped_device_id_guard();
632 GKO_ASSERT_NO_MPI_ERRORS(
634 destination_rank, send_tag, this->
get()));
653 template <
typename SendType>
655 const SendType* send_buffer,
const int send_count,
656 const int destination_rank,
const int send_tag)
const
658 auto guard = exec->get_scoped_device_id_guard();
660 GKO_ASSERT_NO_MPI_ERRORS(
662 destination_rank, send_tag, this->
get(), req.
get()));
681 template <
typename RecvType>
682 status recv(std::shared_ptr<const Executor> exec, RecvType* recv_buffer,
683 const int recv_count,
const int source_rank,
684 const int recv_tag)
const
686 auto guard = exec->get_scoped_device_id_guard();
688 GKO_ASSERT_NO_MPI_ERRORS(
690 source_rank, recv_tag, this->
get(), st.
get()));
709 template <
typename RecvType>
711 const int recv_count,
const int source_rank,
712 const int recv_tag)
const
714 auto guard = exec->get_scoped_device_id_guard();
716 GKO_ASSERT_NO_MPI_ERRORS(
718 source_rank, recv_tag, this->
get(), req.
get()));
734 template <
typename BroadcastType>
735 void broadcast(std::shared_ptr<const Executor> exec, BroadcastType* buffer,
736 int count,
int root_rank)
const
738 auto guard = exec->get_scoped_device_id_guard();
739 GKO_ASSERT_NO_MPI_ERRORS(MPI_Bcast(buffer, count,
741 root_rank, this->
get()));
759 template <
typename BroadcastType>
761 BroadcastType* buffer,
int count,
int root_rank)
const
763 auto guard = exec->get_scoped_device_id_guard();
765 GKO_ASSERT_NO_MPI_ERRORS(
767 root_rank, this->
get(), req.
get()));
786 template <
typename ReduceType>
787 void reduce(std::shared_ptr<const Executor> exec,
788 const ReduceType* send_buffer, ReduceType* recv_buffer,
789 int count, MPI_Op operation,
int root_rank)
const
791 auto guard = exec->get_scoped_device_id_guard();
792 GKO_ASSERT_NO_MPI_ERRORS(MPI_Reduce(send_buffer, recv_buffer, count,
794 operation, root_rank, this->
get()));
814 template <
typename ReduceType>
816 const ReduceType* send_buffer, ReduceType* recv_buffer,
817 int count, MPI_Op operation,
int root_rank)
const
819 auto guard = exec->get_scoped_device_id_guard();
821 GKO_ASSERT_NO_MPI_ERRORS(MPI_Ireduce(
823 operation, root_rank, this->
get(), req.
get()));
840 template <
typename ReduceType>
842 ReduceType* recv_buffer,
int count, MPI_Op operation)
const
844 auto guard = exec->get_scoped_device_id_guard();
845 GKO_ASSERT_NO_MPI_ERRORS(MPI_Allreduce(
847 operation, this->
get()));
865 template <
typename ReduceType>
867 ReduceType* recv_buffer,
int count,
868 MPI_Op operation)
const
870 auto guard = exec->get_scoped_device_id_guard();
872 GKO_ASSERT_NO_MPI_ERRORS(MPI_Iallreduce(
874 operation, this->
get(), req.
get()));
892 template <
typename ReduceType>
894 const ReduceType* send_buffer, ReduceType* recv_buffer,
895 int count, MPI_Op operation)
const
897 auto guard = exec->get_scoped_device_id_guard();
898 GKO_ASSERT_NO_MPI_ERRORS(MPI_Allreduce(
900 operation, this->
get()));
919 template <
typename ReduceType>
921 const ReduceType* send_buffer, ReduceType* recv_buffer,
922 int count, MPI_Op operation)
const
924 auto guard = exec->get_scoped_device_id_guard();
926 GKO_ASSERT_NO_MPI_ERRORS(MPI_Iallreduce(
928 operation, this->
get(), req.
get()));
948 template <
typename SendType,
typename RecvType>
949 void gather(std::shared_ptr<const Executor> exec,
950 const SendType* send_buffer,
const int send_count,
951 RecvType* recv_buffer,
const int recv_count,
954 auto guard = exec->get_scoped_device_id_guard();
955 GKO_ASSERT_NO_MPI_ERRORS(
958 root_rank, this->
get()));
980 template <
typename SendType,
typename RecvType>
982 const SendType* send_buffer,
const int send_count,
983 RecvType* recv_buffer,
const int recv_count,
986 auto guard = exec->get_scoped_device_id_guard();
988 GKO_ASSERT_NO_MPI_ERRORS(MPI_Igather(
1013 template <
typename SendType,
typename RecvType>
1015 const SendType* send_buffer,
const int send_count,
1016 RecvType* recv_buffer,
const int* recv_counts,
1017 const int* displacements,
int root_rank)
const
1019 auto guard = exec->get_scoped_device_id_guard();
1020 GKO_ASSERT_NO_MPI_ERRORS(MPI_Gatherv(
1022 recv_buffer, recv_counts, displacements,
1046 template <
typename SendType,
typename RecvType>
1048 const SendType* send_buffer,
const int send_count,
1049 RecvType* recv_buffer,
const int* recv_counts,
1050 const int* displacements,
int root_rank)
const
1052 auto guard = exec->get_scoped_device_id_guard();
1054 GKO_ASSERT_NO_MPI_ERRORS(MPI_Igatherv(
1056 recv_buffer, recv_counts, displacements,
1077 template <
typename SendType,
typename RecvType>
1079 const SendType* send_buffer,
const int send_count,
1080 RecvType* recv_buffer,
const int recv_count)
const
1082 auto guard = exec->get_scoped_device_id_guard();
1083 GKO_ASSERT_NO_MPI_ERRORS(MPI_Allgather(
1107 template <
typename SendType,
typename RecvType>
1109 const SendType* send_buffer,
const int send_count,
1110 RecvType* recv_buffer,
const int recv_count)
const
1112 auto guard = exec->get_scoped_device_id_guard();
1114 GKO_ASSERT_NO_MPI_ERRORS(MPI_Iallgather(
1117 this->
get(), req.
get()));
1137 template <
typename SendType,
typename RecvType>
1138 void scatter(std::shared_ptr<const Executor> exec,
1139 const SendType* send_buffer,
const int send_count,
1140 RecvType* recv_buffer,
const int recv_count,
1141 int root_rank)
const
1143 auto guard = exec->get_scoped_device_id_guard();
1144 GKO_ASSERT_NO_MPI_ERRORS(MPI_Scatter(
1169 template <
typename SendType,
typename RecvType>
1171 const SendType* send_buffer,
const int send_count,
1172 RecvType* recv_buffer,
const int recv_count,
1173 int root_rank)
const
1175 auto guard = exec->get_scoped_device_id_guard();
1177 GKO_ASSERT_NO_MPI_ERRORS(MPI_Iscatter(
1180 this->
get(), req.
get()));
1202 template <
typename SendType,
typename RecvType>
1204 const SendType* send_buffer,
const int* send_counts,
1205 const int* displacements, RecvType* recv_buffer,
1206 const int recv_count,
int root_rank)
const
1208 auto guard = exec->get_scoped_device_id_guard();
1209 GKO_ASSERT_NO_MPI_ERRORS(MPI_Scatterv(
1210 send_buffer, send_counts, displacements,
1235 template <
typename SendType,
typename RecvType>
1237 const SendType* send_buffer,
const int* send_counts,
1238 const int* displacements, RecvType* recv_buffer,
1239 const int recv_count,
int root_rank)
const
1241 auto guard = exec->get_scoped_device_id_guard();
1243 GKO_ASSERT_NO_MPI_ERRORS(
1244 MPI_Iscatterv(send_buffer, send_counts, displacements,
1247 root_rank, this->
get(), req.
get()));
1267 template <
typename RecvType>
1268 void all_to_all(std::shared_ptr<const Executor> exec, RecvType* recv_buffer,
1269 const int recv_count)
const
1271 auto guard = exec->get_scoped_device_id_guard();
1272 GKO_ASSERT_NO_MPI_ERRORS(MPI_Alltoall(
1296 template <
typename RecvType>
1298 RecvType* recv_buffer,
const int recv_count)
const
1300 auto guard = exec->get_scoped_device_id_guard();
1302 GKO_ASSERT_NO_MPI_ERRORS(MPI_Ialltoall(
1305 this->
get(), req.
get()));
1325 template <
typename SendType,
typename RecvType>
1327 const SendType* send_buffer,
const int send_count,
1328 RecvType* recv_buffer,
const int recv_count)
const
1330 auto guard = exec->get_scoped_device_id_guard();
1331 GKO_ASSERT_NO_MPI_ERRORS(MPI_Alltoall(
1355 template <
typename SendType,
typename RecvType>
1357 const SendType* send_buffer,
const int send_count,
1358 RecvType* recv_buffer,
const int recv_count)
const
1360 auto guard = exec->get_scoped_device_id_guard();
1362 GKO_ASSERT_NO_MPI_ERRORS(MPI_Ialltoall(
1365 this->
get(), req.
get()));
1388 template <
typename SendType,
typename RecvType>
1390 const SendType* send_buffer,
const int* send_counts,
1391 const int* send_offsets, RecvType* recv_buffer,
1392 const int* recv_counts,
const int* recv_offsets)
const
1394 this->
all_to_all_v(std::move(exec), send_buffer, send_counts,
1396 recv_buffer, recv_counts, recv_offsets,
1416 const void* send_buffer,
const int* send_counts,
1417 const int* send_offsets, MPI_Datatype send_type,
1418 void* recv_buffer,
const int* recv_counts,
1419 const int* recv_offsets, MPI_Datatype recv_type)
const
1421 auto guard = exec->get_scoped_device_id_guard();
1422 GKO_ASSERT_NO_MPI_ERRORS(MPI_Alltoallv(
1423 send_buffer, send_counts, send_offsets, send_type, recv_buffer,
1424 recv_counts, recv_offsets, recv_type, this->
get()));
1447 const void* send_buffer,
const int* send_counts,
1448 const int* send_offsets, MPI_Datatype send_type,
1449 void* recv_buffer,
const int* recv_counts,
1450 const int* recv_offsets,
1451 MPI_Datatype recv_type)
const
1453 auto guard = exec->get_scoped_device_id_guard();
1455 GKO_ASSERT_NO_MPI_ERRORS(MPI_Ialltoallv(
1456 send_buffer, send_counts, send_offsets, send_type, recv_buffer,
1457 recv_counts, recv_offsets, recv_type, this->
get(), req.
get()));
1481 template <
typename SendType,
typename RecvType>
1483 const SendType* send_buffer,
const int* send_counts,
1484 const int* send_offsets, RecvType* recv_buffer,
1485 const int* recv_counts,
1486 const int* recv_offsets)
const
1489 std::move(exec), send_buffer, send_counts, send_offsets,
1508 template <
typename ScanType>
1509 void scan(std::shared_ptr<const Executor> exec,
const ScanType* send_buffer,
1510 ScanType* recv_buffer,
int count, MPI_Op operation)
const
1512 auto guard = exec->get_scoped_device_id_guard();
1513 GKO_ASSERT_NO_MPI_ERRORS(MPI_Scan(send_buffer, recv_buffer, count,
1515 operation, this->
get()));
1534 template <
typename ScanType>
1536 const ScanType* send_buffer, ScanType* recv_buffer,
1537 int count, MPI_Op operation)
const
1539 auto guard = exec->get_scoped_device_id_guard();
1541 GKO_ASSERT_NO_MPI_ERRORS(MPI_Iscan(send_buffer, recv_buffer, count,
1543 operation, this->
get(), req.
get()));
1548 std::shared_ptr<MPI_Comm> comm_;
1549 bool force_host_buffer_;
1551 int get_my_rank()
const
1554 GKO_ASSERT_NO_MPI_ERRORS(MPI_Comm_rank(
get(), &my_rank));
1558 int get_node_local_rank()
const
1560 MPI_Comm local_comm;
1562 GKO_ASSERT_NO_MPI_ERRORS(MPI_Comm_split_type(
1563 this->
get(), MPI_COMM_TYPE_SHARED, 0, MPI_INFO_NULL, &local_comm));
1564 GKO_ASSERT_NO_MPI_ERRORS(MPI_Comm_rank(local_comm, &
rank));
1565 MPI_Comm_free(&local_comm);
1569 int get_num_ranks()
const
1572 GKO_ASSERT_NO_MPI_ERRORS(MPI_Comm_size(this->
get(), &size));
1583 const communicator& comm);
1602 template <
typename ValueType>
1608 enum class create_type { allocate = 1, create = 2, dynamic_create = 3 };
1631 : window_{std::exchange(other.window_, MPI_WIN_NULL)}
1642 if (
this != &other) {
1643 if (this->window_ && this->window_ != MPI_WIN_NULL) {
1644 MPI_Win_free(&this->window_);
1646 window_ = std::exchange(other.window_, MPI_WIN_NULL);
1663 window(std::shared_ptr<const Executor> exec, ValueType* base,
int num_elems,
1664 const communicator& comm,
const int disp_unit =
sizeof(ValueType),
1665 MPI_Info input_info = MPI_INFO_NULL,
1668 auto guard = exec->get_scoped_device_id_guard();
1669 unsigned size = num_elems *
sizeof(ValueType);
1670 if (c_type == create_type::create) {
1671 GKO_ASSERT_NO_MPI_ERRORS(MPI_Win_create(
1672 base, size, disp_unit, input_info, comm.
get(), &this->window_));
1673 }
else if (c_type == create_type::dynamic_create) {
1674 GKO_ASSERT_NO_MPI_ERRORS(
1675 MPI_Win_create_dynamic(input_info, comm.
get(), &this->window_));
1676 }
else if (c_type == create_type::allocate) {
1677 GKO_ASSERT_NO_MPI_ERRORS(MPI_Win_allocate(
1678 size, disp_unit, input_info, comm.
get(), base, &this->window_));
1680 GKO_NOT_IMPLEMENTED;
1699 GKO_ASSERT_NO_MPI_ERRORS(MPI_Win_fence(assert, this->window_));
1711 int assert = 0)
const
1713 if (lock_t == lock_type::shared) {
1714 GKO_ASSERT_NO_MPI_ERRORS(
1715 MPI_Win_lock(MPI_LOCK_SHARED, rank, assert, this->window_));
1716 }
else if (lock_t == lock_type::exclusive) {
1717 GKO_ASSERT_NO_MPI_ERRORS(
1718 MPI_Win_lock(MPI_LOCK_EXCLUSIVE, rank, assert, this->window_));
1720 GKO_NOT_IMPLEMENTED;
1732 GKO_ASSERT_NO_MPI_ERRORS(MPI_Win_unlock(rank, this->window_));
1743 GKO_ASSERT_NO_MPI_ERRORS(MPI_Win_lock_all(assert, this->window_));
1752 GKO_ASSERT_NO_MPI_ERRORS(MPI_Win_unlock_all(this->window_));
1763 GKO_ASSERT_NO_MPI_ERRORS(MPI_Win_flush(rank, this->window_));
1774 GKO_ASSERT_NO_MPI_ERRORS(MPI_Win_flush_local(rank, this->window_));
1783 GKO_ASSERT_NO_MPI_ERRORS(MPI_Win_flush_all(this->window_));
1792 GKO_ASSERT_NO_MPI_ERRORS(MPI_Win_flush_local_all(this->window_));
1798 void sync()
const { GKO_ASSERT_NO_MPI_ERRORS(MPI_Win_sync(this->window_)); }
1805 if (this->window_ && this->window_ != MPI_WIN_NULL) {
1806 MPI_Win_free(&this->window_);
1820 template <
typename PutType>
1821 void put(std::shared_ptr<const Executor> exec,
const PutType* origin_buffer,
1822 const int origin_count,
const int target_rank,
1823 const unsigned int target_disp,
const int target_count)
const
1825 auto guard = exec->get_scoped_device_id_guard();
1826 GKO_ASSERT_NO_MPI_ERRORS(
1828 target_rank, target_disp, target_count,
1844 template <
typename PutType>
1846 const PutType* origin_buffer,
const int origin_count,
1847 const int target_rank,
const unsigned int target_disp,
1848 const int target_count)
const
1850 auto guard = exec->get_scoped_device_id_guard();
1852 GKO_ASSERT_NO_MPI_ERRORS(MPI_Rput(
1854 target_rank, target_disp, target_count,
1870 template <
typename PutType>
1872 const PutType* origin_buffer,
const int origin_count,
1873 const int target_rank,
const unsigned int target_disp,
1874 const int target_count, MPI_Op operation)
const
1876 auto guard = exec->get_scoped_device_id_guard();
1877 GKO_ASSERT_NO_MPI_ERRORS(MPI_Accumulate(
1879 target_rank, target_disp, target_count,
1896 template <
typename PutType>
1898 const PutType* origin_buffer,
const int origin_count,
1899 const int target_rank,
const unsigned int target_disp,
1900 const int target_count, MPI_Op operation)
const
1902 auto guard = exec->get_scoped_device_id_guard();
1904 GKO_ASSERT_NO_MPI_ERRORS(MPI_Raccumulate(
1906 target_rank, target_disp, target_count,
1922 template <
typename GetType>
1923 void get(std::shared_ptr<const Executor> exec, GetType* origin_buffer,
1924 const int origin_count,
const int target_rank,
1925 const unsigned int target_disp,
const int target_count)
const
1927 auto guard = exec->get_scoped_device_id_guard();
1928 GKO_ASSERT_NO_MPI_ERRORS(
1930 target_rank, target_disp, target_count,
1946 template <
typename GetType>
1947 request r_get(std::shared_ptr<const Executor> exec, GetType* origin_buffer,
1948 const int origin_count,
const int target_rank,
1949 const unsigned int target_disp,
const int target_count)
const
1951 auto guard = exec->get_scoped_device_id_guard();
1953 GKO_ASSERT_NO_MPI_ERRORS(MPI_Rget(
1955 target_rank, target_disp, target_count,
1973 template <
typename GetType>
1975 GetType* origin_buffer,
const int origin_count,
1976 GetType* result_buffer,
const int result_count,
1977 const int target_rank,
const unsigned int target_disp,
1978 const int target_count, MPI_Op operation)
const
1980 auto guard = exec->get_scoped_device_id_guard();
1981 GKO_ASSERT_NO_MPI_ERRORS(MPI_Get_accumulate(
1984 target_rank, target_disp, target_count,
2003 template <
typename GetType>
2005 GetType* origin_buffer,
const int origin_count,
2006 GetType* result_buffer,
const int result_count,
2007 const int target_rank,
2008 const unsigned int target_disp,
2009 const int target_count, MPI_Op operation)
const
2011 auto guard = exec->get_scoped_device_id_guard();
2013 GKO_ASSERT_NO_MPI_ERRORS(MPI_Rget_accumulate(
2016 target_rank, target_disp, target_count,
2033 template <
typename GetType>
2035 GetType* origin_buffer, GetType* result_buffer,
2036 const int target_rank,
const unsigned int target_disp,
2037 MPI_Op operation)
const
2039 auto guard = exec->get_scoped_device_id_guard();
2040 GKO_ASSERT_NO_MPI_ERRORS(MPI_Fetch_and_op(
2042 target_rank, target_disp, operation, this->
get_window()));
2055 #endif // GKO_HAVE_MPI
2058 #endif // GKO_PUBLIC_CORE_BASE_MPI_HPP_