diff --git a/core/test/mpi/distributed/CMakeLists.txt b/core/test/mpi/distributed/CMakeLists.txt index ad6929ecdef..a943898653a 100644 --- a/core/test/mpi/distributed/CMakeLists.txt +++ b/core/test/mpi/distributed/CMakeLists.txt @@ -2,5 +2,8 @@ ginkgo_create_test(helpers MPI_SIZE 1) ginkgo_create_test(matrix MPI_SIZE 1) ginkgo_create_test(neighborhood_communicator MPI_SIZE 6) ginkgo_create_test(row_gatherer MPI_SIZE 6) +if (GINKGO_HAVE_CXX17) + ginkgo_create_test(sparse_communicator MPI_SIZE 6) +endif () add_subdirectory(preconditioner) diff --git a/core/test/mpi/distributed/sparse_communicator.cpp b/core/test/mpi/distributed/sparse_communicator.cpp new file mode 100644 index 00000000000..464f6d2c769 --- /dev/null +++ b/core/test/mpi/distributed/sparse_communicator.cpp @@ -0,0 +1,87 @@ +// SPDX-FileCopyrightText: 2017 - 2024 The Ginkgo authors +// +// SPDX-License-Identifier: BSD-3-Clause + +#include + + +#include +#include +#include + + +#include "core/test/utils/assertions.hpp" + + +class SparseCommunicator : public ::testing::Test { +protected: + using part_type = gko::experimental::distributed::Partition; + using map_type = gko::experimental::distributed::index_map; + using Dense = gko::matrix::Dense<>; + + void SetUp() + { + rank = comm.rank(); + ASSERT_EQ(comm.size(), 6); + + auto offset = static_cast(rank * 3); + buffer = gko::initialize({offset, offset + 1, offset + 2}, ref); + } + + std::shared_ptr ref = gko::ReferenceExecutor::create(); + gko::experimental::mpi::communicator comm = MPI_COMM_WORLD; + int rank = -1; + + // globally this is [0, ..., 17] + std::unique_ptr buffer; + gko::detail::DenseCache recv_buffer; + gko::detail::DenseCache send_buffer; +}; + +TEST_F(SparseCommunicator, CanDefaultConstruct) +{ + gko::experimental::distributed::sparse_communicator spcomm{}; + + auto empty = Dense::create(ref); + auto req = spcomm.communicate(empty.get(), send_buffer, recv_buffer); + req.wait(); + + ASSERT_EQ(send_buffer.get(), nullptr); + ASSERT_EQ(recv_buffer.get(), nullptr); +} + +TEST_F(SparseCommunicator, 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, 15, 16}}, + {ref, {8, 12, 13, 14}}}; + auto imap = map_type{ref, part, comm.rank(), recv_connections[comm.rank()]}; + + gko::experimental::distributed::sparse_communicator spcomm{comm, imap}; + + auto req = spcomm.communicate(buffer.get(), send_buffer, recv_buffer); + req.wait(); + ASSERT_NE(send_buffer.get(), nullptr); + ASSERT_NE(recv_buffer.get(), nullptr); + auto recv_size = recv_connections[rank].get_size(); + gko::size_type send_size[] = {4, 6, 2, 4, 7, 3}; + auto send_dim = gko::dim<2>{send_size[rank], 1}; + auto recv_dim = gko::dim<2>{recv_size, 1}; + GKO_ASSERT_EQUAL_DIMENSIONS(send_buffer.get(), send_dim); + GKO_ASSERT_EQUAL_DIMENSIONS(recv_buffer.get(), recv_dim); + // repeat recv_connections, since there is no conversion between long and + // double + gko::array values[] = {{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, 15, 16}}, + {ref, {8, 12, 13, 14}}}; + auto expected = Dense::create(ref, recv_dim, values[rank], 1); + GKO_ASSERT_MTX_NEAR(recv_buffer.get(), expected, 0.0); +}