1 // RUN: %libomp-compile-and-run | FileCheck %s
4 // RUN: %libomp-compile-and-run
5 // The runtime currently does not get dependency information from GCC.
8 // Tests OMP 5.x task dependence "omp_all_memory",
9 // emulates compiler codegen versions for new dep kind
12 // task0 - task1 (in: i1, i2)
14 // task2 (inoutset: i2), (in: i1)
16 // task3 (omp_all_memory) via flag=0x80
18 // task4 - task5 (in: i1, i2)
20 // task6 (omp_all_memory) via addr=-1
22 // task7 (omp_all_memory) via flag=0x80
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
76 #define mysleep(n) Sleep(n)
79 #define mysleep(n) usleep((n)*1000)
82 // to check the # of concurrent tasks (must be 1 for MTX, <3 for other kinds)
83 static int checker
= 0;
89 // ---------------------------------------------------------------------------
90 // internal data to emulate compiler codegen
96 #define DEP_ALL_MEM 0x80
107 typedef int (*entry_t
)(int, task_t
*);
115 // thunk routine for tasks with ALL dependency
116 int thunk_m(int gtid
, task_t
*ptask
) {
118 #pragma omp atomic capture
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
124 printf("Error m1, checker %d != 1\n", lcheck
);
127 #pragma omp atomic read
128 lcheck
= checker
; // must still be equal to 1
131 printf("Error m2, checker %d != 1\n", lcheck
);
137 // thunk routine for tasks with inoutset dependency
138 int thunk_s(int gtid
, task_t
*ptask
) {
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
146 printf("Error s1, checker %d != 1\n", lcheck
);
149 #pragma omp atomic read
150 lcheck
= checker
; // must still be equal to 1
153 printf("Error s2, checker %d != 1\n", lcheck
);
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;;"};
172 // End of internal data
173 // ---------------------------------------------------------------------------
177 omp_set_num_threads(8);
181 #pragma omp single nowait
185 int gtid
= __kmpc_global_thread_num(&loc
);
186 int t
= omp_get_thread_num();
187 #pragma omp task depend(in : i1, i2)
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
);
199 #pragma omp atomic read
200 lcheck
= checker
; // 1 or 2
201 if (lcheck
> 2 || lcheck
< 1) {
204 printf("Error2, checker %d, not 1 or 2\n", lcheck
);
209 #pragma omp task depend(in : i1, i2)
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
);
221 #pragma omp atomic read
222 lcheck
= checker
; // 1 or 2
223 if (lcheck
> 2 || lcheck
< 1) {
225 printf("Error4, checker %d, not 1 or 2\n", lcheck
);
230 // compiler codegen start
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);
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
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)
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
);
265 #pragma omp atomic read
266 lcheck
= checker
; // 1 or 2
267 if (lcheck
> 2 || lcheck
< 1) {
269 printf("Error6, checker %d, not 1 or 2\n", lcheck
);
274 #pragma omp task depend(in : i1, i2)
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
);
286 #pragma omp atomic read
287 lcheck
= checker
; // 1 or 2
288 if (lcheck
> 2 || lcheck
< 1) {
290 printf("Error8, checker %d, not 1 or 2\n", lcheck
);
295 // compiler codegen start
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);
305 ptr
= __kmpc_omp_task_alloc(&loc
, gtid
, TIED
, sizeof(task_t
), 0, thunk_m
);
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)
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
);
324 printf("Error9, checker %d, != 1\n", lcheck
);
327 #pragma omp atomic read
331 printf("Error10, checker %d, != 1\n", lcheck
);
338 if (err
== 0 && checker
== 0) {
342 printf("failed, err = %d, checker = %d\n", err
, checker
);