[Openmp-commits] [openmp] [OpenMP] Corrects the setting of the Static_Steal schedule with `omp_set_schedule` (PR #227236)

Samuel Newcome via Openmp-commits openmp-commits at lists.llvm.org
Fri Oct 2 03:07:06 PDT 2026


https://github.com/SamNewcome updated https://github.com/llvm/llvm-project/pull/227236

>From ee669523a1b2395197fd449285da9ad8b8a59db7 Mon Sep 17 00:00:00 2001
From: Samuel Newcome <samuel.newcome at tum.de>
Date: Fri, 25 Sep 2026 14:34:45 +0200
Subject: [PATCH 1/2] Adding a test that checks that every schedule kind
 accepted as valid can actually be set, and can then be gotten. Fails
 currently with static_steal

---
 .../test/worksharing/for/kmp_sched_set_get.c  | 81 +++++++++++++++++++
 1 file changed, 81 insertions(+)
 create mode 100644 openmp/runtime/test/worksharing/for/kmp_sched_set_get.c

diff --git a/openmp/runtime/test/worksharing/for/kmp_sched_set_get.c b/openmp/runtime/test/worksharing/for/kmp_sched_set_get.c
new file mode 100644
index 0000000000000..f1f1ae3102243
--- /dev/null
+++ b/openmp/runtime/test/worksharing/for/kmp_sched_set_get.c
@@ -0,0 +1,81 @@
+// RUN: %libomp-compile-and-run
+
+// The test checks that every schedule kind accepted by omp_set_schedule(),
+// i.e. that is not considered out of range in __kmp_set_schedule in
+// kmp_runtime.cpp, can be set, and we can afterwards get the schedule back with
+// omp_get_schedule
+
+#include <omp.h>
+#include <stdio.h>
+
+// ---------------------------------------------------------------------------
+// As with kmp.h, static steal is by default enabled, but can be manually
+// disabled. If libomp is built with -DKMP_STATIC_STEAL_ENABLED=0, pass the
+// same flag to the tests (for example through OPENMP_TEST_FLAGS).
+#ifndef KMP_STATIC_STEAL_ENABLED
+#define KMP_STATIC_STEAL_ENABLED 1
+#endif
+
+// These definitions need to match kmp_sched_t in kmp.h.
+#ifndef KMP_SCHED_TYPE_DEFINED
+#define KMP_SCHED_TYPE_DEFINED
+typedef enum kmp_sched {
+  kmp_sched_lower = 0,
+  kmp_sched_static = 1,
+  kmp_sched_dynamic = 2,
+  kmp_sched_guided = 3,
+  kmp_sched_auto = 4,
+  kmp_sched_upper_std = 5,
+  kmp_sched_lower_ext = 100,
+  kmp_sched_trapezoidal = 101,
+#if KMP_STATIC_STEAL_ENABLED
+  kmp_sched_static_steal = 102,
+#endif
+  kmp_sched_upper,
+  kmp_sched_default = kmp_sched_static,
+  kmp_sched_monotonic = 0x80000000
+} kmp_sched_t;
+#endif
+
+// ---------------------------------------------------------------------------
+
+int main() {
+  const int chunk = 5;
+  int err = 0;
+  unsigned k;
+
+  // Visit every kind that __kmp_set_schedule() accepts: the standard kinds
+  // between lower and upper_std, and the extension kinds between lower_ext
+  // and upper.
+  for (k = kmp_sched_lower + 1; k < kmp_sched_upper; ++k) {
+    omp_sched_t kind_get;
+    int chunk_get;
+
+    if (k >= kmp_sched_upper_std && k <= kmp_sched_lower_ext) {
+      continue;
+    }
+
+#ifdef DEBUG
+    printf("checking kind %u\n", k);
+#endif
+
+    omp_set_schedule((omp_sched_t)k, chunk);
+    omp_get_schedule(&kind_get, &chunk_get);
+
+    // Check kind and chunk match.
+    // The chunk size is ignored for auto, so allow a mismatched chunk size.
+    if (kind_get != (omp_sched_t)k ||
+        (k != kmp_sched_auto && chunk_get != chunk)) {
+      printf("Error: kind %u: schedule: (%d, %d) is not equal to (%u, %d)\n", k,
+             (int)kind_get, chunk_get, k, chunk);
+      ++err;
+    }
+  }
+
+  if (err > 0) {
+    printf("Failed\n");
+    return 1;
+  }
+  printf("Passed\n");
+  return 0;
+}

>From 6cf3d077b8f6955f6f4703cded1e22d6d7741ccd Mon Sep 17 00:00:00 2001
From: Samuel Newcome <samuel.newcome at tum.de>
Date: Tue, 29 Sep 2026 11:02:17 +0200
Subject: [PATCH 2/2] Static-steal is now settable with omp_set_schedule,
 fixing the previously added test. To handle its use in ordered for-loops, we
 convert the schedule to dynamic non-monotonic in
 __kmp_dispatch_init_algorithm, like when it gets set in the environment
 variable. A test than ordered static-steal works correctly is also added.

---
 openmp/runtime/src/kmp_dispatch.cpp           |  7 +++
 openmp/runtime/src/kmp_global.cpp             |  7 ++-
 .../for/kmp_sched_static_steal_ordered.c      | 63 +++++++++++++++++++
 3 files changed, 74 insertions(+), 3 deletions(-)
 create mode 100644 openmp/runtime/test/worksharing/for/kmp_sched_static_steal_ordered.c

diff --git a/openmp/runtime/src/kmp_dispatch.cpp b/openmp/runtime/src/kmp_dispatch.cpp
index 3b4a1f34df040..57e4bcb83f60f 100644
--- a/openmp/runtime/src/kmp_dispatch.cpp
+++ b/openmp/runtime/src/kmp_dispatch.cpp
@@ -265,6 +265,13 @@ void __kmp_dispatch_init_algorithm(ident_t *loc, int gtid,
       // Use the scheduling specified by OMP_SCHEDULE (or __kmp_sch_default if
       // not specified)
       schedule = team->t.t_sched.r_sched_type;
+#if KMP_STATIC_STEAL_ENABLED
+      // Treat static_steal set by omp_set_schedule() like
+      // OMP_SCHEDULE=static_steal, i.e. as nonmonotonic dynamic
+      if (SCHEDULE_WITHOUT_MODIFIERS(schedule) == kmp_sch_static_steal)
+        schedule = (enum sched_type)(kmp_sch_dynamic_chunked |
+                                     kmp_sch_modifier_nonmonotonic);
+#endif
       monotonicity = __kmp_get_monotonicity(loc, schedule, use_hier);
       schedule = SCHEDULE_WITHOUT_MODIFIERS(schedule);
       if (pr->flags.ordered) // correct monotonicity for ordered loop if needed
diff --git a/openmp/runtime/src/kmp_global.cpp b/openmp/runtime/src/kmp_global.cpp
index 15b9babfaf0ba..78ae429e3d465 100644
--- a/openmp/runtime/src/kmp_global.cpp
+++ b/openmp/runtime/src/kmp_global.cpp
@@ -235,9 +235,10 @@ enum sched_type __kmp_sch_map[kmp_sched_upper - kmp_sched_lower_ext +
     kmp_sch_dynamic_chunked, // ==> kmp_sched_dynamic           = 2
     kmp_sch_guided_chunked, // ==> kmp_sched_guided            = 3
     kmp_sch_auto, // ==> kmp_sched_auto              = 4
-    kmp_sch_trapezoidal // ==> kmp_sched_trapezoidal       = 101
-    // will likely not be used, introduced here just to debug the code
-    // of public intel extension schedules
+    kmp_sch_trapezoidal, // ==> kmp_sched_trapezoidal       = 101
+#if KMP_STATIC_STEAL_ENABLED
+    kmp_sch_static_steal // ==> kmp_sched_static_steal      = 102
+#endif
 };
 
 #if KMP_MIC_SUPPORTED
diff --git a/openmp/runtime/test/worksharing/for/kmp_sched_static_steal_ordered.c b/openmp/runtime/test/worksharing/for/kmp_sched_static_steal_ordered.c
new file mode 100644
index 0000000000000..d92d1101c7f41
--- /dev/null
+++ b/openmp/runtime/test/worksharing/for/kmp_sched_static_steal_ordered.c
@@ -0,0 +1,63 @@
+// RUN: %libomp-compile-and-run
+
+// Tests that an ordered loop with schedule(runtime) when the run-time
+// schedule is set to static_steal with omp_set_schedule(), does not
+// use the unordered static-steal scheduling nor hang.
+// Such loops must fall back to dynamic, as they do with the environment
+// variable OMP_SCHEDULE=static_steal.
+
+#include <omp.h>
+#include "omp_testsuite.h"
+
+// ---------------------------------------------------------------------------
+// Definition copied from OpenMP RTL (kmp_sched_t in kmp.h).
+enum { kmp_sched_static_steal = 102 };
+// End of definition copied from OpenMP RTL.
+// ---------------------------------------------------------------------------
+
+static int last_i = 0;
+
+/* Utility function to check that i is increasing monotonically
+   with each call */
+static int check_i_islarger(int i) {
+  int islarger;
+  islarger = (i > last_i);
+  last_i = i;
+  return (islarger);
+}
+
+int test_static_steal_ordered() {
+  int sum;
+  int is_larger = 1;
+  int known_sum;
+  int i;
+
+  last_i = 0;
+  sum = 0;
+  omp_set_schedule((omp_sched_t)kmp_sched_static_steal, 4);
+
+  // num_threads(4): static_steal needs more than one thread.
+#pragma omp parallel for schedule(runtime) ordered num_threads(4)
+  for (i = 1; i <= LOOPCOUNT; i++) {
+#pragma omp ordered
+    {
+      is_larger = check_i_islarger(i) && is_larger;
+      sum = sum + i;
+    }
+  }
+
+  known_sum = (LOOPCOUNT * (LOOPCOUNT + 1)) / 2;
+  return (known_sum == sum) && is_larger;
+}
+
+int main() {
+  int i;
+  int num_failed = 0;
+
+  for (i = 0; i < REPETITIONS; i++) {
+    if (!test_static_steal_ordered()) {
+      num_failed++;
+    }
+  }
+  return num_failed;
+}
\ No newline at end of file



More information about the Openmp-commits mailing list