aboutsummaryrefslogtreecommitdiff
path: root/final/runtime/test/worksharing/for/omp_monotonic_schedule_set_get.c
diff options
context:
space:
mode:
Diffstat (limited to 'final/runtime/test/worksharing/for/omp_monotonic_schedule_set_get.c')
-rw-r--r--final/runtime/test/worksharing/for/omp_monotonic_schedule_set_get.c134
1 files changed, 134 insertions, 0 deletions
diff --git a/final/runtime/test/worksharing/for/omp_monotonic_schedule_set_get.c b/final/runtime/test/worksharing/for/omp_monotonic_schedule_set_get.c
new file mode 100644
index 0000000..94896eb
--- /dev/null
+++ b/final/runtime/test/worksharing/for/omp_monotonic_schedule_set_get.c
@@ -0,0 +1,134 @@
+// RUN: %libomp-compile-and-run
+
+// The test checks OMP 5.0 monotonic/nonmonotonic scheduling API
+// 1. initial schedule should be (static,0)
+// 2. omp_get_schedule() should return the schedule set by omp_set_schedule()
+// 3. schedules set inside parallel should not impact outer tasks' schedules
+
+#include <stdio.h>
+#ifndef __INTEL_COMPILER
+#define _OMPIMP
+#endif
+
+#define NO_MODIFIERS ((omp_sched_t)0)
+
+#include "omp.h"
+
+int global = 0;
+int err = 0;
+
+omp_sched_t sched_append_modifiers(omp_sched_t sched, omp_sched_t modifiers) {
+ return (omp_sched_t)((int)sched | (int)modifiers);
+}
+
+omp_sched_t sched_without_modifiers(omp_sched_t sched) {
+ return (omp_sched_t)((int)sched & ~((int)omp_sched_monotonic));
+}
+
+int sched_has_modifiers(omp_sched_t sched, omp_sched_t modifiers) {
+ return (((int)sched & ((int)omp_sched_monotonic)) > 0);
+}
+
+// check that sched = hope | modifiers
+void check_schedule(const char *extra, const omp_sched_t sched, int chunk,
+ omp_sched_t hope_sched, int hope_chunk) {
+
+ if (sched != hope_sched || chunk != hope_chunk) {
+#pragma omp atomic
+ ++err;
+ printf("Error: %s: schedule: (%d, %d) is not equal to (%d, %d)\n", extra,
+ (int)hope_sched, hope_chunk, (int)sched, chunk);
+ }
+}
+
+int main() {
+ int i;
+ int chunk;
+ omp_sched_t sched0;
+
+ omp_set_dynamic(0);
+ omp_set_nested(1);
+
+ // check serial region
+ omp_get_schedule(&sched0, &chunk);
+#ifdef DEBUG
+ printf("initial: (%d, %d)\n", sched0, chunk);
+#endif
+ check_schedule("initial", omp_sched_static, 0, sched0, chunk);
+ // set schedule before the parallel, check it after the parallel
+ omp_set_schedule(
+ sched_append_modifiers(omp_sched_dynamic, omp_sched_monotonic), 3);
+
+#pragma omp parallel num_threads(3) private(i)
+ {
+ omp_sched_t n_outer_set, n_outer_get;
+ int c_outer;
+ int tid = omp_get_thread_num();
+
+ n_outer_set = sched_append_modifiers((omp_sched_t)(tid + 1),
+ omp_sched_monotonic); // 1, 2, 3
+
+ // check outer parallel region
+ // master sets (static, unchunked), others - (dynamic, 1), (guided, 2)
+ // set schedule before inner parallel, check it after the parallel
+ omp_set_schedule(n_outer_set, tid);
+
+// Make sure this schedule doesn't crash the runtime
+#pragma omp for
+ for (i = 0; i < 100; ++i) {
+#pragma omp atomic
+ global++;
+ }
+
+#pragma omp parallel num_threads(3) private(i) shared(n_outer_set)
+ {
+ omp_sched_t n_inner_set, n_inner_get;
+ int c_inner_set, c_inner_get;
+ int tid = omp_get_thread_num();
+
+ n_inner_set = (omp_sched_t)(tid + 1); // 1, 2, 3
+ c_inner_set = (int)(n_outer_set)*10 +
+ (int)n_inner_set; // 11, 12, 13, 21, 22, 23, 31, 32, 33
+ n_inner_set = sched_append_modifiers(n_inner_set, omp_sched_monotonic);
+ // schedules set inside parallel should not impact outer schedules
+ omp_set_schedule(n_inner_set, c_inner_set);
+
+// Make sure this schedule doesn't crash the runtime
+#pragma omp for
+ for (i = 0; i < 100; ++i) {
+#pragma omp atomic
+ global++;
+ }
+
+#pragma omp barrier
+ omp_get_schedule(&n_inner_get, &c_inner_get);
+#ifdef DEBUG
+ printf("inner parallel: o_th %d, i_th %d, (%d, %d)\n", n_outer_set - 1,
+ tid, n_inner_get, c_inner_get);
+#endif
+ check_schedule("inner", n_inner_set, c_inner_set, n_inner_get,
+ c_inner_get);
+ }
+
+ omp_get_schedule(&n_outer_get, &c_outer);
+#ifdef DEBUG
+ printf("outer parallel: thread %d, (%d, %d)\n", tid, n_outer_get, c_outer);
+#endif
+ check_schedule("outer", n_outer_set, tid, n_outer_get, c_outer);
+ }
+
+ omp_get_schedule(&sched0, &chunk);
+#ifdef DEBUG
+ printf("after parallels: (%d, %d)\n", sched0, chunk);
+#endif
+ check_schedule("after parallels",
+ sched_append_modifiers(omp_sched_dynamic, omp_sched_monotonic),
+ 3, sched0, chunk);
+
+ if (err > 0) {
+ printf("Failed\n");
+ return 1;
+ }
+ printf("Passed\n");
+ return 0;
+}