]> https://gitweb.dealii.org/ - dealii.git/commitdiff
Utilities::Trilinos::duplicate_communicator.
authorWolfgang Bangerth <bangerth@math.tamu.edu>
Thu, 6 Aug 2009 16:03:27 +0000 (16:03 +0000)
committerWolfgang Bangerth <bangerth@math.tamu.edu>
Thu, 6 Aug 2009 16:03:27 +0000 (16:03 +0000)
git-svn-id: https://svn.dealii.org/trunk@19192 0785d39b-7218-0410-832d-ea1e28bc413d

deal.II/base/include/base/utilities.h
deal.II/base/source/utilities.cc
deal.II/doc/news/changes.h

index 72b2a63fff8e49d94eef98a27289f2931d377ae0..5a9476aaeda9441c73650f7c9b380ed0cf1db37e 100644 (file)
@@ -365,6 +365,63 @@ namespace Utilities
                                      */
     const Epetra_Comm& comm_world();
 
+                                    /**
+                                     * Given a communicator, duplicate it. If
+                                     * the given communicator is serial, that
+                                     * means to just return a copy of
+                                     * itself. On the other hand, if it is
+                                     * parallel, we duplicate the underlying
+                                     * MPI_Comm object: we create a separate
+                                     * MPI communicator that contains the
+                                     * same processors and in the same order
+                                     * but has a separate identifier distinct
+                                     * from the given communicator. The
+                                     * function returns a pointer to a new
+                                     * object of a class derived from
+                                     * Epetra_Comm. The caller of this
+                                     * function needs to assume ownership of
+                                     * this function.
+                                     *
+                                     * This facility is used to separate
+                                     * streams of communication. For example,
+                                     * a program could simply use
+                                     * MPI_Comm_World for everything. But it
+                                     * is easy to come up with scenarios
+                                     * where sometimes not all processors
+                                     * participate in a communication that is
+                                     * intended to be global -- for example
+                                     * if we assemble a matrix on a coarse
+                                     * mesh with fewer cells than there are
+                                     * processors, some processors may not
+                                     * sync their matrices with the rest
+                                     * because they haven't written into it
+                                     * because they own no cells. That's
+                                     * clearly a bug. However, if these
+                                     * processors just continue their work,
+                                     * and the next parallel operation
+                                     * happens to be a sync on a different
+                                     * matrix, then the sync could succeed --
+                                     * by accident, since different
+                                     * processors are talking about different
+                                     * matrices.
+                                     *
+                                     * This kind of situation can be avoided
+                                     * if we use different communicators for
+                                     * different matrices which reduces the
+                                     * likelihood that communications meant
+                                     * to be separate aren't recognized as
+                                     * such just because they happen on the
+                                     * same communicator. In addition, it is
+                                     * conceivable that some MPI operations
+                                     * can be parallelized using multiple
+                                     * threads because their communicators
+                                     * identifies the communication in
+                                     * question, not their relative timing as
+                                     * is the case in a sequential program
+                                     * that just uses a single communicator.
+                                     */
+    Epetra_Comm *
+    duplicate_communicator (const Epetra_Comm &communicator);
 
                                     /**
                                      * Return the number of MPI processes
index e7fd9fdf5b13ea9e33baa90488999d357052ccdb..7b791c0e2399007c3b441b2f47e22c08603ca01e 100644 (file)
 #  include <limits.h>
 #endif
 
+#ifdef DEAL_II_USE_TRILINOS
+#  ifdef DEAL_II_COMPILER_SUPPORTS_MPI
+#    include <Epetra_MpiComm.h>
+#  endif
+#  include "Epetra_SerialComm.h"
+#endif
+
+
+
 DEAL_II_NAMESPACE_OPEN
 
 
@@ -599,6 +608,32 @@ namespace Utilities
     }
 
 
+
+    Epetra_Comm *
+    duplicate_communicator (const Epetra_Comm &communicator)
+    {
+#ifdef DEAL_II_COMPILER_SUPPORTS_MPI
+
+                                      // see if the communicator is in fact a
+                                      // parallel MPI communicator; if so,
+                                      // return a duplicate of it
+      Epetra_MpiComm
+       *mpi_comm = dynamic_cast<const Epetra_MpiComm *>(&communicator);
+      if (mpi_comm != 0)
+       return new Epetra_MpiComm(duplicate_communicator(mpi_comm->GetMpiComm()));
+#endif
+
+                                      // if we don't support MPI, or if the
+                                      // communicator in question was in fact
+                                      // not an MPI communicator, return a
+                                      // copy of the same object again
+      Assert (dynamic_cast<const Epetra_SerialComm*>(&communicator)
+             != 0,
+             ExcInternalError());
+      return new Epetra_SerialComm(dynamic_cast<const Epetra_SerialComm&>(communicator));
+    }
+    
+
     unsigned int get_n_mpi_processes (const Epetra_Comm &mpi_communicator)
     {
       return mpi_communicator.NumProc();
index 9109f128dc98e069d9d83ac8fa6dae8726e26e89..6eafb7ac893a143cab66a7afee13bb3d1bae59d8 100644 (file)
@@ -157,6 +157,16 @@ inconvenience this causes.
 <h3>base</h3>
 
 <ol>
+  <li>
+  <p>
+  New: The Utilities::Trilinos::duplicate_communicator function allows to duplicate
+  an Epetra_Comm object to get a unique parallel MPI communicator out of an
+  existing one.
+  <br>
+  (WB 2009/08/06)
+  </p>
+  </li>
+
   <li>
   <p>
   New: There is now a specialization Tensor<0,dim> of tensors of rank 0. Since rank-0

In the beginning the Universe was created. This has made a lot of people very angry and has been widely regarded as a bad move.

Douglas Adams


Typeset in Trocchi and Trocchi Bold Sans Serif.