Skip to content

Commit d7d3d40

Browse files
MarcelKochyhmtsai
andcommitted
[coll-comm] review updates:
- documentation - formatting - refactor test - fix docs - merge tests Co-authored-by: Yu-Hsiang M. Tsai <[email protected]> Signed-off-by: Marcel Koch <[email protected]>
1 parent ab1cf94 commit d7d3d40

10 files changed

+308
-544
lines changed

core/distributed/collective_communicator.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44

55
#include "ginkgo/core/distributed/collective_communicator.hpp"
66

7+
#include <mpi.h>
8+
79

810
namespace gko {
911
namespace experimental {

core/distributed/neighborhood_communicator.cpp

+13-14
Original file line numberDiff line numberDiff line change
@@ -14,27 +14,27 @@ namespace mpi {
1414

1515

1616
/**
17-
* \brief Computes the inverse envelope (target-ids, sizes) for a given
17+
* @brief Computes the inverse envelope (target-ids, sizes) for a given
1818
* one-sided communication pattern.
1919
*
20-
* \param exec the executor, this will always use the host executor
21-
* \param comm communicator
22-
* \param ids target ids of the one-sided operation
23-
* \param sizes number of elements send to each id
20+
* @param exec the executor, this will always use the host executor
21+
* @param comm communicator
22+
* @param ids target ids of the one-sided operation
23+
* @param sizes number of elements send to each id
2424
*
25-
* \return the inverse envelope consisting of the target-ids and the sizes
25+
* @return the inverse envelope consisting of the target-ids and the sizes
2626
*/
2727
std::tuple<std::vector<comm_index_type>, std::vector<comm_index_type>>
2828
communicate_inverse_envelope(std::shared_ptr<const Executor> exec,
29-
mpi::communicator comm,
29+
communicator comm,
3030
const std::vector<comm_index_type>& ids,
3131
const std::vector<comm_index_type>& sizes)
3232
{
3333
auto host_exec = exec->get_master();
3434
std::vector<comm_index_type> inverse_sizes_full(comm.size());
35-
mpi::window<comm_index_type> window(host_exec, inverse_sizes_full.data(),
36-
inverse_sizes_full.size(), comm,
37-
sizeof(comm_index_type), MPI_INFO_ENV);
35+
window<comm_index_type> window(host_exec, inverse_sizes_full.data(),
36+
inverse_sizes_full.size(), comm,
37+
sizeof(comm_index_type), MPI_INFO_ENV);
3838
window.fence();
3939
for (int i = 0; i < ids.size(); ++i) {
4040
window.put(host_exec, sizes.data() + i, 1, ids[i], comm.rank(), 1);
@@ -61,8 +61,8 @@ communicate_inverse_envelope(std::shared_ptr<const Executor> exec,
6161
* The graph is unweighted and has the same rank ordering as the input
6262
* communicator.
6363
*/
64-
mpi::communicator create_neighborhood_comm(
65-
mpi::communicator base, const std::vector<comm_index_type>& sources,
64+
communicator create_neighborhood_comm(
65+
communicator base, const std::vector<comm_index_type>& sources,
6666
const std::vector<comm_index_type>& destinations)
6767
{
6868
auto in_degree = static_cast<comm_index_type>(sources.size());
@@ -80,8 +80,7 @@ mpi::communicator create_neighborhood_comm(
8080
info, false, &graph_comm));
8181
GKO_ASSERT_NO_MPI_ERRORS(MPI_Info_free(&info));
8282

83-
return mpi::communicator::create_owning(graph_comm,
84-
base.force_host_buffer());
83+
return communicator::create_owning(graph_comm, base.force_host_buffer());
8584
}
8685

8786

+1-5
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,7 @@
11
ginkgo_create_test(helpers MPI_SIZE 1)
22
ginkgo_create_test(matrix MPI_SIZE 1)
3-
ginkgo_create_test(dense_communicator MPI_SIZE 6)
3+
ginkgo_create_test(collective_communicator MPI_SIZE 6)
44
ginkgo_create_test(vector_cache MPI_SIZE 3)
55

6-
if(NOT GINKGO_HAVE_OPENMPI_PRE_4_1_X)
7-
ginkgo_create_test(neighborhood_communicator MPI_SIZE 6)
8-
endif()
9-
106
add_subdirectory(preconditioner)
117
add_subdirectory(solver)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,262 @@
1+
// SPDX-FileCopyrightText: 2017 - 2025 The Ginkgo authors
2+
//
3+
// SPDX-License-Identifier: BSD-3-Clause
4+
5+
#include <gtest/gtest.h>
6+
7+
#include <core/test/utils.hpp>
8+
9+
#include <ginkgo/core/distributed/dense_communicator.hpp>
10+
#include <ginkgo/core/distributed/neighborhood_communicator.hpp>
11+
12+
#include "core/test/utils/assertions.hpp"
13+
14+
using gko::experimental::mpi::comm_index_type;
15+
16+
template <typename CommunicatorType>
17+
class CollectiveCommunicator : public ::testing::Test {
18+
protected:
19+
using communicator_type = CommunicatorType;
20+
using part_type = gko::experimental::distributed::Partition<int, long>;
21+
using map_type = gko::experimental::distributed::index_map<int, long>;
22+
23+
void SetUp() override { ASSERT_EQ(comm.size(), 6); }
24+
25+
communicator_type create_default_comm()
26+
{
27+
auto part = gko::share(part_type::build_from_global_size_uniform(
28+
ref, comm.size(), comm.size() * 3));
29+
gko::array<long> recv_connections[] = {{ref, {3, 5, 10, 11}},
30+
{ref, {0, 1, 7, 12, 13}},
31+
{ref, {3, 4, 17}},
32+
{ref, {1, 2, 12, 14}},
33+
{ref, {4, 5, 9, 10, 16, 15}},
34+
{ref, {8, 12, 13, 14}}};
35+
auto imap = map_type{ref, part, comm.rank(), recv_connections[rank]};
36+
37+
return {comm, imap};
38+
}
39+
40+
std::shared_ptr<gko::Executor> ref = gko::ReferenceExecutor::create();
41+
gko::experimental::mpi::communicator comm = MPI_COMM_WORLD;
42+
std::array<gko::array<long>, 6> recv_connections{
43+
{{ref, {3, 5, 10, 11}},
44+
{ref, {0, 1, 7, 12, 13}},
45+
{ref, {3, 4, 17}},
46+
{ref, {1, 2, 12, 14}},
47+
{ref, {4, 5, 9, 10, 16, 15}},
48+
{ref, {8, 12, 13, 14}}}};
49+
int rank = comm.rank();
50+
};
51+
52+
using gko::experimental::mpi::DenseCommunicator;
53+
using gko::experimental::mpi::NeighborhoodCommunicator;
54+
using CommunicatorTypes = ::testing::Types<
55+
#if !GINKGO_HAVE_OPENMPI_PRE_4_1_X
56+
NeighborhoodCommunicator,
57+
#endif
58+
DenseCommunicator>;
59+
TYPED_TEST_SUITE(CollectiveCommunicator, CommunicatorTypes,
60+
TypenameNameGenerator);
61+
62+
63+
TYPED_TEST(CollectiveCommunicator, CanDefaultConstruct)
64+
{
65+
using communicator_type = typename TestFixture::communicator_type;
66+
communicator_type nhcomm{this->comm};
67+
68+
ASSERT_EQ(nhcomm.get_base_communicator(), this->comm);
69+
ASSERT_EQ(nhcomm.get_send_size(), 0);
70+
ASSERT_EQ(nhcomm.get_recv_size(), 0);
71+
}
72+
73+
74+
TYPED_TEST(CollectiveCommunicator, CanConstructFromIndexMap)
75+
{
76+
using communicator_type = typename TestFixture::communicator_type;
77+
using part_type = typename TestFixture::part_type;
78+
using map_type = typename TestFixture::map_type;
79+
auto part = gko::share(part_type::build_from_global_size_uniform(
80+
this->ref, this->comm.size(), this->comm.size() * 3));
81+
auto imap = map_type{this->ref, part, this->rank,
82+
this->recv_connections[this->rank]};
83+
84+
communicator_type spcomm{this->comm, imap};
85+
86+
std::array<gko::size_type, 6> send_sizes = {4, 6, 2, 4, 7, 3};
87+
ASSERT_EQ(spcomm.get_recv_size(),
88+
this->recv_connections[this->rank].get_size());
89+
ASSERT_EQ(spcomm.get_send_size(), send_sizes[this->rank]);
90+
}
91+
92+
93+
TYPED_TEST(CollectiveCommunicator, CanConstructFromEmptyIndexMap)
94+
{
95+
using communicator_type = typename TestFixture::communicator_type;
96+
using map_type = typename TestFixture::map_type;
97+
auto imap = map_type{this->ref};
98+
99+
communicator_type spcomm{this->comm, imap};
100+
101+
ASSERT_EQ(spcomm.get_recv_size(), 0);
102+
ASSERT_EQ(spcomm.get_send_size(), 0);
103+
}
104+
105+
106+
TYPED_TEST(CollectiveCommunicator, CanConstructFromIndexMapWithoutConnection)
107+
{
108+
using communicator_type = typename TestFixture::communicator_type;
109+
using part_type = typename TestFixture::part_type;
110+
using map_type = typename TestFixture::map_type;
111+
auto part = gko::share(part_type::build_from_global_size_uniform(
112+
this->ref, this->comm.size(), this->comm.size() * 3));
113+
auto imap = map_type{this->ref, part, this->rank, {this->ref, 0}};
114+
115+
communicator_type spcomm{this->comm, imap};
116+
117+
ASSERT_EQ(spcomm.get_recv_size(), 0);
118+
ASSERT_EQ(spcomm.get_send_size(), 0);
119+
}
120+
121+
122+
TYPED_TEST(CollectiveCommunicator, CanTestEquality)
123+
{
124+
auto comm_a = this->create_default_comm();
125+
auto comm_b = this->create_default_comm();
126+
127+
ASSERT_EQ(comm_a, comm_b);
128+
}
129+
130+
131+
TYPED_TEST(CollectiveCommunicator, CanTestInequality)
132+
{
133+
using communicator_type = typename TestFixture::communicator_type;
134+
auto comm_a = this->create_default_comm();
135+
auto comm_b = communicator_type(this->comm);
136+
137+
ASSERT_NE(comm_a, comm_b);
138+
}
139+
140+
141+
TYPED_TEST(CollectiveCommunicator, CanCopyConstruct)
142+
{
143+
auto spcomm = this->create_default_comm();
144+
145+
auto copy(spcomm);
146+
147+
ASSERT_EQ(copy, spcomm);
148+
}
149+
150+
151+
TYPED_TEST(CollectiveCommunicator, CanCopyAssign)
152+
{
153+
using communicator_type = typename TestFixture::communicator_type;
154+
auto spcomm = this->create_default_comm();
155+
communicator_type copy{this->comm};
156+
157+
copy = spcomm;
158+
159+
ASSERT_EQ(copy, spcomm);
160+
}
161+
162+
163+
TYPED_TEST(CollectiveCommunicator, CanMoveConstruct)
164+
{
165+
using communicator_type = typename TestFixture::communicator_type;
166+
auto spcomm = this->create_default_comm();
167+
auto moved_from = spcomm;
168+
auto empty_comm = communicator_type{MPI_COMM_NULL};
169+
170+
auto moved(std::move(moved_from));
171+
172+
ASSERT_EQ(moved, spcomm);
173+
ASSERT_EQ(moved_from, empty_comm);
174+
}
175+
176+
177+
TYPED_TEST(CollectiveCommunicator, CanMoveAssign)
178+
{
179+
using communicator_type = typename TestFixture::communicator_type;
180+
auto spcomm = this->create_default_comm();
181+
auto moved_from = spcomm;
182+
auto empty_comm = communicator_type{MPI_COMM_NULL};
183+
communicator_type moved{this->comm};
184+
185+
moved = std::move(moved_from);
186+
187+
ASSERT_EQ(moved, spcomm);
188+
ASSERT_EQ(moved_from, empty_comm);
189+
}
190+
191+
192+
TYPED_TEST(CollectiveCommunicator, CanCommunicateIalltoall)
193+
{
194+
auto spcomm = this->create_default_comm();
195+
gko::array<long> recv_buffer{this->ref,
196+
this->recv_connections[this->rank].get_size()};
197+
gko::array<long> send_buffers[] = {
198+
{this->ref, {0, 1, 1, 2}},
199+
{this->ref, {3, 5, 3, 4, 4, 5}},
200+
{this->ref, {7, 8}},
201+
{this->ref, {10, 11, 9, 10}},
202+
{this->ref, {12, 13, 12, 14, 12, 13, 14}},
203+
{this->ref, {17, 16, 15}}};
204+
205+
auto req = spcomm.i_all_to_all_v(this->ref,
206+
send_buffers[this->rank].get_const_data(),
207+
recv_buffer.get_data());
208+
req.wait();
209+
210+
GKO_ASSERT_ARRAY_EQ(recv_buffer, this->recv_connections[this->rank]);
211+
}
212+
213+
214+
TYPED_TEST(CollectiveCommunicator, CanCommunicateIalltoallWhenEmpty)
215+
{
216+
using communicator_type = typename TestFixture::communicator_type;
217+
communicator_type spcomm{this->comm};
218+
219+
auto req = spcomm.i_all_to_all_v(this->ref, static_cast<int*>(nullptr),
220+
static_cast<int*>(nullptr));
221+
222+
ASSERT_NO_THROW(req.wait());
223+
}
224+
225+
226+
TYPED_TEST(CollectiveCommunicator, CanCreateInverse)
227+
{
228+
auto spcomm = this->create_default_comm();
229+
230+
auto inverse = spcomm.create_inverse();
231+
232+
ASSERT_EQ(inverse->get_recv_size(), spcomm.get_send_size());
233+
ASSERT_EQ(inverse->get_send_size(), spcomm.get_recv_size());
234+
}
235+
236+
237+
TYPED_TEST(CollectiveCommunicator, CanCommunicateRoundTrip)
238+
{
239+
auto spcomm = this->create_default_comm();
240+
auto inverse = spcomm.create_inverse();
241+
gko::array<long> send_buffers[] = {
242+
{this->ref, {1, 2, 3, 4}},
243+
{this->ref, {5, 6, 7, 8, 9, 10}},
244+
{this->ref, {11, 12}},
245+
{this->ref, {13, 14, 15, 16}},
246+
{this->ref, {17, 18, 19, 20, 21, 22, 23}},
247+
{this->ref, {24, 25, 26}}};
248+
gko::array<long> recv_buffer{this->ref,
249+
this->recv_connections[this->rank].get_size()};
250+
gko::array<long> round_trip{this->ref, send_buffers[this->rank].get_size()};
251+
252+
spcomm
253+
.i_all_to_all_v(this->ref, send_buffers[this->rank].get_const_data(),
254+
recv_buffer.get_data())
255+
.wait();
256+
inverse
257+
->i_all_to_all_v(this->ref, recv_buffer.get_const_data(),
258+
round_trip.get_data())
259+
.wait();
260+
261+
GKO_ASSERT_ARRAY_EQ(send_buffers[this->rank], round_trip);
262+
}

0 commit comments

Comments
 (0)