[Openmp-commits] [PATCH] D98838: [OpenMP] Fixed a crash in hidden helper thread

Shilei Tian via Phabricator via Openmp-commits openmp-commits at lists.llvm.org
Wed Mar 17 19:07:23 PDT 2021


tianshilei1992 created this revision.
tianshilei1992 added reviewers: ronlieb, protze.joachim, lebedev.ri, JonChesterfield, jdoerfert.
Herald added subscribers: guansong, yaxunl.
tianshilei1992 requested review of this revision.
Herald added subscribers: openmp-commits, sstefan1.
Herald added a project: OpenMP.

It is reported that after enabling hidden helper thread, the program
can hit the assertion `new_gtid < __kmp_threads_capacity` sometimes. The root
cause is explained as follows. Let's say the default `__kmp_threads_capacity` is
`N`. If hidden helper thread is enabled, `__kmp_threads_capacity` will be offset
to `N+8` by default. If the number of threads we need exceeds `N+8`, e.g. via
`num_threads` clause, we need to expand `__kmp_threads`. In
`__kmp_expand_threads`, the expansion starts from `__kmp_threads_capacity`, and
repeatedly doubling it until the new capacity meets the requirement. Let's
assume the new requirement is `Y`.  If `Y` happens to meet the constraint
`(N+8)*2^X=Y` where `X` is the number of iterations, the new capacity is not
enough because we have 8 slots for hidden helper threads.

Here is an example.

  #include <vector>
  
  int main(int argc, char *argv[]) {
    constexpr const size_t N = 1344;
    std::vector<int> data(N);
  
  #pragma omp parallel for
    for (unsigned i = 0; i < N; ++i) {
      data[i] = i;
    }
  
  #pragma omp parallel for num_threads(N)
    for (unsigned i = 0; i < N; ++i) {
      data[i] += i;
    }
  
    return 0;
  }

My CPU is 20C40T, then `__kmp_threads_capacity` is 160. After offset,
`__kmp_threads_capacity` becomes 168. `1344 = (160+8)*2^3`, then the assertions
hit.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D98838

Files:
  openmp/runtime/src/kmp_runtime.cpp
  openmp/runtime/src/kmp_settings.cpp
  openmp/runtime/test/tasking/hidden_helper_task/num_threads.cpp


Index: openmp/runtime/test/tasking/hidden_helper_task/num_threads.cpp
===================================================================
--- /dev/null
+++ openmp/runtime/test/tasking/hidden_helper_task/num_threads.cpp
@@ -0,0 +1,35 @@
+// RUN: %libomp-cxx-compile-and-run
+
+#include <omp.h>
+
+#include <algorithm>
+#include <cassert>
+#include <vector>
+
+int main(int argc, char *argv[]) {
+  constexpr const int __kmp_hidden_helper_threads_num = 8;
+  const int __kmp_threads_capacity =
+      std::min(std::max(std::max(32, 4 * omp_get_num_threads()),
+                        4 * omp_get_num_procs()),
+               std::numeric_limits<int>::max());
+  const int capacity = __kmp_threads_capacity + __kmp_hidden_helper_threads_num;
+  const int N = 2 * capacity;
+
+  std::vector<int> data(N);
+
+#pragma omp parallel for
+  for (unsigned i = 0; i < N; ++i) {
+    data[i] = i;
+  }
+
+#pragma omp parallel for num_threads(N)
+  for (unsigned i = 0; i < N; ++i) {
+    data[i] += i;
+  }
+
+  for (unsigned i = 0; i < N; ++i) {
+    assert(data[i] == 2 * i);
+  }
+
+  return 0;
+}
Index: openmp/runtime/src/kmp_settings.cpp
===================================================================
--- openmp/runtime/src/kmp_settings.cpp
+++ openmp/runtime/src/kmp_settings.cpp
@@ -504,9 +504,10 @@
     nth = (4 * __kmp_xproc);
 
   // If hidden helper task is enabled, we initialize the thread capacity with
-  // extra
-  // __kmp_hidden_helper_threads_num.
-  nth += __kmp_hidden_helper_threads_num;
+  // extra __kmp_hidden_helper_threads_num.
+  if (__kmp_enable_hidden_helper) {
+    nth += __kmp_hidden_helper_threads_num;
+  }
 
   if (nth > __kmp_max_nth)
     nth = __kmp_max_nth;
Index: openmp/runtime/src/kmp_runtime.cpp
===================================================================
--- openmp/runtime/src/kmp_runtime.cpp
+++ openmp/runtime/src/kmp_runtime.cpp
@@ -3547,6 +3547,10 @@
     newCapacity = newCapacity <= (__kmp_sys_max_nth >> 1) ? (newCapacity << 1)
                                                           : __kmp_sys_max_nth;
   } while (newCapacity < minimumRequiredCapacity);
+  // If hidden helper thread is enabled, we also need to count the number
+  if (__kmp_enable_hidden_helper) {
+    newCapacity += __kmp_hidden_helper_threads_num;
+  }
   newThreads = (kmp_info_t **)__kmp_allocate(
       (sizeof(kmp_info_t *) + sizeof(kmp_root_t *)) * newCapacity + CACHE_LINE);
   newRoot =


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D98838.331440.patch
Type: text/x-patch
Size: 2431 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/openmp-commits/attachments/20210318/87b63d8d/attachment.bin>


More information about the Openmp-commits mailing list