From a739fca9ee5bc2ebd2deab410a90ed24024813d5 Mon Sep 17 00:00:00 2001 From: Jean-Paul Pelteret Date: Wed, 7 Mar 2018 17:54:25 +0100 Subject: [PATCH] Fix Vector::operator=(TrilinosWrappers::MPI::Vector) Data was being copied to the local vector directly from the distributed vector (as opposed to its localised equivalent). This lead to only a partial copy of data, and all of the data was offset incorrectly in the returned vector (giving each process a different view of the localised vector). --- .../changes/minor/20180307Jean-PaulPelteret | 7 ++ include/deal.II/lac/vector.templates.h | 28 ++++--- .../trilinos/parallel_block_vector_copy_01.cc | 75 +++++++++++++++++++ ...allel_block_vector_copy_01.mpirun=2.output | 47 ++++++++++++ 4 files changed, 148 insertions(+), 9 deletions(-) create mode 100644 doc/news/changes/minor/20180307Jean-PaulPelteret create mode 100644 tests/trilinos/parallel_block_vector_copy_01.cc create mode 100644 tests/trilinos/parallel_block_vector_copy_01.mpirun=2.output diff --git a/doc/news/changes/minor/20180307Jean-PaulPelteret b/doc/news/changes/minor/20180307Jean-PaulPelteret new file mode 100644 index 0000000000..804b36b9de --- /dev/null +++ b/doc/news/changes/minor/20180307Jean-PaulPelteret @@ -0,0 +1,7 @@ +Fixed: Copying a Trilinos::MPI::Vector to a local deal.II Vector using +operator=() resulted in only a partial copy of data to the local vector. In +addition, the copied elements were offset incorrectly on each process. +Similar held for copying a Trilinos::MPI::BlockVector to a local deal.II +BlockVector. This has been fixed and now works as expected. +
+(Jean-Paul Pelteret, 2018/03/07) diff --git a/include/deal.II/lac/vector.templates.h b/include/deal.II/lac/vector.templates.h index 393817135f..ebb917a35e 100644 --- a/include/deal.II/lac/vector.templates.h +++ b/include/deal.II/lac/vector.templates.h @@ -180,6 +180,9 @@ Vector::Vector (const TrilinosWrappers::MPI::Vector &v) localized_vector.reinit(complete_index_set(vec_size), v.get_mpi_communicator()); localized_vector.reinit (v, false, true); + Assert(localized_vector.size() == vec_size, + ExcDimensionMismatch(localized_vector.size(), vec_size)); + // get a representation of the vector // and copy it TrilinosScalar **start_ptr; @@ -825,22 +828,29 @@ template Vector & Vector::operator= (const TrilinosWrappers::MPI::Vector &v) { - // Generate a localized version - // of the Trilinos vectors and - // then call the other = - // operator. - TrilinosWrappers::MPI::Vector localized_vector; - localized_vector.reinit(complete_index_set(v.size()), v.get_mpi_communicator()); - localized_vector.reinit(v, false, true); - if (v.size() != vec_size) reinit (v.size(), true); if (vec_size != 0) { + // Copy the distributed vector to + // a local one at all processors + // that know about the original vector. + // TODO: There could + // be a better solution than + // this, but it has not yet been + // found. + TrilinosWrappers::MPI::Vector localized_vector; + localized_vector.reinit(complete_index_set(vec_size), v.get_mpi_communicator()); + localized_vector.reinit (v, false, true); + + Assert(localized_vector.size() == vec_size, + ExcDimensionMismatch(localized_vector.size(), vec_size)); + // get a representation of the vector // and copy it TrilinosScalar **start_ptr; - int ierr = v.trilinos_vector().ExtractView (&start_ptr); + + int ierr = localized_vector.trilinos_vector().ExtractView (&start_ptr); AssertThrow (ierr == 0, ExcTrilinosError(ierr)); std::copy (start_ptr[0], start_ptr[0]+vec_size, begin()); diff --git a/tests/trilinos/parallel_block_vector_copy_01.cc b/tests/trilinos/parallel_block_vector_copy_01.cc new file mode 100644 index 0000000000..f61401ceba --- /dev/null +++ b/tests/trilinos/parallel_block_vector_copy_01.cc @@ -0,0 +1,75 @@ +// --------------------------------------------------------------------- +// +// 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 at +// the top level of the deal.II distribution. +// +// --------------------------------------------------------------------- + + + +// make sure that block vector copies correctly to a serial vector + +#include "../tests.h" +#include +#include +#include +#include + + +int main (int argc,char **argv) +{ + typedef BlockVector BlockVectorLocal; + typedef TrilinosWrappers::MPI::BlockVector BlockVector; + + Utilities::MPI::MPI_InitFinalize mpi_initialization (argc, argv, 1); + MPILogInitAll log; + + const MPI_Comm &mpi_communicator = MPI_COMM_WORLD; + const unsigned int this_mpi_process = Utilities::MPI::this_mpi_process(mpi_communicator); + const unsigned int n_mpi_processes = Utilities::MPI::n_mpi_processes(mpi_communicator); + + const unsigned int n_blocks = 2; + const unsigned int n_dofs_per_block = 10; + + std::vector locally_owned_partitioning (n_blocks); + for (unsigned int b=0; b