From 6d548e62ccadd7ac7fb26da4547da964165123e5 Mon Sep 17 00:00:00 2001 From: Marcel Koch Date: Thu, 19 Dec 2024 14:57:14 +0100 Subject: [PATCH] [coll-comm] review updates: - merge tests Co-authored-by: Yu-Hsiang M. Tsai --- core/test/mpi/distributed/CMakeLists.txt | 6 +- .../distributed/collective_communicator.cpp | 285 ++++++++++++++++++ .../mpi/distributed/dense_communicator.cpp | 243 --------------- .../distributed/neighborhood_communicator.cpp | 244 --------------- 4 files changed, 286 insertions(+), 492 deletions(-) create mode 100644 core/test/mpi/distributed/collective_communicator.cpp delete mode 100644 core/test/mpi/distributed/dense_communicator.cpp delete mode 100644 core/test/mpi/distributed/neighborhood_communicator.cpp diff --git a/core/test/mpi/distributed/CMakeLists.txt b/core/test/mpi/distributed/CMakeLists.txt index f788c4b3bc4..1bd06262cf0 100644 --- a/core/test/mpi/distributed/CMakeLists.txt +++ b/core/test/mpi/distributed/CMakeLists.txt @@ -1,11 +1,7 @@ ginkgo_create_test(helpers MPI_SIZE 1) ginkgo_create_test(matrix MPI_SIZE 1) -ginkgo_create_test(dense_communicator MPI_SIZE 6) +ginkgo_create_test(collective_communicator MPI_SIZE 6) ginkgo_create_test(vector_cache MPI_SIZE 3) -if(NOT GINKGO_HAVE_OPENMPI_PRE_4_1_X) - ginkgo_create_test(neighborhood_communicator MPI_SIZE 6) -endif() - add_subdirectory(preconditioner) add_subdirectory(solver) diff --git a/core/test/mpi/distributed/collective_communicator.cpp b/core/test/mpi/distributed/collective_communicator.cpp new file mode 100644 index 00000000000..7bba4efafa3 --- /dev/null +++ b/core/test/mpi/distributed/collective_communicator.cpp @@ -0,0 +1,285 @@ +// SPDX-FileCopyrightText: 2017 - 2024 The Ginkgo authors +// +// SPDX-License-Identifier: BSD-3-Clause + +#include + +#include + +#include +#include + +#include "core/test/utils/assertions.hpp" + +using gko::experimental::mpi::comm_index_type; + +template +class CollectiveCommunicator : public ::testing::Test { +protected: + using communicator_type = CommunicatorType; + using part_type = gko::experimental::distributed::Partition; + using map_type = gko::experimental::distributed::index_map; + + void SetUp() override { ASSERT_EQ(comm.size(), 6); } + + communicator_type create_default_comm() + { + auto part = gko::share(part_type::build_from_global_size_uniform( + ref, comm.size(), comm.size() * 3)); + gko::array recv_connections[] = {{ref, {3, 5, 10, 11}}, + {ref, {0, 1, 7, 12, 13}}, + {ref, {3, 4, 17}}, + {ref, {1, 2, 12, 14}}, + {ref, {4, 5, 9, 10, 16, 15}}, + {ref, {8, 12, 13, 14}}}; + auto imap = map_type{ref, part, comm.rank(), recv_connections[rank]}; + + return {comm, imap}; + } + + std::shared_ptr ref = gko::ReferenceExecutor::create(); + gko::experimental::mpi::communicator comm = MPI_COMM_WORLD; + int rank = comm.rank(); +}; + +using gko::experimental::mpi::DenseCommunicator; +using gko::experimental::mpi::NeighborhoodCommunicator; +using CommunicatorTypes = ::testing::Types< +#if !GINKGO_HAVE_OPENMPI_PRE_4_1_X + NeighborhoodCommunicator, +#endif + DenseCommunicator>; +TYPED_TEST_SUITE(CollectiveCommunicator, CommunicatorTypes, + TypenameNameGenerator); + + +TYPED_TEST(CollectiveCommunicator, CanDefaultConstruct) +{ + using communicator_type = typename TestFixture::communicator_type; + communicator_type nhcomm{this->comm}; + + ASSERT_EQ(nhcomm.get_base_communicator(), this->comm); + ASSERT_EQ(nhcomm.get_send_size(), 0); + ASSERT_EQ(nhcomm.get_recv_size(), 0); +} + + +TYPED_TEST(CollectiveCommunicator, CanConstructFromIndexMap) +{ + using communicator_type = typename TestFixture::communicator_type; + using part_type = typename TestFixture::part_type; + using map_type = typename TestFixture::map_type; + auto part = gko::share(part_type::build_from_global_size_uniform( + this->ref, this->comm.size(), this->comm.size() * 3)); + gko::array recv_connections[] = {{this->ref, {3, 5, 10, 11}}, + {this->ref, {0, 1, 7, 12, 13}}, + {this->ref, {3, 4, 17}}, + {this->ref, {1, 2, 12, 14}}, + {this->ref, {4, 5, 9, 10, 16, 15}}, + {this->ref, {8, 12, 13, 14}}}; + auto imap = + map_type{this->ref, part, this->rank, recv_connections[this->rank]}; + + communicator_type spcomm{this->comm, imap}; + + std::array send_sizes = {4, 6, 2, 4, 7, 3}; + ASSERT_EQ(spcomm.get_recv_size(), recv_connections[this->rank].get_size()); + ASSERT_EQ(spcomm.get_send_size(), send_sizes[this->rank]); +} + + +TYPED_TEST(CollectiveCommunicator, CanConstructFromEmptyIndexMap) +{ + using communicator_type = typename TestFixture::communicator_type; + using map_type = typename TestFixture::map_type; + auto imap = map_type{this->ref}; + + communicator_type spcomm{this->comm, imap}; + + ASSERT_EQ(spcomm.get_recv_size(), 0); + ASSERT_EQ(spcomm.get_send_size(), 0); +} + + +TYPED_TEST(CollectiveCommunicator, CanConstructFromIndexMapWithoutConnection) +{ + using communicator_type = typename TestFixture::communicator_type; + using part_type = typename TestFixture::part_type; + using map_type = typename TestFixture::map_type; + auto part = gko::share(part_type::build_from_global_size_uniform( + this->ref, this->comm.size(), this->comm.size() * 3)); + auto imap = map_type{this->ref, part, this->rank, {this->ref, 0}}; + + communicator_type spcomm{this->comm, imap}; + + ASSERT_EQ(spcomm.get_recv_size(), 0); + ASSERT_EQ(spcomm.get_send_size(), 0); +} + + +TYPED_TEST(CollectiveCommunicator, CanTestEquality) +{ + auto comm_a = this->create_default_comm(); + auto comm_b = this->create_default_comm(); + + ASSERT_EQ(comm_a, comm_b); +} + + +TYPED_TEST(CollectiveCommunicator, CanTestInequality) +{ + using communicator_type = typename TestFixture::communicator_type; + auto comm_a = this->create_default_comm(); + auto comm_b = communicator_type(this->comm); + + ASSERT_NE(comm_a, comm_b); +} + + +TYPED_TEST(CollectiveCommunicator, CanCopyConstruct) +{ + auto spcomm = this->create_default_comm(); + + auto copy(spcomm); + + ASSERT_TRUE(copy == spcomm); +} + + +TYPED_TEST(CollectiveCommunicator, CanCopyAssign) +{ + using communicator_type = typename TestFixture::communicator_type; + auto spcomm = this->create_default_comm(); + communicator_type copy{this->comm}; + + copy = spcomm; + + ASSERT_TRUE(copy == spcomm); +} + + +TYPED_TEST(CollectiveCommunicator, CanMoveConstruct) +{ + using communicator_type = typename TestFixture::communicator_type; + auto spcomm = this->create_default_comm(); + auto moved_from = spcomm; + auto empty_comm = communicator_type{MPI_COMM_NULL}; + + auto moved(std::move(moved_from)); + + ASSERT_TRUE(moved == spcomm); + ASSERT_TRUE(moved_from == empty_comm); +} + + +TYPED_TEST(CollectiveCommunicator, CanMoveAssign) +{ + using communicator_type = typename TestFixture::communicator_type; + auto spcomm = this->create_default_comm(); + auto moved_from = spcomm; + auto empty_comm = communicator_type{MPI_COMM_NULL}; + communicator_type moved{this->comm}; + + moved = std::move(moved_from); + + ASSERT_TRUE(moved == spcomm); + ASSERT_TRUE(moved_from == empty_comm); +} + + +TYPED_TEST(CollectiveCommunicator, CanCommunicateIalltoall) +{ + using communicator_type = typename TestFixture::communicator_type; + using part_type = typename TestFixture::part_type; + using map_type = typename TestFixture::map_type; + auto part = gko::share(part_type::build_from_global_size_uniform( + this->ref, this->comm.size(), this->comm.size() * 3)); + gko::array recv_connections[] = {{this->ref, {3, 5, 10, 11}}, + {this->ref, {0, 1, 7, 12, 13}}, + {this->ref, {3, 4, 17}}, + {this->ref, {1, 2, 12, 14}}, + {this->ref, {4, 5, 9, 10, 16, 15}}, + {this->ref, {8, 12, 13, 14}}}; + auto imap = + map_type{this->ref, part, this->rank, recv_connections[this->rank]}; + communicator_type spcomm{this->comm, imap}; + gko::array recv_buffer{this->ref, + recv_connections[this->rank].get_size()}; + gko::array send_buffers[] = { + {this->ref, {0, 1, 1, 2}}, + {this->ref, {3, 5, 3, 4, 4, 5}}, + {this->ref, {7, 8}}, + {this->ref, {10, 11, 9, 10}}, + {this->ref, {12, 13, 12, 14, 12, 13, 14}}, + {this->ref, {17, 16, 15}}}; + + auto req = spcomm.i_all_to_all_v(this->ref, + send_buffers[this->rank].get_const_data(), + recv_buffer.get_data()); + req.wait(); + + GKO_ASSERT_ARRAY_EQ(recv_buffer, recv_connections[this->rank]); +} + + +TYPED_TEST(CollectiveCommunicator, CanCommunicateIalltoallWhenEmpty) +{ + using communicator_type = typename TestFixture::communicator_type; + communicator_type spcomm{this->comm}; + + auto req = spcomm.i_all_to_all_v(this->ref, static_cast(nullptr), + static_cast(nullptr)); + req.wait(); +} + + +TYPED_TEST(CollectiveCommunicator, CanCreateInverse) +{ + auto spcomm = this->create_default_comm(); + + auto inverse = spcomm.create_inverse(); + + ASSERT_EQ(inverse->get_recv_size(), spcomm.get_send_size()); + ASSERT_EQ(inverse->get_send_size(), spcomm.get_recv_size()); +} + + +TYPED_TEST(CollectiveCommunicator, CanCommunicateRoundTrip) +{ + using communicator_type = typename TestFixture::communicator_type; + using part_type = typename TestFixture::part_type; + using map_type = typename TestFixture::map_type; + auto part = gko::share(part_type::build_from_global_size_uniform( + this->ref, this->comm.size(), this->comm.size() * 3)); + gko::array recv_connections[] = {{this->ref, {3, 5, 10, 11}}, + {this->ref, {0, 1, 7, 12, 13}}, + {this->ref, {3, 4, 17}}, + {this->ref, {1, 2, 12, 14}}, + {this->ref, {4, 5, 9, 10, 16, 15}}, + {this->ref, {8, 12, 13, 14}}}; + auto imap = + map_type{this->ref, part, this->rank, recv_connections[this->rank]}; + communicator_type spcomm{this->comm, imap}; + auto inverse = spcomm.create_inverse(); + gko::array send_buffers[] = { + {this->ref, {1, 2, 3, 4}}, + {this->ref, {5, 6, 7, 8, 9, 10}}, + {this->ref, {11, 12}}, + {this->ref, {13, 14, 15, 16}}, + {this->ref, {17, 18, 19, 20, 21, 22, 23}}, + {this->ref, {24, 25, 26}}}; + gko::array recv_buffer{this->ref, + recv_connections[this->rank].get_size()}; + gko::array round_trip{this->ref, send_buffers[this->rank].get_size()}; + + spcomm + .i_all_to_all_v(this->ref, send_buffers[this->rank].get_const_data(), + recv_buffer.get_data()) + .wait(); + inverse + ->i_all_to_all_v(this->ref, recv_buffer.get_const_data(), + round_trip.get_data()) + .wait(); + + GKO_ASSERT_ARRAY_EQ(send_buffers[this->rank], round_trip); +} diff --git a/core/test/mpi/distributed/dense_communicator.cpp b/core/test/mpi/distributed/dense_communicator.cpp deleted file mode 100644 index c273814cd04..00000000000 --- a/core/test/mpi/distributed/dense_communicator.cpp +++ /dev/null @@ -1,243 +0,0 @@ -// SPDX-FileCopyrightText: 2017 - 2024 The Ginkgo authors -// -// SPDX-License-Identifier: BSD-3-Clause - -#include - -#include - -#include "core/test/utils/assertions.hpp" - -using gko::experimental::mpi::comm_index_type; - -class DenseCommunicator : public ::testing::Test { -protected: - using part_type = gko::experimental::distributed::Partition; - using map_type = gko::experimental::distributed::index_map; - - void SetUp() override { ASSERT_EQ(comm.size(), 6); } - - gko::experimental::mpi::DenseCommunicator create_default_comm() - { - auto part = gko::share(part_type::build_from_global_size_uniform( - ref, comm.size(), comm.size() * 3)); - gko::array recv_connections[] = {{ref, {3, 5, 10, 11}}, - {ref, {0, 1, 7, 12, 13}}, - {ref, {3, 4, 17}}, - {ref, {1, 2, 12, 14}}, - {ref, {4, 5, 9, 10, 16, 15}}, - {ref, {8, 12, 13, 14}}}; - auto imap = map_type{ref, part, comm.rank(), recv_connections[rank]}; - - - return {comm, imap}; - } - - std::shared_ptr ref = gko::ReferenceExecutor::create(); - gko::experimental::mpi::communicator comm = MPI_COMM_WORLD; - int rank = comm.rank(); -}; - - -TEST_F(DenseCommunicator, CanDefaultConstruct) -{ - gko::experimental::mpi::DenseCommunicator dcomm{comm}; - - ASSERT_EQ(dcomm.get_base_communicator(), comm); - ASSERT_EQ(dcomm.get_send_size(), 0); - ASSERT_EQ(dcomm.get_recv_size(), 0); -} - - -TEST_F(DenseCommunicator, CanConstructFromIndexMap) -{ - auto part = gko::share(part_type::build_from_global_size_uniform( - ref, comm.size(), comm.size() * 3)); - gko::array recv_connections[] = {{ref, {3, 5, 10, 11}}, - {ref, {0, 1, 7, 12, 13}}, - {ref, {3, 4, 17}}, - {ref, {1, 2, 12, 14}}, - {ref, {4, 5, 9, 10, 16, 15}}, - {ref, {8, 12, 13, 14}}}; - auto imap = map_type{ref, part, comm.rank(), recv_connections[rank]}; - - gko::experimental::mpi::DenseCommunicator dcomm{comm, imap}; - - std::array send_sizes = {4, 6, 2, 4, 7, 3}; - ASSERT_EQ(dcomm.get_recv_size(), recv_connections[rank].get_size()); - ASSERT_EQ(dcomm.get_send_size(), send_sizes[rank]); -} - - -TEST_F(DenseCommunicator, CanConstructFromEmptyIndexMap) -{ - auto imap = map_type{ref}; - - gko::experimental::mpi::DenseCommunicator dcomm{comm, imap}; - - ASSERT_EQ(dcomm.get_recv_size(), 0); - ASSERT_EQ(dcomm.get_send_size(), 0); -} - - -TEST_F(DenseCommunicator, CanConstructFromIndexMapWithoutConnection) -{ - auto part = gko::share(part_type::build_from_global_size_uniform( - ref, comm.size(), comm.size() * 3)); - auto imap = map_type{ref, part, comm.rank(), {ref, 0}}; - - gko::experimental::mpi::DenseCommunicator dcomm{comm, imap}; - - ASSERT_EQ(dcomm.get_recv_size(), 0); - ASSERT_EQ(dcomm.get_send_size(), 0); -} - - -TEST_F(DenseCommunicator, CanTestEquality) -{ - auto comm_a = create_default_comm(); - auto comm_b = create_default_comm(); - - ASSERT_EQ(comm_a, comm_b); -} - - -TEST_F(DenseCommunicator, CanTestInequality) -{ - auto comm_a = create_default_comm(); - auto comm_b = gko::experimental::mpi::DenseCommunicator(comm); - - ASSERT_NE(comm_a, comm_b); -} - - -TEST_F(DenseCommunicator, CanCopyConstruct) -{ - auto dcomm = create_default_comm(); - - auto copy(dcomm); - - ASSERT_TRUE(copy == dcomm); -} - - -TEST_F(DenseCommunicator, CanCopyAssign) -{ - auto dcomm = create_default_comm(); - gko::experimental::mpi::DenseCommunicator copy{comm}; - - copy = dcomm; - - ASSERT_TRUE(copy == dcomm); -} - - -TEST_F(DenseCommunicator, CanMoveConstruct) -{ - auto dcomm = create_default_comm(); - auto moved_from = dcomm; - auto empty_comm = gko::experimental::mpi::DenseCommunicator{MPI_COMM_NULL}; - - auto moved(std::move(moved_from)); - - ASSERT_TRUE(moved == dcomm); - ASSERT_TRUE(moved_from == empty_comm); -} - - -TEST_F(DenseCommunicator, CanMoveAssign) -{ - auto dcomm = create_default_comm(); - auto moved_from = dcomm; - auto empty_comm = gko::experimental::mpi::DenseCommunicator{MPI_COMM_NULL}; - gko::experimental::mpi::DenseCommunicator moved{comm}; - - moved = std::move(moved_from); - - ASSERT_TRUE(moved == dcomm); - ASSERT_TRUE(moved_from == empty_comm); -} - - -TEST_F(DenseCommunicator, CanCommunicateIalltoall) -{ - auto part = gko::share(part_type::build_from_global_size_uniform( - ref, comm.size(), comm.size() * 3)); - gko::array recv_connections[] = {{ref, {3, 5, 10, 11}}, - {ref, {0, 1, 7, 12, 13}}, - {ref, {3, 4, 17}}, - {ref, {1, 2, 12, 14}}, - {ref, {4, 5, 9, 10, 16, 15}}, - {ref, {8, 12, 13, 14}}}; - auto imap = map_type{ref, part, comm.rank(), recv_connections[rank]}; - gko::experimental::mpi::DenseCommunicator dcomm{comm, imap}; - gko::array recv_buffer{ref, recv_connections[rank].get_size()}; - gko::array send_buffers[] = {{ref, {0, 1, 1, 2}}, - {ref, {3, 5, 3, 4, 4, 5}}, - {ref, {7, 8}}, - {ref, {10, 11, 9, 10}}, - {ref, {12, 13, 12, 14, 12, 13, 14}}, - {ref, {17, 16, 15}}}; - - auto req = dcomm.i_all_to_all_v(ref, send_buffers[rank].get_const_data(), - recv_buffer.get_data()); - req.wait(); - - GKO_ASSERT_ARRAY_EQ(recv_buffer, recv_connections[rank]); -} - - -TEST_F(DenseCommunicator, CanCommunicateIalltoallWhenEmpty) -{ - gko::experimental::mpi::DenseCommunicator dcomm{comm}; - - auto req = dcomm.i_all_to_all_v(ref, static_cast(nullptr), - static_cast(nullptr)); - req.wait(); -} - - -TEST_F(DenseCommunicator, CanCreateInverse) -{ - auto dcomm = create_default_comm(); - - auto inverse = dcomm.create_inverse(); - - ASSERT_EQ(inverse->get_recv_size(), dcomm.get_send_size()); - ASSERT_EQ(inverse->get_send_size(), dcomm.get_recv_size()); -} - - -TEST_F(DenseCommunicator, CanCommunicateRoundTrip) -{ - auto part = gko::share(part_type::build_from_global_size_uniform( - ref, comm.size(), comm.size() * 3)); - gko::array recv_connections[] = {{ref, {3, 5, 10, 11}}, - {ref, {0, 1, 7, 12, 13}}, - {ref, {3, 4, 17}}, - {ref, {1, 2, 12, 14}}, - {ref, {4, 5, 9, 10, 16, 15}}, - {ref, {8, 12, 13, 14}}}; - auto imap = map_type{ref, part, comm.rank(), recv_connections[rank]}; - gko::experimental::mpi::DenseCommunicator dcomm{comm, imap}; - auto inverse = dcomm.create_inverse(); - gko::array send_buffers[] = {{ref, {1, 2, 3, 4}}, - {ref, {5, 6, 7, 8, 9, 10}}, - {ref, {11, 12}}, - {ref, {13, 14, 15, 16}}, - {ref, {17, 18, 19, 20, 21, 22, 23}}, - {ref, {24, 25, 26}}}; - gko::array recv_buffer{ref, recv_connections[rank].get_size()}; - gko::array round_trip{ref, send_buffers[rank].get_size()}; - - dcomm - .i_all_to_all_v(ref, send_buffers[rank].get_const_data(), - recv_buffer.get_data()) - .wait(); - inverse - ->i_all_to_all_v(ref, recv_buffer.get_const_data(), - round_trip.get_data()) - .wait(); - - GKO_ASSERT_ARRAY_EQ(send_buffers[rank], round_trip); -} diff --git a/core/test/mpi/distributed/neighborhood_communicator.cpp b/core/test/mpi/distributed/neighborhood_communicator.cpp deleted file mode 100644 index 11afd9f083b..00000000000 --- a/core/test/mpi/distributed/neighborhood_communicator.cpp +++ /dev/null @@ -1,244 +0,0 @@ -// SPDX-FileCopyrightText: 2017 - 2024 The Ginkgo authors -// -// SPDX-License-Identifier: BSD-3-Clause - -#include - -#include - -#include "core/test/utils/assertions.hpp" - -using gko::experimental::mpi::comm_index_type; - -class NeighborhoodCommunicator : public ::testing::Test { -protected: - using part_type = gko::experimental::distributed::Partition; - using map_type = gko::experimental::distributed::index_map; - - void SetUp() override { ASSERT_EQ(comm.size(), 6); } - - gko::experimental::mpi::NeighborhoodCommunicator create_default_comm() - { - auto part = gko::share(part_type::build_from_global_size_uniform( - ref, comm.size(), comm.size() * 3)); - gko::array recv_connections[] = {{ref, {3, 5, 10, 11}}, - {ref, {0, 1, 7, 12, 13}}, - {ref, {3, 4, 17}}, - {ref, {1, 2, 12, 14}}, - {ref, {4, 5, 9, 10, 16, 15}}, - {ref, {8, 12, 13, 14}}}; - auto imap = map_type{ref, part, comm.rank(), recv_connections[rank]}; - - return {comm, imap}; - } - - std::shared_ptr ref = gko::ReferenceExecutor::create(); - gko::experimental::mpi::communicator comm = MPI_COMM_WORLD; - int rank = comm.rank(); -}; - - -TEST_F(NeighborhoodCommunicator, CanDefaultConstruct) -{ - gko::experimental::mpi::NeighborhoodCommunicator nhcomm{comm}; - - ASSERT_EQ(nhcomm.get_base_communicator(), comm); - ASSERT_EQ(nhcomm.get_send_size(), 0); - ASSERT_EQ(nhcomm.get_recv_size(), 0); -} - - -TEST_F(NeighborhoodCommunicator, CanConstructFromIndexMap) -{ - auto part = gko::share(part_type::build_from_global_size_uniform( - ref, comm.size(), comm.size() * 3)); - gko::array recv_connections[] = {{ref, {3, 5, 10, 11}}, - {ref, {0, 1, 7, 12, 13}}, - {ref, {3, 4, 17}}, - {ref, {1, 2, 12, 14}}, - {ref, {4, 5, 9, 10, 16, 15}}, - {ref, {8, 12, 13, 14}}}; - auto imap = map_type{ref, part, comm.rank(), recv_connections[rank]}; - - gko::experimental::mpi::NeighborhoodCommunicator spcomm{comm, imap}; - - std::array send_sizes = {4, 6, 2, 4, 7, 3}; - ASSERT_EQ(spcomm.get_recv_size(), recv_connections[rank].get_size()); - ASSERT_EQ(spcomm.get_send_size(), send_sizes[rank]); -} - - -TEST_F(NeighborhoodCommunicator, CanConstructFromEmptyIndexMap) -{ - auto imap = map_type{ref}; - - gko::experimental::mpi::NeighborhoodCommunicator spcomm{comm, imap}; - - ASSERT_EQ(spcomm.get_recv_size(), 0); - ASSERT_EQ(spcomm.get_send_size(), 0); -} - - -TEST_F(NeighborhoodCommunicator, CanConstructFromIndexMapWithoutConnection) -{ - auto part = gko::share(part_type::build_from_global_size_uniform( - ref, comm.size(), comm.size() * 3)); - auto imap = map_type{ref, part, comm.rank(), {ref, 0}}; - - gko::experimental::mpi::NeighborhoodCommunicator spcomm{comm, imap}; - - ASSERT_EQ(spcomm.get_recv_size(), 0); - ASSERT_EQ(spcomm.get_send_size(), 0); -} - - -TEST_F(NeighborhoodCommunicator, CanTestEquality) -{ - auto comm_a = create_default_comm(); - auto comm_b = create_default_comm(); - - ASSERT_EQ(comm_a, comm_b); -} - - -TEST_F(NeighborhoodCommunicator, CanTestInequality) -{ - auto comm_a = create_default_comm(); - auto comm_b = gko::experimental::mpi::NeighborhoodCommunicator(comm); - - ASSERT_NE(comm_a, comm_b); -} - - -TEST_F(NeighborhoodCommunicator, CanCopyConstruct) -{ - auto spcomm = create_default_comm(); - - auto copy(spcomm); - - ASSERT_TRUE(copy == spcomm); -} - - -TEST_F(NeighborhoodCommunicator, CanCopyAssign) -{ - auto spcomm = create_default_comm(); - gko::experimental::mpi::NeighborhoodCommunicator copy{comm}; - - copy = spcomm; - - ASSERT_TRUE(copy == spcomm); -} - - -TEST_F(NeighborhoodCommunicator, CanMoveConstruct) -{ - auto spcomm = create_default_comm(); - auto moved_from = spcomm; - auto empty_comm = - gko::experimental::mpi::NeighborhoodCommunicator{MPI_COMM_NULL}; - - auto moved(std::move(moved_from)); - - ASSERT_TRUE(moved == spcomm); - ASSERT_TRUE(moved_from == empty_comm); -} - - -TEST_F(NeighborhoodCommunicator, CanMoveAssign) -{ - auto spcomm = create_default_comm(); - auto moved_from = spcomm; - auto empty_comm = - gko::experimental::mpi::NeighborhoodCommunicator{MPI_COMM_NULL}; - gko::experimental::mpi::NeighborhoodCommunicator moved{comm}; - - moved = std::move(moved_from); - - ASSERT_TRUE(moved == spcomm); - ASSERT_TRUE(moved_from == empty_comm); -} - - -TEST_F(NeighborhoodCommunicator, CanCommunicateIalltoall) -{ - auto part = gko::share(part_type::build_from_global_size_uniform( - ref, comm.size(), comm.size() * 3)); - gko::array recv_connections[] = {{ref, {3, 5, 10, 11}}, - {ref, {0, 1, 7, 12, 13}}, - {ref, {3, 4, 17}}, - {ref, {1, 2, 12, 14}}, - {ref, {4, 5, 9, 10, 16, 15}}, - {ref, {8, 12, 13, 14}}}; - auto imap = map_type{ref, part, comm.rank(), recv_connections[rank]}; - gko::experimental::mpi::NeighborhoodCommunicator spcomm{comm, imap}; - gko::array recv_buffer{ref, recv_connections[rank].get_size()}; - gko::array send_buffers[] = {{ref, {0, 1, 1, 2}}, - {ref, {3, 5, 3, 4, 4, 5}}, - {ref, {7, 8}}, - {ref, {10, 11, 9, 10}}, - {ref, {12, 13, 12, 14, 12, 13, 14}}, - {ref, {17, 16, 15}}}; - - auto req = spcomm.i_all_to_all_v(ref, send_buffers[rank].get_const_data(), - recv_buffer.get_data()); - req.wait(); - - GKO_ASSERT_ARRAY_EQ(recv_buffer, recv_connections[rank]); -} - - -TEST_F(NeighborhoodCommunicator, CanCommunicateIalltoallWhenEmpty) -{ - gko::experimental::mpi::NeighborhoodCommunicator spcomm{comm}; - - auto req = spcomm.i_all_to_all_v(ref, static_cast(nullptr), - static_cast(nullptr)); - req.wait(); -} - - -TEST_F(NeighborhoodCommunicator, CanCreateInverse) -{ - auto spcomm = create_default_comm(); - - auto inverse = spcomm.create_inverse(); - - ASSERT_EQ(inverse->get_recv_size(), spcomm.get_send_size()); - ASSERT_EQ(inverse->get_send_size(), spcomm.get_recv_size()); -} - - -TEST_F(NeighborhoodCommunicator, CanCommunicateRoundTrip) -{ - auto part = gko::share(part_type::build_from_global_size_uniform( - ref, comm.size(), comm.size() * 3)); - gko::array recv_connections[] = {{ref, {3, 5, 10, 11}}, - {ref, {0, 1, 7, 12, 13}}, - {ref, {3, 4, 17}}, - {ref, {1, 2, 12, 14}}, - {ref, {4, 5, 9, 10, 16, 15}}, - {ref, {8, 12, 13, 14}}}; - auto imap = map_type{ref, part, comm.rank(), recv_connections[rank]}; - gko::experimental::mpi::NeighborhoodCommunicator spcomm{comm, imap}; - auto inverse = spcomm.create_inverse(); - gko::array send_buffers[] = {{ref, {1, 2, 3, 4}}, - {ref, {5, 6, 7, 8, 9, 10}}, - {ref, {11, 12}}, - {ref, {13, 14, 15, 16}}, - {ref, {17, 18, 19, 20, 21, 22, 23}}, - {ref, {24, 25, 26}}}; - gko::array recv_buffer{ref, recv_connections[rank].get_size()}; - gko::array round_trip{ref, send_buffers[rank].get_size()}; - - spcomm - .i_all_to_all_v(ref, send_buffers[rank].get_const_data(), - recv_buffer.get_data()) - .wait(); - inverse - ->i_all_to_all_v(ref, recv_buffer.get_const_data(), - round_trip.get_data()) - .wait(); - - GKO_ASSERT_ARRAY_EQ(send_buffers[rank], round_trip); -}