[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