From 2ac776dddf689d3e3859e9e31b6d96c9bcc51ae4 Mon Sep 17 00:00:00 2001
From: Neil Vaytet <neil.vaytet@esss.se>
Date: Wed, 15 Aug 2018 14:30:33 +0200
Subject: [PATCH] Refs #20443 : replaced openmp static schedule with manual
 loop count

---
 Framework/Kernel/inc/MantidKernel/Strings.h | 15 ++++++++++++---
 Framework/Kernel/test/StringsTest.h         | 21 ++++++++++++++++++++-
 2 files changed, 32 insertions(+), 4 deletions(-)

diff --git a/Framework/Kernel/inc/MantidKernel/Strings.h b/Framework/Kernel/inc/MantidKernel/Strings.h
index 3f6dc001031..c80d89facdf 100644
--- a/Framework/Kernel/inc/MantidKernel/Strings.h
+++ b/Framework/Kernel/inc/MantidKernel/Strings.h
@@ -164,9 +164,18 @@ join(ITERATOR_TYPE begin, ITERATOR_TYPE end, const std::string &separator,
 
       // Initialise ostringstream
       std::ostringstream thread_stream;
-#pragma omp for schedule(static)
-      for (int i = 0; i < dist; i++) {
-        // Write to ostringstream
+
+      // Compute loop start and stop for current thread
+      int nchunk = dist / nThreads;
+      int nstart = nchunk * idThread;
+      int nextra = dist % nchunk;
+      if (idThread < nextra)
+        nchunk++;
+      nstart += std::min(idThread % nThreads, nextra);
+      int nstop = nstart + nchunk;
+
+      // Write to ostringstream for this thread
+      for (int i = nstart; i < nstop; i++) {
         thread_stream << separator << *(begin + i);
       }
       output[idThread] = thread_stream.str();
diff --git a/Framework/Kernel/test/StringsTest.h b/Framework/Kernel/test/StringsTest.h
index 8f4fb76e9af..e65782ae72e 100644
--- a/Framework/Kernel/test/StringsTest.h
+++ b/Framework/Kernel/test/StringsTest.h
@@ -286,6 +286,25 @@ public:
     TS_ASSERT_EQUALS(out, "A,Help,I'm,Inside,Me,Stuck,Test");
   }
 
+  void test_joinLong() {
+    std::vector<std::string> v;
+    std::string out;
+    std::string ans;
+
+    out = join(v.begin(), v.end(), ",");
+    TS_ASSERT_EQUALS(out, "");
+
+    int n = 100000;
+    for (int i = 0; i < n; i++) {
+      v.emplace_back(std::to_string(i));
+      ans += std::to_string(i) + ",";
+    }
+
+    out = join(v.begin(), v.end(), ",");
+    ans.pop_back();
+    TS_ASSERT_EQUALS(out, ans);
+  }
+
   void test_joinCompress() {
 
     std::vector<std::vector<int>> inputList{
@@ -615,7 +634,7 @@ public:
     return new StringsTestPerformance();
   }
   static void destroySuite(StringsTestPerformance *suite) { delete suite; }
-  void setUp() override { input = std::vector<double>(10000000, 0.123456); }
+  void setUp() override { input = std::vector<double>(50000000, 0.123456); }
   void test_join_double() {
     auto result = join(input.begin(), input.end(), separator);
   }
-- 
GitLab