1 // RUN: %libomp-compile-and-run | FileCheck %s
4 // The runtime currently does not get dependency information from GCC.
7 // Tests OMP 5.x task dependence "omp_all_memory",
8 // emulates compiler codegen versions for new dep kind
11 // task0 - task1 (in: i1, i2)
13 // task2 (inoutset: i2), (in: i1)
15 // task3 (omp_all_memory) via flag=0x80
17 // task4 - task5 (in: i1, i2)
19 // task6 (omp_all_memory) via addr=-1
21 // task7 (omp_all_memory) via flag=0x80
26 // CHECK: ompt_event_dependences:
27 // CHECK-SAME: ompt_dependence_type_in
28 // CHECK-SAME: ompt_dependence_type_in
29 // CHECK-SAME: ndeps=2
31 // CHECK: ompt_event_dependences:
32 // CHECK-SAME: ompt_dependence_type_in
33 // CHECK-SAME: ompt_dependence_type_in
34 // CHECK-SAME: ndeps=2
36 // CHECK: ompt_event_dependences:
37 // CHECK-SAME: ompt_dependence_type_in
38 // CHECK-SAME: ompt_dependence_type_inoutset
39 // CHECK-SAME: ndeps=2
41 // CHECK: ompt_event_dependences:
42 // CHECK-SAME: ompt_dependence_type_in
43 // CHECK-SAME: ompt_dependence_type_out_all_memory
44 // CHECK-SAME: ndeps=2
46 // CHECK: ompt_event_dependences:
47 // CHECK-SAME: ompt_dependence_type_in
48 // CHECK-SAME: ompt_dependence_type_in
49 // CHECK-SAME: ndeps=2
51 // CHECK: ompt_event_dependences:
52 // CHECK-SAME: ompt_dependence_type_in
53 // CHECK-SAME: ompt_dependence_type_in
54 // CHECK-SAME: ndeps=2
56 // CHECK: ompt_event_dependences:
57 // CHECK-SAME: ompt_dependence_type_out_all_memory
58 // CHECK-SAME: ndeps=1
60 // CHECK: ompt_event_dependences:
61 // CHECK-SAME: ompt_dependence_type_out_all_memory
62 // CHECK-SAME: ompt_dependence_type_mutexinoutset
63 // CHECK-SAME: ndeps=2
65 // CHECK: ompt_event_dependences:
66 // CHECK-SAME: ompt_dependence_type_in
67 // CHECK-SAME: ndeps=1
75 #define mysleep(n) Sleep(n)
78 #define mysleep(n) usleep((n)*1000)
81 // to check the # of concurrent tasks (must be 1 for MTX, <3 for other kinds)
82 static int checker
= 0;
88 // ---------------------------------------------------------------------------
89 // internal data to emulate compiler codegen
95 #define DEP_ALL_MEM 0x80
106 typedef int (*entry_t
)(int, task_t
*);
114 // thunk routine for tasks with ALL dependency
115 int thunk_m(int gtid
, task_t
*ptask
) {
117 #pragma omp atomic capture
119 th
= omp_get_thread_num();
120 printf("task m_%d, th %d, checker %d\n", ptask
->f_priv
, th
, lcheck
);
121 if (lcheck
!= 1) { // no more than 1 task at a time
123 printf("Error m1, checker %d != 1\n", lcheck
);
126 #pragma omp atomic read
127 lcheck
= checker
; // must still be equal to 1
130 printf("Error m2, checker %d != 1\n", lcheck
);
136 // thunk routine for tasks with inoutset dependency
137 int thunk_s(int gtid
, task_t
*ptask
) {
139 #pragma omp atomic capture
140 lcheck
= ++checker
; // 1
141 th
= omp_get_thread_num();
142 printf("task 2_%d, th %d, checker %d\n", ptask
->f_priv
, th
, lcheck
);
143 if (lcheck
!= 1) { // no more than 1 task at a time
145 printf("Error s1, checker %d != 1\n", lcheck
);
148 #pragma omp atomic read
149 lcheck
= checker
; // must still be equal to 1
152 printf("Error s2, checker %d != 1\n", lcheck
);
162 int __kmpc_global_thread_num(id
*);
163 task_t
*__kmpc_omp_task_alloc(id
*loc
, int gtid
, int flags
, size_t sz
,
164 size_t shar
, entry_t rtn
);
165 int __kmpc_omp_task_with_deps(id
*loc
, int gtid
, task_t
*task
, int ndeps
,
166 dep
*dep_lst
, int nd_noalias
, dep
*noalias_lst
);
167 static id loc
= {0, 2, 0, 0, ";file;func;0;0;;"};
171 // End of internal data
172 // ---------------------------------------------------------------------------
175 char *ompx_all_memory
= (void *)0xffffffffffffffff;
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 #pragma omp task depend(in : i1) depend(inout : ompx_all_memory[0])
246 #pragma omp atomic capture
248 th
= omp_get_thread_num();
249 printf("task m_%d, th %d, checker %d\n", t
, th
, lcheck
);
250 if (lcheck
!= 1) { // no more than 1 task at a time
252 printf("Error m1, checker %d != 1\n", lcheck
);
255 #pragma omp atomic read
256 lcheck
= checker
; // must still be equal to 1
259 printf("Error m2, checker %d != 1\n", lcheck
);
264 // compiler codegen end
265 #pragma omp task depend(in : i1, i2)
268 #pragma omp atomic capture
269 lcheck
= ++checker
; // 1 or 2
270 th
= omp_get_thread_num();
271 printf("task 4_%d, th %d, checker %d\n", t
, th
, lcheck
);
272 if (lcheck
> 2 || lcheck
< 1) {
273 err
++; // no more than 2 tasks concurrently
274 printf("Error5, checker %d, not 1 or 2\n", lcheck
);
277 #pragma omp atomic read
278 lcheck
= checker
; // 1 or 2
279 if (lcheck
> 2 || lcheck
< 1) {
281 printf("Error6, checker %d, not 1 or 2\n", lcheck
);
286 #pragma omp task depend(in : i1, i2)
289 #pragma omp atomic capture
290 lcheck
= ++checker
; // 1 or 2
291 th
= omp_get_thread_num();
292 printf("task 5_%d, th %d, checker %d\n", t
, th
, lcheck
);
293 if (lcheck
> 2 || lcheck
< 1) {
294 err
++; // no more than 2 tasks concurrently
295 printf("Error7, checker %d, not 1 or 2\n", lcheck
);
298 #pragma omp atomic read
299 lcheck
= checker
; // 1 or 2
300 if (lcheck
> 2 || lcheck
< 1) {
302 printf("Error8, checker %d, not 1 or 2\n", lcheck
);
308 #pragma omp task depend(inout : ompx_all_memory[0])
311 #pragma omp atomic capture
313 th
= omp_get_thread_num();
314 printf("task m_%d, th %d, checker %d\n", t
, th
, lcheck
);
315 if (lcheck
!= 1) { // no more than 1 task at a time
317 printf("Error m1, checker %d != 1\n", lcheck
);
320 #pragma omp atomic read
321 lcheck
= checker
; // must still be equal to 1
324 printf("Error m2, checker %d != 1\n", lcheck
);
330 #pragma omp task depend(inout : ompx_all_memory[0]) depend(mutexinoutset : i3)
333 #pragma omp atomic capture
335 th
= omp_get_thread_num();
336 printf("task m_%d, th %d, checker %d\n", t
, th
, lcheck
);
337 if (lcheck
!= 1) { // no more than 1 task at a time
339 printf("Error m1, checker %d != 1\n", lcheck
);
342 #pragma omp atomic read
343 lcheck
= checker
; // must still be equal to 1
346 printf("Error m2, checker %d != 1\n", lcheck
);
351 #pragma omp task depend(in : i3)
354 #pragma omp atomic capture
355 lcheck
= ++checker
; // 1
356 th
= omp_get_thread_num();
357 printf("task 8_%d, th %d, checker %d\n", t
, th
, lcheck
);
360 printf("Error9, checker %d, != 1\n", lcheck
);
363 #pragma omp atomic read
367 printf("Error10, checker %d, != 1\n", lcheck
);
374 if (err
== 0 && checker
== 0) {
378 printf("failed, err = %d, checker = %d\n", err
, checker
);