From 3f3e21039071b64385bed541437999ed949284e2 Mon Sep 17 00:00:00 2001
From: Martin Nolte <mnolte@dune-project.org>
Date: Sun, 26 Aug 2012 17:25:26 +0000
Subject: [PATCH] implement scan and partualSum (MPI_SCAN)

[[Imported from SVN: r6929]]
---
 .../parallel/collectivecommunication.hh       | 41 ++++++++++++++++---
 .../parallel/mpicollectivecommunication.hh    | 17 ++++++++
 2 files changed, 53 insertions(+), 5 deletions(-)

diff --git a/dune/common/parallel/collectivecommunication.hh b/dune/common/parallel/collectivecommunication.hh
index 8c819b9ce..48f74d9a0 100644
--- a/dune/common/parallel/collectivecommunication.hh
+++ b/dune/common/parallel/collectivecommunication.hh
@@ -252,20 +252,51 @@ namespace Dune
      * in every process.
      *
      * The template parameter BinaryFunction is the type of
-     * the binary function to use for the computation
+     * the binary function to use for the computation.
      *
      * @param in The array to compute on.
      * @param out The array to store the results in.
      * @param len The number of components in the array
      */
     template<typename BinaryFunction, typename Type>
-    void allreduce(Type* in, Type* out, int len) const
+    int allreduce(Type* in, Type* out, int len) const
     {
       std::copy(in, in+len, out);
-      return;
+      return 0;
     }
 
+    /** \brief perform a partial reduction of processes 0, ..., rank
+     *
+     *  The template parameter BinaryFunction gives the type of the reduction.
+     *
+     *  Note: scan and allreduce are very similar. The only difference is that
+     *        scan only returns the reduction of the arguments over processes
+     *        0, ..., rank instead of over all processes.
+     *
+     *  \param[in]   in   array of input arguments
+     *  \param[out]  out  array to store the output in
+     *  \param[in]   len  number of elements in each array
+     */
+    template< class BinaryFunction, class T >
+    int scan ( T *in, T *out, int len ) const
+    {
+      std::copy( in, in+len, out );
+      return 0;
+    }
+
+    /** \brief compute the sum of the argument over processes 0, ..., rank
+     *
+     *  Note: This function assumes that type T has an operator+
+     *
+     * \param[in]  in  argument for this process
+     */
+    template< class T >
+    T partialSum ( T &in ) const
+    {
+      return in;
+    }
   };
-}
 
-#endif
+} // namespace Dune
+
+#endif // #ifndef DUNE_COLLECTIVECOMMUNICATION_HH
diff --git a/dune/common/parallel/mpicollectivecommunication.hh b/dune/common/parallel/mpicollectivecommunication.hh
index c94796cb1..fc8d278f7 100644
--- a/dune/common/parallel/mpicollectivecommunication.hh
+++ b/dune/common/parallel/mpicollectivecommunication.hh
@@ -295,6 +295,23 @@ namespace Dune
                            (Generic_MPI_Op<Type, BinaryFunction>::get()),communicator);
     }
 
+    /** \copydoc CollectiveCommunication::scan(T *in,T *out,int len) const */
+    template< class BinaryFunction, class T >
+    int scan ( T *in, T *out, int len ) const
+    {
+      return MPI_Scan( in, out, len, MPITraits< T >::getType(),
+                       (Generic_MPI_Op< T, BinaryFunction >::get()), communicator );
+    }
+
+    /** \copydoc CollectiveCommunication::partialSum(T &in) const */
+    template< class T >
+    T partialSum ( T &in ) const
+    {
+      T out;
+      scan< std::plus< T > >( &in, &out, 1 );
+      return out;
+    }
+
   private:
     MPI_Comm communicator;
     int me;
-- 
GitLab