[rtsan] Add fork/execve interceptors (#117198)
[llvm-project.git] / openmp / runtime / test / ompt / tasks / kmp_task_depend_all.c
bloba18fe5a726e777f641b5faeca5d8892704278543
1 // RUN: %libomp-compile-and-run | FileCheck %s
2 // REQUIRES: ompt
4 // RUN: %libomp-compile-and-run
5 // The runtime currently does not get dependency information from GCC.
6 // UNSUPPORTED: gcc
8 // Tests OMP 5.x task dependence "omp_all_memory",
9 // emulates compiler codegen versions for new dep kind
11 // Task tree created:
12 // task0 - task1 (in: i1, i2)
13 // \
14 // task2 (inoutset: i2), (in: i1)
15 // /
16 // task3 (omp_all_memory) via flag=0x80
17 // /
18 // task4 - task5 (in: i1, i2)
19 // /
20 // task6 (omp_all_memory) via addr=-1
21 // /
22 // task7 (omp_all_memory) via flag=0x80
23 // /
24 // task8 (in: i3)
27 // CHECK: ompt_event_dependences:
28 // CHECK-SAME: ompt_dependence_type_in
29 // CHECK-SAME: ompt_dependence_type_in
30 // CHECK-SAME: ndeps=2
32 // CHECK: ompt_event_dependences:
33 // CHECK-SAME: ompt_dependence_type_in
34 // CHECK-SAME: ompt_dependence_type_in
35 // CHECK-SAME: ndeps=2
37 // CHECK: ompt_event_dependences:
38 // CHECK-SAME: ompt_dependence_type_in
39 // CHECK-SAME: ompt_dependence_type_inoutset
40 // CHECK-SAME: ndeps=2
42 // CHECK: ompt_event_dependences:
43 // CHECK-SAME: ompt_dependence_type_in
44 // CHECK-SAME: ompt_dependence_type_out_all_memory
45 // CHECK-SAME: ndeps=2
47 // CHECK: ompt_event_dependences:
48 // CHECK-SAME: ompt_dependence_type_in
49 // CHECK-SAME: ompt_dependence_type_in
50 // CHECK-SAME: ndeps=2
52 // CHECK: ompt_event_dependences:
53 // CHECK-SAME: ompt_dependence_type_in
54 // CHECK-SAME: ompt_dependence_type_in
55 // CHECK-SAME: ndeps=2
57 // CHECK: ompt_event_dependences:
58 // CHECK-SAME: ompt_dependence_type_out_all_memory
59 // CHECK-SAME: ndeps=1
61 // CHECK: ompt_event_dependences:
62 // CHECK-SAME: ompt_dependence_type_out_all_memory
63 // CHECK-SAME: ompt_dependence_type_mutexinoutset
64 // CHECK-SAME: ndeps=2
66 // CHECK: ompt_event_dependences:
67 // CHECK-SAME: ompt_dependence_type_in
68 // CHECK-SAME: ndeps=1
70 #include "callback.h"
71 #include <stdio.h>
72 #include <omp.h>
74 #ifdef _WIN32
75 #include <windows.h>
76 #define mysleep(n) Sleep(n)
77 #else
78 #include <unistd.h>
79 #define mysleep(n) usleep((n)*1000)
80 #endif
82 // to check the # of concurrent tasks (must be 1 for MTX, <3 for other kinds)
83 static int checker = 0;
84 static int err = 0;
85 #ifndef DELAY
86 #define DELAY 100
87 #endif
89 // ---------------------------------------------------------------------------
90 // internal data to emulate compiler codegen
91 typedef struct DEP {
92 size_t addr;
93 size_t len;
94 unsigned char flags;
95 } dep;
96 #define DEP_ALL_MEM 0x80
97 typedef struct task {
98 void **shareds;
99 void *entry;
100 int part_id;
101 void *destr_thunk;
102 int priority;
103 long long device_id;
104 int f_priv;
105 } task_t;
106 #define TIED 1
107 typedef int (*entry_t)(int, task_t *);
108 typedef struct ID {
109 int reserved_1;
110 int flags;
111 int reserved_2;
112 int reserved_3;
113 char *psource;
114 } id;
115 // thunk routine for tasks with ALL dependency
116 int thunk_m(int gtid, task_t *ptask) {
117 int lcheck, th;
118 #pragma omp atomic capture
119 lcheck = ++checker;
120 th = omp_get_thread_num();
121 printf("task m_%d, th %d, checker %d\n", ptask->f_priv, th, lcheck);
122 if (lcheck != 1) { // no more than 1 task at a time
123 err++;
124 printf("Error m1, checker %d != 1\n", lcheck);
126 mysleep(DELAY);
127 #pragma omp atomic read
128 lcheck = checker; // must still be equal to 1
129 if (lcheck != 1) {
130 err++;
131 printf("Error m2, checker %d != 1\n", lcheck);
133 #pragma omp atomic
134 --checker;
135 return 0;
137 // thunk routine for tasks with inoutset dependency
138 int thunk_s(int gtid, task_t *ptask) {
139 int lcheck, th;
140 #pragma omp atomic capture
141 lcheck = ++checker; // 1
142 th = omp_get_thread_num();
143 printf("task 2_%d, th %d, checker %d\n", ptask->f_priv, th, lcheck);
144 if (lcheck != 1) { // no more than 1 task at a time
145 err++;
146 printf("Error s1, checker %d != 1\n", lcheck);
148 mysleep(DELAY);
149 #pragma omp atomic read
150 lcheck = checker; // must still be equal to 1
151 if (lcheck != 1) {
152 err++;
153 printf("Error s2, checker %d != 1\n", lcheck);
155 #pragma omp atomic
156 --checker;
157 return 0;
160 #ifdef __cplusplus
161 extern "C" {
162 #endif
163 int __kmpc_global_thread_num(id *);
164 task_t *__kmpc_omp_task_alloc(id *loc, int gtid, int flags, size_t sz,
165 size_t shar, entry_t rtn);
166 int __kmpc_omp_task_with_deps(id *loc, int gtid, task_t *task, int ndeps,
167 dep *dep_lst, int nd_noalias, dep *noalias_lst);
168 static id loc = {0, 2, 0, 0, ";file;func;0;0;;"};
169 #ifdef __cplusplus
170 } // extern "C"
171 #endif
172 // End of internal data
173 // ---------------------------------------------------------------------------
175 int main() {
176 int i1, i2, i3;
177 omp_set_num_threads(8);
178 omp_set_dynamic(0);
179 #pragma omp parallel
181 #pragma omp single nowait
183 dep sdep[2];
184 task_t *ptr;
185 int gtid = __kmpc_global_thread_num(&loc);
186 int t = omp_get_thread_num();
187 #pragma omp task depend(in : i1, i2)
188 { // task 0
189 int lcheck, th;
190 #pragma omp atomic capture
191 lcheck = ++checker; // 1 or 2
192 th = omp_get_thread_num();
193 printf("task 0_%d, th %d, checker %d\n", t, th, lcheck);
194 if (lcheck > 2 || lcheck < 1) {
195 err++; // no more than 2 tasks concurrently
196 printf("Error1, checker %d, not 1 or 2\n", lcheck);
198 mysleep(DELAY);
199 #pragma omp atomic read
200 lcheck = checker; // 1 or 2
201 if (lcheck > 2 || lcheck < 1) {
202 #pragma omp atomic
203 err++;
204 printf("Error2, checker %d, not 1 or 2\n", lcheck);
206 #pragma omp atomic
207 --checker;
209 #pragma omp task depend(in : i1, i2)
210 { // task 1
211 int lcheck, th;
212 #pragma omp atomic capture
213 lcheck = ++checker; // 1 or 2
214 th = omp_get_thread_num();
215 printf("task 1_%d, th %d, checker %d\n", t, th, lcheck);
216 if (lcheck > 2 || lcheck < 1) {
217 err++; // no more than 2 tasks concurrently
218 printf("Error3, checker %d, not 1 or 2\n", lcheck);
220 mysleep(DELAY);
221 #pragma omp atomic read
222 lcheck = checker; // 1 or 2
223 if (lcheck > 2 || lcheck < 1) {
224 err++;
225 printf("Error4, checker %d, not 1 or 2\n", lcheck);
227 #pragma omp atomic
228 --checker;
230 // compiler codegen start
231 // task2
232 ptr = __kmpc_omp_task_alloc(&loc, gtid, TIED, sizeof(task_t), 0, thunk_s);
233 sdep[0].addr = (size_t)&i1;
234 sdep[0].len = 0; // not used
235 sdep[0].flags = 1; // IN
236 sdep[1].addr = (size_t)&i2;
237 sdep[1].len = 0; // not used
238 sdep[1].flags = 8; // INOUTSET
239 ptr->f_priv = t + 10; // init single first-private variable
240 __kmpc_omp_task_with_deps(&loc, gtid, ptr, 2, sdep, 0, 0);
242 // task3
243 ptr = __kmpc_omp_task_alloc(&loc, gtid, TIED, sizeof(task_t), 0, thunk_m);
244 sdep[0].addr = (size_t)&i1; // to be ignored
245 sdep[0].len = 0; // not used
246 sdep[0].flags = 1; // IN
247 sdep[1].addr = 0;
248 sdep[1].len = 0; // not used
249 sdep[1].flags = DEP_ALL_MEM; // omp_all_memory
250 ptr->f_priv = t + 20; // init single first-private variable
251 __kmpc_omp_task_with_deps(&loc, gtid, ptr, 2, sdep, 0, 0);
252 // compiler codegen end
253 #pragma omp task depend(in : i1, i2)
254 { // task 4
255 int lcheck, th;
256 #pragma omp atomic capture
257 lcheck = ++checker; // 1 or 2
258 th = omp_get_thread_num();
259 printf("task 4_%d, th %d, checker %d\n", t, th, lcheck);
260 if (lcheck > 2 || lcheck < 1) {
261 err++; // no more than 2 tasks concurrently
262 printf("Error5, checker %d, not 1 or 2\n", lcheck);
264 mysleep(DELAY);
265 #pragma omp atomic read
266 lcheck = checker; // 1 or 2
267 if (lcheck > 2 || lcheck < 1) {
268 err++;
269 printf("Error6, checker %d, not 1 or 2\n", lcheck);
271 #pragma omp atomic
272 --checker;
274 #pragma omp task depend(in : i1, i2)
275 { // task 5
276 int lcheck, th;
277 #pragma omp atomic capture
278 lcheck = ++checker; // 1 or 2
279 th = omp_get_thread_num();
280 printf("task 5_%d, th %d, checker %d\n", t, th, lcheck);
281 if (lcheck > 2 || lcheck < 1) {
282 err++; // no more than 2 tasks concurrently
283 printf("Error7, checker %d, not 1 or 2\n", lcheck);
285 mysleep(DELAY);
286 #pragma omp atomic read
287 lcheck = checker; // 1 or 2
288 if (lcheck > 2 || lcheck < 1) {
289 err++;
290 printf("Error8, checker %d, not 1 or 2\n", lcheck);
292 #pragma omp atomic
293 --checker;
295 // compiler codegen start
296 // task6
297 ptr = __kmpc_omp_task_alloc(&loc, gtid, TIED, sizeof(task_t), 0, thunk_m);
298 sdep[0].addr = (size_t)(-1); // omp_all_memory
299 sdep[0].len = 0; // not used
300 sdep[0].flags = 2; // OUT
301 ptr->f_priv = t + 30; // init single first-private variable
302 __kmpc_omp_task_with_deps(&loc, gtid, ptr, 1, sdep, 0, 0);
304 // task7
305 ptr = __kmpc_omp_task_alloc(&loc, gtid, TIED, sizeof(task_t), 0, thunk_m);
306 sdep[0].addr = 0;
307 sdep[0].len = 0; // not used
308 sdep[0].flags = DEP_ALL_MEM; // omp_all_memory
309 sdep[1].addr = (size_t)&i3; // to be ignored
310 sdep[1].len = 0; // not used
311 sdep[1].flags = 4; // MUTEXINOUTSET
312 ptr->f_priv = t + 40; // init single first-private variable
313 __kmpc_omp_task_with_deps(&loc, gtid, ptr, 2, sdep, 0, 0);
314 // compiler codegen end
315 #pragma omp task depend(in : i3)
316 { // task 8
317 int lcheck, th;
318 #pragma omp atomic capture
319 lcheck = ++checker; // 1
320 th = omp_get_thread_num();
321 printf("task 8_%d, th %d, checker %d\n", t, th, lcheck);
322 if (lcheck != 1) {
323 err++;
324 printf("Error9, checker %d, != 1\n", lcheck);
326 mysleep(DELAY);
327 #pragma omp atomic read
328 lcheck = checker;
329 if (lcheck != 1) {
330 err++;
331 printf("Error10, checker %d, != 1\n", lcheck);
333 #pragma omp atomic
334 --checker;
336 } // single
337 } // parallel
338 if (err == 0 && checker == 0) {
339 printf("passed\n");
340 return 0;
341 } else {
342 printf("failed, err = %d, checker = %d\n", err, checker);
343 return 1;