From b601b80e22a2739db2a7b31fbec97ab5effd69ab Mon Sep 17 00:00:00 2001
From: Ross Miller <rgmiller@ornl.gov>
Date: Fri, 10 Jun 2016 14:59:53 -0400
Subject: [PATCH] Sort out issues with different versions of boost::mpi::reduce

Prior to v1.55 of Boost, boost::mpi::reduce() would treat a
std::vector<T> as a single object.  In v1.55, some overloads of reduce()
were added that recognize std::vector<T> a collection of T elements.

The practical upshot is that for Boost < 1.55, the operator function you
pass in to reduce() should accept std::vector<T>, while in 1.55 and later
it must simply accept T.  This is explained in more detail here:
http://stackoverflow.com/questions/28845847/custom-reduce-operation-in-boost-mpi

This change adds a #define to check the Boost version and define function
objects that accept the correct parameters.

Refs #16539
---
 .../MPIAlgorithms/src/GatherWorkspaces.cpp    | 41 ++++++++++++++-----
 1 file changed, 31 insertions(+), 10 deletions(-)

diff --git a/Framework/MPIAlgorithms/src/GatherWorkspaces.cpp b/Framework/MPIAlgorithms/src/GatherWorkspaces.cpp
index 3ef32d2209e..fc35ef9a156 100644
--- a/Framework/MPIAlgorithms/src/GatherWorkspaces.cpp
+++ b/Framework/MPIAlgorithms/src/GatherWorkspaces.cpp
@@ -21,7 +21,34 @@ using namespace DataObjects;
 
 // Anonymous namespace for locally-used functors
 namespace {
-/// Sum for boostmpi MantidVec
+
+/// Functor used for computing the sum of the square values of a vector
+// Used by the eplus templates below
+template <class T> struct SumGaussError : public std::binary_function<T, T, T> {
+  SumGaussError() {}
+  /// Sums the arguments in quadrature
+  inline T operator()(const T &l, const T &r) const {
+    return std::sqrt(l * l + r * r);
+  }
+};
+
+
+// Newer versions of boost::mpi::reduce (>=v1.55) will recognize std::vector
+// as a collection of individual elements and operate on a per-element
+// basis.  Older versions treat vectors as a single object.  Thus we need
+// two different versions of the sum operators that we pass into reduce().
+// This is explained in more detail at:
+// http://stackoverflow.com/questions/28845847/custom-reduce-operation-in-boost-mpi
+#if (BOOST_VERSION / 100 % 1000) >= 55 // is the boost version >= 1.55?
+
+struct vplus : public std::plus<double> { };
+
+struct eplus : public SumGaussError<double> { };
+        
+#else // older version of Boost that passes the entire MantidVec
+      // the operator
+
+/// Sum for boostmpi MantidVec 
 struct vplus : public std::binary_function<MantidVec, MantidVec,
                                            MantidVec> { // functor for operator+
   MantidVec
@@ -34,15 +61,6 @@ struct vplus : public std::binary_function<MantidVec, MantidVec,
   }
 };
 
-/// Functor used for computing the sum of the square values of a vector
-template <class T> struct SumGaussError : public std::binary_function<T, T, T> {
-  SumGaussError() {}
-  /// Sums the arguments in quadrature
-  inline T operator()(const T &l, const T &r) const {
-    return std::sqrt(l * l + r * r);
-  }
-};
-
 /// Sum for error for boostmpi MantidVec
 struct eplus : public std::binary_function<MantidVec, MantidVec,
                                            MantidVec> { // functor for operator+
@@ -55,6 +73,9 @@ struct eplus : public std::binary_function<MantidVec, MantidVec,
     return (v);
   }
 };
+
+#endif // boost version
+
 }
 
 // Register the algorithm into the AlgorithmFactory
-- 
GitLab