From 4d1aa408b7dbf909abc9d9f133d224dfbdeb2deb Mon Sep 17 00:00:00 2001 From: Bruno Turcksin Date: Wed, 22 Aug 2018 20:49:03 +0000 Subject: [PATCH] Add test for mmult using Trilinos matrices in parallel --- source/lac/trilinos_sparse_matrix.cc | 9 +- tests/epetraext/CMakeLists.txt | 6 + .../sparse_matrix_mmult_01.cc | 0 ...rix_mmult_01.with_64bit_indices=off.output | 0 tests/epetraext/sparse_matrix_mmult_02.cc | 160 ++++++++++++++++++ .../sparse_matrix_mmult_02.mpirun=2.output | 2 + 6 files changed, 175 insertions(+), 2 deletions(-) create mode 100644 tests/epetraext/CMakeLists.txt rename tests/{trilinos => epetraext}/sparse_matrix_mmult_01.cc (100%) rename tests/{trilinos => epetraext}/sparse_matrix_mmult_01.with_64bit_indices=off.output (100%) create mode 100644 tests/epetraext/sparse_matrix_mmult_02.cc create mode 100644 tests/epetraext/sparse_matrix_mmult_02.mpirun=2.output diff --git a/source/lac/trilinos_sparse_matrix.cc b/source/lac/trilinos_sparse_matrix.cc index 83c9f397ba..a28803efad 100644 --- a/source/lac/trilinos_sparse_matrix.cc +++ b/source/lac/trilinos_sparse_matrix.cc @@ -31,7 +31,9 @@ # include -# include +# ifdef DEAL_II_TRILINOS_WITH_EPETRAEXT +# include +# endif # include # include # include @@ -2307,13 +2309,16 @@ namespace TrilinosWrappers inputright.locally_owned_domain_indices(), inputleft.get_mpi_communicator()); - +# ifdef DEAL_II_TRILINOS_WITH_EPETRAEXT EpetraExt::MatrixMatrix::Multiply(inputleft.trilinos_matrix(), transpose_left, *mod_B, false, const_cast( tmp_result.trilinos_matrix())); +# else + Assert("false", ExcMessage("This function requires EpetraExt.")); +# endif result.reinit(tmp_result.trilinos_matrix()); } } // namespace internals diff --git a/tests/epetraext/CMakeLists.txt b/tests/epetraext/CMakeLists.txt new file mode 100644 index 0000000000..e5c0c1c03e --- /dev/null +++ b/tests/epetraext/CMakeLists.txt @@ -0,0 +1,6 @@ +CMAKE_MINIMUM_REQUIRED(VERSION 2.8.12) +INCLUDE(../setup_testsubproject.cmake) +PROJECT(testsuite CXX) +IF(DEAL_II_WITH_TRILINOS AND DEAL_II_TRILINOS_WITH_EPETRAEXT) + DEAL_II_PICKUP_TESTS() +ENDIF() diff --git a/tests/trilinos/sparse_matrix_mmult_01.cc b/tests/epetraext/sparse_matrix_mmult_01.cc similarity index 100% rename from tests/trilinos/sparse_matrix_mmult_01.cc rename to tests/epetraext/sparse_matrix_mmult_01.cc diff --git a/tests/trilinos/sparse_matrix_mmult_01.with_64bit_indices=off.output b/tests/epetraext/sparse_matrix_mmult_01.with_64bit_indices=off.output similarity index 100% rename from tests/trilinos/sparse_matrix_mmult_01.with_64bit_indices=off.output rename to tests/epetraext/sparse_matrix_mmult_01.with_64bit_indices=off.output diff --git a/tests/epetraext/sparse_matrix_mmult_02.cc b/tests/epetraext/sparse_matrix_mmult_02.cc new file mode 100644 index 0000000000..8cc0291387 --- /dev/null +++ b/tests/epetraext/sparse_matrix_mmult_02.cc @@ -0,0 +1,160 @@ +// --------------------------------------------------------------------- +// +// Copyright (C) 2018 by the deal.II authors +// +// This file is part of the deal.II library. +// +// The deal.II library is free software; you can use it, redistribute +// it, and/or modify it under the terms of the GNU Lesser General +// Public License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// The full text of the license can be found in the file LICENSE.md at +// the top level directory of deal.II. +// +// --------------------------------------------------------------------- + + + +// check TrilinosWrappers::SparseMatrix::mmult in parallel + +#include +#include + +#include + +#include +#include + +#include "../tests.h" + +using namespace dealii; + +void +value_rank_0(TrilinosWrappers::SparseMatrix &a) +{ + a.set(0, 0, 0); + a.set(0, 2, 2); + a.set(0, 15, 15); + a.set(1, 4, 5); + a.set(1, 9, 10); + a.set(1, 10, 11); + a.set(2, 0, 2); + a.set(2, 13, 30); + a.set(3, 7, 10); + a.set(3, 10, 13); + a.set(3, 18, 21); + a.set(4, 0, 4); + a.set(4, 1, 5); + a.set(4, 16, 20); + a.set(5, 0, 5); + a.set(5, 10, 15); + a.set(5, 13, 18); + a.set(6, 1, 7); + a.set(6, 7, 13); + a.set(6, 8, 14); + a.set(7, 13, 20); + a.set(7, 18, 25); + a.set(7, 11, 18); + a.set(8, 1, 9); + a.set(8, 10, 18); + a.set(8, 16, 24); + a.set(9, 8, 17); + a.set(9, 13, 22); + a.set(9, 14, 23); +} + +void +value_rank_1(TrilinosWrappers::SparseMatrix &a) +{ + a.set(10, 15, 25); + a.set(10, 0, 10); + a.set(10, 2, 12); + a.set(11, 10, 21); + a.set(11, 9, 20); + a.set(11, 4, 15); + a.set(12, 13, 50); + a.set(12, 0, 12); + a.set(13, 10, 23); + a.set(13, 18, 31); + a.set(13, 7, 20); + a.set(14, 16, 30); + a.set(14, 0, 14); + a.set(14, 1, 15); + a.set(15, 10, 25); + a.set(15, 13, 28); + a.set(15, 0, 15); + a.set(16, 7, 23); + a.set(16, 1, 17); + a.set(16, 8, 24); + a.set(17, 11, 28); + a.set(17, 13, 30); + a.set(17, 18, 35); + a.set(18, 10, 28); + a.set(18, 16, 34); + a.set(18, 1, 19); + a.set(19, 13, 32); + a.set(19, 14, 33); + a.set(19, 8, 27); +} + +void +test() +{ + const unsigned int my_rank = Utilities::MPI::this_mpi_process(MPI_COMM_WORLD); + const unsigned int n_procs = Utilities::MPI::n_mpi_processes(MPI_COMM_WORLD); + + const unsigned int n_local_rows = 10; + const unsigned int n_entries_per_row = 3; + const unsigned int size = n_local_rows * n_procs; + + // Compare the result of a*b in parallel with a*b in serial + IndexSet partitioning(size); + const unsigned int local_offset(n_local_rows * my_rank); + partitioning.add_range(local_offset, local_offset + n_local_rows); + partitioning.compress(); + TrilinosWrappers::SparseMatrix a(partitioning); + TrilinosWrappers::SparseMatrix b(partitioning); + if (my_rank == 0) + { + value_rank_0(a); + } + if (my_rank == 1) + { + value_rank_1(a); + } + a.compress(VectorOperation::insert); + b.copy_from(a); + TrilinosWrappers::SparseMatrix c; + a.mmult(c, b); + + + TrilinosWrappers::SparseMatrix serial_a(size, size, n_entries_per_row); + TrilinosWrappers::SparseMatrix serial_b(size, size, n_entries_per_row); + value_rank_0(serial_a); + value_rank_1(serial_a); + serial_a.compress(VectorOperation::insert); + serial_b.copy_from(serial_a); + TrilinosWrappers::SparseMatrix serial_c; + serial_a.mmult(serial_c, serial_b); + + AssertThrow(serial_c.n_nonzero_elements() == c.n_nonzero_elements(), + ExcInternalError()); + AssertThrow(serial_c.l1_norm() == c.l1_norm(), ExcInternalError()); + AssertThrow(serial_c.linfty_norm() == c.linfty_norm(), ExcInternalError()); + AssertThrow(serial_c.frobenius_norm() == c.frobenius_norm(), + ExcInternalError()); + + if (my_rank == 0) + deallog << "OK" << std::endl; +} + + +int +main(int argc, char *argv[]) +{ + Utilities::MPI::MPI_InitFinalize mpi(argc, argv, 1); + + initlog(); + + test(); +} diff --git a/tests/epetraext/sparse_matrix_mmult_02.mpirun=2.output b/tests/epetraext/sparse_matrix_mmult_02.mpirun=2.output new file mode 100644 index 0000000000..0fd8fc12f0 --- /dev/null +++ b/tests/epetraext/sparse_matrix_mmult_02.mpirun=2.output @@ -0,0 +1,2 @@ + +DEAL::OK -- 2.39.5