From 58a20bb767287f557c8279c5f201a9ed45fae46b Mon Sep 17 00:00:00 2001
From: Stephane Del Pino <stephane.delpino44@gmail.com>
Date: Thu, 4 Oct 2018 19:07:56 +0200
Subject: [PATCH] Add Sum of array values and rename Reduce{Min,Max} to
 {Min,Max}

Sum should only work for scalar types (requires init to 0) and should be worked
properly to ensure reproducible results for floating point values
---
 src/scheme/AcousticSolver.hpp |  2 +-
 src/utils/ArrayUtils.hpp      | 60 +++++++++++++++++++++++++++++++----
 tests/test_ArrayUtils.cpp     | 10 +++---
 3 files changed, 60 insertions(+), 12 deletions(-)

diff --git a/src/scheme/AcousticSolver.hpp b/src/scheme/AcousticSolver.hpp
index 07ae8902d..d8aace57d 100644
--- a/src/scheme/AcousticSolver.hpp
+++ b/src/scheme/AcousticSolver.hpp
@@ -268,7 +268,7 @@ class AcousticSolver
         m_Vj_over_cj[j] = 2*Vj[j]/(S*cj[j]);
       });
 
-    return ReduceMin(m_Vj_over_cj);
+    return Min(m_Vj_over_cj);
   }
 
   void computeNextStep(const double& t, const double& dt,
diff --git a/src/utils/ArrayUtils.hpp b/src/utils/ArrayUtils.hpp
index b64452d99..734f0692b 100644
--- a/src/utils/ArrayUtils.hpp
+++ b/src/utils/ArrayUtils.hpp
@@ -5,7 +5,7 @@
 #include <PastisUtils.hpp>
 
 template <typename ArrayType>
-class ReduceMin
+class Min
 {
  private:
   const ArrayType& m_array;
@@ -45,19 +45,19 @@ class ReduceMin
   }
 
   PASTIS_INLINE
-  ReduceMin(const ArrayType& array)
+  Min(const ArrayType& array)
       : m_array(array)
   {
     ;
   }
 
   PASTIS_INLINE
-  ~ReduceMin() = default;
+  ~Min() = default;
 };
 
 
 template <typename ArrayType>
-class ReduceMax
+class Max
 {
  private:
   const ArrayType& m_array;
@@ -97,14 +97,62 @@ class ReduceMax
   }
 
   PASTIS_INLINE
-  ReduceMax(const ArrayType& array)
+  Max(const ArrayType& array)
       : m_array(array)
   {
     ;
   }
 
   PASTIS_INLINE
-  ~ReduceMax() = default;
+  ~Max() = default;
+};
+
+
+template <typename DataType>
+class Sum
+{
+ private:
+  using data_type = DataType;
+  const Array<data_type>& m_array;
+  using index_type = typename Array<DataType>::index_type;
+
+ public:
+  PASTIS_INLINE
+  operator data_type()
+  {
+    data_type reduced_value;
+    parallel_reduce(m_array.size(), *this, reduced_value);
+    return reduced_value;
+  }
+
+  PASTIS_INLINE
+  void operator()(const index_type& i, data_type& data) const
+  {
+    data += m_array[i];
+  }
+
+  PASTIS_INLINE
+  void join(volatile data_type& dst,
+            const volatile data_type& src) const
+  {
+    dst += src;
+  }
+
+  PASTIS_INLINE
+  void init(data_type& value) const
+  {
+    value = 0;
+  }
+
+  PASTIS_INLINE
+  Sum(const Array<DataType>& array)
+      : m_array(array)
+  {
+    ;
+  }
+
+  PASTIS_INLINE
+  ~Sum() = default;
 };
 
 #endif //ARRAY_UTILS_HPP
diff --git a/tests/test_ArrayUtils.cpp b/tests/test_ArrayUtils.cpp
index 8183e7157..80ead5291 100644
--- a/tests/test_ArrayUtils.cpp
+++ b/tests/test_ArrayUtils.cpp
@@ -25,8 +25,8 @@ TEST_CASE("ArrayUtils", "[utils]") {
     a[8] =12;
     a[9] = 9;
 
-    SECTION("ReduceMin") {
-      ReduceMin r_min(a);
+    SECTION("Min") {
+      Min r_min(a);
       data_type data;
 
       r_min.init(data);
@@ -57,11 +57,11 @@ TEST_CASE("ArrayUtils", "[utils]") {
 
       REQUIRE((r_min == -3));
 
-      REQUIRE((ReduceMin(a) == -3));
+      REQUIRE((Min(a) == -3));
     }
 
     SECTION("ReduceMax") {
-      ReduceMax r_max(a);
+      Max r_max(a);
       data_type data;
 
       r_max.init(data);
@@ -90,7 +90,7 @@ TEST_CASE("ArrayUtils", "[utils]") {
 
       REQUIRE((r_max == 23));
 
-      REQUIRE((ReduceMax(a) == 23));
+      REQUIRE((Max(a) == 23));
     }
   }
 }
-- 
GitLab