From b55a0b6d033f90a75dec5132e380e8c05404d9e4 Mon Sep 17 00:00:00 2001 From: Ankit Srivastava Date: Thu, 6 Feb 2020 15:15:18 -0500 Subject: [PATCH 1/2] Fix in global_scan and global_scan_inplace. Updating the elements on the first processor after exscan may lead to erroneous results. --- include/mxx/reduction.hpp | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/include/mxx/reduction.hpp b/include/mxx/reduction.hpp index a84b995..868f57a 100644 --- a/include/mxx/reduction.hpp +++ b/include/mxx/reduction.hpp @@ -741,14 +741,14 @@ void global_scan(InIterator begin, InIterator end, OutIterator out, Func func, c local_scan(begin, end, out, func); // mxx::scan typedef typename std::iterator_traits::value_type T; - T sum = T(); - if (n > 0) - sum = *(out+(n-1)); + T sum = *(out+(n-1)); T presum = exscan(sum, func, nonzero_comm, commutative); - // accumulate previous sum on all local elements - for (size_t i = 0; i < n; ++i) { - *o = func(presum, *o); - ++o; + if (nonzero_comm.rank() != 0) { + // accumulate previous sum on all local elements + for (size_t i = 0; i < n; ++i) { + *o = func(presum, *o); + ++o; + } } } } @@ -773,10 +773,12 @@ inline void global_scan_inplace(Iterator begin, Iterator end, Func func, const b T sum = *(begin + (n-1)); T presum = exscan(sum, func, nonzero_comm, commutative); - // accumulate previous sum on all local elements - for (size_t i = 0; i < n; ++i) { - *o = func(presum, *o); - ++o; + if (nonzero_comm.rank() != 0) { + // accumulate previous sum on all local elements + for (size_t i = 0; i < n; ++i) { + *o = func(presum, *o); + ++o; + } } } } From 9e184c55cff4c9ef6b2045a3d47a6404bb4a259d Mon Sep 17 00:00:00 2001 From: Ankit Srivastava Date: Tue, 3 Mar 2020 12:13:30 -0500 Subject: [PATCH 2/2] Added a test that was failing before the fix in b55a0b6d033f90a75dec5132e380e8c05404d9e4. --- test/test_reductions.cpp | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/test/test_reductions.cpp b/test/test_reductions.cpp index bf6d113..c395401 100644 --- a/test/test_reductions.cpp +++ b/test/test_reductions.cpp @@ -247,7 +247,7 @@ TEST(MxxReduce, GlobalReduce) { TEST(MxxReduce, GlobalScan) { mxx::comm c; - // test reduce with zero elements for some processes + // test scan with zero elements for some processes size_t n = 0; int presize = 0; if (c.rank() % 2 == 0) { @@ -273,6 +273,31 @@ TEST(MxxReduce, GlobalScan) { } } +TEST(MxxReduce, GlobalScanMin) { + mxx::comm c; + // test scan with min and an array of positive + // elements sorted in ascending order + size_t n = c.size(); + std::vector local(n); + for (size_t i = 0; i < n; ++i) { + local[i] = (c.rank()*n)+i+1; + } + // test inplace scan + std::vector local_cpy(local); + mxx::global_scan_inplace(local_cpy.begin(), local_cpy.end(), mxx::min(), c); + for (size_t i = 0; i < n; ++i) { + // 1 is both the first as well as the minimum element + ASSERT_EQ(1, local_cpy[i]); + } + // test scan + std::vector result = mxx::global_scan(local, mxx::min(), c); + ASSERT_EQ(local.size(), result.size()); + for (size_t i = 0; i < n; ++i) { + // 1 is both the first as well as the minimum element + ASSERT_EQ(1, result[i]); + } +} + TEST(MxxReduce, GlobalExScan) { mxx::comm c; // test reduce with zero elements for some processes