1 // RUN: %libomp-compile-and-run
2 // The runtime currently does not get dependency information from GCC.
5 // Tests OMP 5.x task dependence "omp_all_memory",
6 // emulates compiler codegen versions for new dep kind
9 // task0 - task1 (in: i1, i2)
11 // task2 (inoutset: i2), (in: i1)
13 // task3 (omp_all_memory) via flag=0x80
15 // task4 - task5 (in: i1, i2)
17 // task6 (omp_all_memory) via addr=-1
19 // task7 (omp_all_memory) via flag=0x80
23 // task9 - no dependences
25 // taskwait (omp_all_memory) (should not wait for task9, see prints)
32 #define mysleep(n) Sleep(n)
35 #define mysleep(n) usleep((n)*1000)
38 // to check the # of concurrent tasks (must be 1 for MTX, <3 for other kinds)
39 static int checker
= 0;
41 static int taskwait_flag
= 0;
43 // set delay interval in ms for dependent tasks
47 // ---------------------------------------------------------------------------
48 // internal data to emulate compiler codegen
54 #define DEP_ALL_MEM 0x80
65 typedef int(*entry_t
)(int, task_t
*);
73 // thunk routine for tasks with ALL dependency
74 int thunk_m(int gtid
, task_t
* ptask
) {
76 #pragma omp atomic capture
78 th
= omp_get_thread_num();
79 printf("task m_%d, th %d, checker %d\n", ptask
->f_priv
, th
, lcheck
);
80 if (lcheck
!= 1) { // no more than 1 task at a time
82 printf("Error m1, checker %d != 1\n", lcheck
);
85 #pragma omp atomic read
86 lcheck
= checker
; // must still be equal to 1
89 printf("Error m2, checker %d != 1\n", lcheck
);
95 // thunk routine for tasks with inoutset dependency
96 int thunk_s(int gtid
, task_t
* ptask
) {
98 #pragma omp atomic capture
99 lcheck
= ++checker
; // 1
100 th
= omp_get_thread_num();
101 printf("task 2_%d, th %d, checker %d\n", ptask
->f_priv
, th
, lcheck
);
102 if (lcheck
!= 1) { // no more than 1 task at a time
104 printf("Error s1, checker %d != 1\n", lcheck
);
107 #pragma omp atomic read
108 lcheck
= checker
; // must still be equal to 1
111 printf("Error s2, checker %d != 1\n", lcheck
);
121 int __kmpc_global_thread_num(id
*);
122 task_t
*__kmpc_omp_task_alloc(id
*loc
, int gtid
, int flags
,
123 size_t sz
, size_t shar
, entry_t rtn
);
124 int __kmpc_omp_task_with_deps(id
*loc
, int gtid
, task_t
*task
, int ndeps
,
125 dep
*dep_lst
, int nd_noalias
, dep
*noalias_lst
);
126 void __kmpc_omp_wait_deps(id
*loc
, int gtid
, int ndeps
, dep
*dep_lst
,
127 int ndeps_noalias
, dep
*noalias_dep_lst
);
128 static id loc
= {0, 2, 0, 0, ";file;func;0;0;;"};
132 // End of internal data
133 // ---------------------------------------------------------------------------
138 omp_set_num_threads(8);
142 #pragma omp single nowait
146 int gtid
= __kmpc_global_thread_num(&loc
);
147 int t
= omp_get_thread_num();
148 // Create longest task first to ensure it is stolen.
149 // The test may hang if the task created last and
150 // executed by a thread which executes taskwait.
152 { // task 9 - long running task
154 int th
= omp_get_thread_num();
155 printf("signalled independent task 9_%d, th %d started....\n", t
, th
);
156 // Wait for taskwait depend() to finish
157 // If the taskwait depend() improperly depends on this task
158 // to finish, then the test will hang and a timeout should trigger
160 #pragma omp atomic read
161 flag
= taskwait_flag
;
165 printf("signalled independent task 9_%d, th %d finished....\n", t
, th
);
167 #pragma omp task depend(in: i1, i2)
170 #pragma omp atomic capture
171 lcheck
= ++checker
; // 1 or 2
172 th
= omp_get_thread_num();
173 printf("task 0_%d, th %d, checker %d\n", t
, th
, lcheck
);
174 if (lcheck
> 2 || lcheck
< 1) {
175 err
++; // no more than 2 tasks concurrently
176 printf("Error1, checker %d, not 1 or 2\n", lcheck
);
179 #pragma omp atomic read
180 lcheck
= checker
; // 1 or 2
181 if (lcheck
> 2 || lcheck
< 1) {
184 printf("Error2, checker %d, not 1 or 2\n", lcheck
);
189 #pragma omp task depend(in: i1, i2)
192 #pragma omp atomic capture
193 lcheck
= ++checker
; // 1 or 2
194 th
= omp_get_thread_num();
195 printf("task 1_%d, th %d, checker %d\n", t
, th
, lcheck
);
196 if (lcheck
> 2 || lcheck
< 1) {
197 err
++; // no more than 2 tasks concurrently
198 printf("Error3, checker %d, not 1 or 2\n", lcheck
);
201 #pragma omp atomic read
202 lcheck
= checker
; // 1 or 2
203 if (lcheck
> 2 || lcheck
< 1) {
205 printf("Error4, checker %d, not 1 or 2\n", lcheck
);
210 // compiler codegen start
212 ptr
= __kmpc_omp_task_alloc(&loc
, gtid
, TIED
, sizeof(task_t
), 0, thunk_s
);
213 sdep
[0].addr
= (size_t)&i1
;
214 sdep
[0].len
= 0; // not used
215 sdep
[0].flags
= 1; // IN
216 sdep
[1].addr
= (size_t)&i2
;
217 sdep
[1].len
= 0; // not used
218 sdep
[1].flags
= 8; // INOUTSET
219 ptr
->f_priv
= t
+ 10; // init single first-private variable
220 __kmpc_omp_task_with_deps(&loc
, gtid
, ptr
, 2, sdep
, 0, 0);
223 ptr
= __kmpc_omp_task_alloc(&loc
, gtid
, TIED
, sizeof(task_t
), 0, thunk_m
);
224 sdep
[0].addr
= (size_t)&i1
; // to be ignored
225 sdep
[0].len
= 0; // not used
226 sdep
[0].flags
= 1; // IN
228 sdep
[1].len
= 0; // not used
229 sdep
[1].flags
= DEP_ALL_MEM
; // omp_all_memory
230 ptr
->f_priv
= t
+ 20; // init single first-private variable
231 __kmpc_omp_task_with_deps(&loc
, gtid
, ptr
, 2, sdep
, 0, 0);
232 // compiler codegen end
233 #pragma omp task depend(in: i1, i2)
236 #pragma omp atomic capture
237 lcheck
= ++checker
; // 1 or 2
238 th
= omp_get_thread_num();
239 printf("task 4_%d, th %d, checker %d\n", t
, th
, lcheck
);
240 if (lcheck
> 2 || lcheck
< 1) {
241 err
++; // no more than 2 tasks concurrently
242 printf("Error5, checker %d, not 1 or 2\n", lcheck
);
245 #pragma omp atomic read
246 lcheck
= checker
; // 1 or 2
247 if (lcheck
> 2 || lcheck
< 1) {
249 printf("Error6, checker %d, not 1 or 2\n", lcheck
);
254 #pragma omp task depend(in: i1, i2)
257 #pragma omp atomic capture
258 lcheck
= ++checker
; // 1 or 2
259 th
= omp_get_thread_num();
260 printf("task 5_%d, th %d, checker %d\n", t
, th
, lcheck
);
261 if (lcheck
> 2 || lcheck
< 1) {
262 err
++; // no more than 2 tasks concurrently
263 printf("Error7, checker %d, not 1 or 2\n", lcheck
);
266 #pragma omp atomic read
267 lcheck
= checker
; // 1 or 2
268 if (lcheck
> 2 || lcheck
< 1) {
270 printf("Error8, checker %d, not 1 or 2\n", lcheck
);
275 // compiler codegen start
277 ptr
= __kmpc_omp_task_alloc(&loc
, gtid
, TIED
, sizeof(task_t
), 0, thunk_m
);
278 sdep
[0].addr
= (size_t)(-1); // omp_all_memory
279 sdep
[0].len
= 0; // not used
280 sdep
[0].flags
= 2; // OUT
281 ptr
->f_priv
= t
+ 30; // init single first-private variable
282 __kmpc_omp_task_with_deps(&loc
, gtid
, ptr
, 1, sdep
, 0, 0);
285 ptr
= __kmpc_omp_task_alloc(&loc
, gtid
, TIED
, sizeof(task_t
), 0, thunk_m
);
287 sdep
[0].len
= 0; // not used
288 sdep
[0].flags
= DEP_ALL_MEM
; // omp_all_memory
289 sdep
[1].addr
= (size_t)&i3
; // to be ignored
290 sdep
[1].len
= 0; // not used
291 sdep
[1].flags
= 4; // MUTEXINOUTSET
292 ptr
->f_priv
= t
+ 40; // init single first-private variable
293 __kmpc_omp_task_with_deps(&loc
, gtid
, ptr
, 2, sdep
, 0, 0);
294 // compiler codegen end
295 #pragma omp task depend(in: i3)
298 #pragma omp atomic capture
299 lcheck
= ++checker
; // 1
300 th
= omp_get_thread_num();
301 printf("task 8_%d, th %d, checker %d\n", t
, th
, lcheck
);
304 printf("Error9, checker %d, != 1\n", lcheck
);
307 #pragma omp atomic read
311 printf("Error10, checker %d, != 1\n", lcheck
);
316 mysleep(1); // wait a bit to ensure at least first task is stolen
317 // #pragma omp taskwait depend(omp_all_memory: out)
318 printf("all 10 tasks generated;\n"
319 "taskwait depend(omp_all_memory: out) started, th %d\n", t
);
320 __kmpc_omp_wait_deps(&loc
, gtid
, 1, sdep
, 0, 0);
321 #pragma omp atomic write
323 printf("taskwait depend(omp_all_memory: out) passed, th %d\n", t
);
327 if (err
== 0 && checker
== 0) {
331 printf("failed, err = %d, checker = %d\n", err
, checker
);