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
28 #define mysleep(n) Sleep(n)
31 #define mysleep(n) usleep((n)*1000)
34 // to check the # of concurrent tasks (must be 1 for MTX, <3 for other kinds)
35 static int checker
= 0;
41 // ---------------------------------------------------------------------------
42 // internal data to emulate compiler codegen
48 #define DEP_ALL_MEM 0x80
59 typedef int(*entry_t
)(int, task_t
*);
67 // thunk routine for tasks with ALL dependency
68 int thunk_m(int gtid
, task_t
* ptask
) {
70 #pragma omp atomic capture
72 th
= omp_get_thread_num();
73 printf("task m_%d, th %d, checker %d\n", ptask
->f_priv
, th
, lcheck
);
74 if (lcheck
!= 1) { // no more than 1 task at a time
76 printf("Error m1, checker %d != 1\n", lcheck
);
79 #pragma omp atomic read
80 lcheck
= checker
; // must still be equal to 1
83 printf("Error m2, checker %d != 1\n", lcheck
);
89 // thunk routine for tasks with inoutset dependency
90 int thunk_s(int gtid
, task_t
* ptask
) {
92 #pragma omp atomic capture
93 lcheck
= ++checker
; // 1
94 th
= omp_get_thread_num();
95 printf("task 2_%d, th %d, checker %d\n", ptask
->f_priv
, th
, lcheck
);
96 if (lcheck
!= 1) { // no more than 1 task at a time
98 printf("Error s1, checker %d != 1\n", lcheck
);
101 #pragma omp atomic read
102 lcheck
= checker
; // must still be equal to 1
105 printf("Error s2, checker %d != 1\n", lcheck
);
115 int __kmpc_global_thread_num(id
*);
116 task_t
*__kmpc_omp_task_alloc(id
*loc
, int gtid
, int flags
,
117 size_t sz
, size_t shar
, entry_t rtn
);
118 int __kmpc_omp_task_with_deps(id
*loc
, int gtid
, task_t
*task
, int ndeps
,
119 dep
*dep_lst
, int nd_noalias
, dep
*noalias_lst
);
120 static id loc
= {0, 2, 0, 0, ";file;func;0;0;;"};
124 // End of internal data
125 // ---------------------------------------------------------------------------
130 omp_set_num_threads(8);
134 #pragma omp single nowait
138 int gtid
= __kmpc_global_thread_num(&loc
);
139 int t
= omp_get_thread_num();
140 #pragma omp task depend(in: i1, i2)
143 #pragma omp atomic capture
144 lcheck
= ++checker
; // 1 or 2
145 th
= omp_get_thread_num();
146 printf("task 0_%d, th %d, checker %d\n", t
, th
, lcheck
);
147 if (lcheck
> 2 || lcheck
< 1) {
148 err
++; // no more than 2 tasks concurrently
149 printf("Error1, checker %d, not 1 or 2\n", lcheck
);
152 #pragma omp atomic read
153 lcheck
= checker
; // 1 or 2
154 if (lcheck
> 2 || lcheck
< 1) {
157 printf("Error2, checker %d, not 1 or 2\n", lcheck
);
162 #pragma omp task depend(in: i1, i2)
165 #pragma omp atomic capture
166 lcheck
= ++checker
; // 1 or 2
167 th
= omp_get_thread_num();
168 printf("task 1_%d, th %d, checker %d\n", t
, th
, lcheck
);
169 if (lcheck
> 2 || lcheck
< 1) {
170 err
++; // no more than 2 tasks concurrently
171 printf("Error3, checker %d, not 1 or 2\n", lcheck
);
174 #pragma omp atomic read
175 lcheck
= checker
; // 1 or 2
176 if (lcheck
> 2 || lcheck
< 1) {
178 printf("Error4, checker %d, not 1 or 2\n", lcheck
);
183 // compiler codegen start
185 ptr
= __kmpc_omp_task_alloc(&loc
, gtid
, TIED
, sizeof(task_t
), 0, thunk_s
);
186 sdep
[0].addr
= (size_t)&i1
;
187 sdep
[0].len
= 0; // not used
188 sdep
[0].flags
= 1; // IN
189 sdep
[1].addr
= (size_t)&i2
;
190 sdep
[1].len
= 0; // not used
191 sdep
[1].flags
= 8; // INOUTSET
192 ptr
->f_priv
= t
+ 10; // init single first-private variable
193 __kmpc_omp_task_with_deps(&loc
, gtid
, ptr
, 2, sdep
, 0, 0);
196 ptr
= __kmpc_omp_task_alloc(&loc
, gtid
, TIED
, sizeof(task_t
), 0, thunk_m
);
197 sdep
[0].addr
= (size_t)&i1
; // to be ignored
198 sdep
[0].len
= 0; // not used
199 sdep
[0].flags
= 1; // IN
201 sdep
[1].len
= 0; // not used
202 sdep
[1].flags
= DEP_ALL_MEM
; // omp_all_memory
203 ptr
->f_priv
= t
+ 20; // init single first-private variable
204 __kmpc_omp_task_with_deps(&loc
, gtid
, ptr
, 2, sdep
, 0, 0);
205 // compiler codegen end
206 #pragma omp task depend(in: i1, i2)
209 #pragma omp atomic capture
210 lcheck
= ++checker
; // 1 or 2
211 th
= omp_get_thread_num();
212 printf("task 4_%d, th %d, checker %d\n", t
, th
, lcheck
);
213 if (lcheck
> 2 || lcheck
< 1) {
214 err
++; // no more than 2 tasks concurrently
215 printf("Error5, checker %d, not 1 or 2\n", lcheck
);
218 #pragma omp atomic read
219 lcheck
= checker
; // 1 or 2
220 if (lcheck
> 2 || lcheck
< 1) {
222 printf("Error6, checker %d, not 1 or 2\n", lcheck
);
227 #pragma omp task depend(in: i1, i2)
230 #pragma omp atomic capture
231 lcheck
= ++checker
; // 1 or 2
232 th
= omp_get_thread_num();
233 printf("task 5_%d, th %d, checker %d\n", t
, th
, lcheck
);
234 if (lcheck
> 2 || lcheck
< 1) {
235 err
++; // no more than 2 tasks concurrently
236 printf("Error7, checker %d, not 1 or 2\n", lcheck
);
239 #pragma omp atomic read
240 lcheck
= checker
; // 1 or 2
241 if (lcheck
> 2 || lcheck
< 1) {
243 printf("Error8, checker %d, not 1 or 2\n", lcheck
);
248 // compiler codegen start
250 ptr
= __kmpc_omp_task_alloc(&loc
, gtid
, TIED
, sizeof(task_t
), 0, thunk_m
);
251 sdep
[0].addr
= (size_t)(-1); // omp_all_memory
252 sdep
[0].len
= 0; // not used
253 sdep
[0].flags
= 2; // OUT
254 ptr
->f_priv
= t
+ 30; // init single first-private variable
255 __kmpc_omp_task_with_deps(&loc
, gtid
, ptr
, 1, sdep
, 0, 0);
258 ptr
= __kmpc_omp_task_alloc(&loc
, gtid
, TIED
, sizeof(task_t
), 0, thunk_m
);
260 sdep
[0].len
= 0; // not used
261 sdep
[0].flags
= DEP_ALL_MEM
; // omp_all_memory
262 sdep
[1].addr
= (size_t)&i3
; // to be ignored
263 sdep
[1].len
= 0; // not used
264 sdep
[1].flags
= 4; // MUTEXINOUTSET
265 ptr
->f_priv
= t
+ 40; // init single first-private variable
266 __kmpc_omp_task_with_deps(&loc
, gtid
, ptr
, 2, sdep
, 0, 0);
267 // compiler codegen end
268 #pragma omp task depend(in: i3)
271 #pragma omp atomic capture
272 lcheck
= ++checker
; // 1
273 th
= omp_get_thread_num();
274 printf("task 8_%d, th %d, checker %d\n", t
, th
, lcheck
);
277 printf("Error9, checker %d, != 1\n", lcheck
);
280 #pragma omp atomic read
284 printf("Error10, checker %d, != 1\n", lcheck
);
291 if (err
== 0 && checker
== 0) {
295 printf("failed, err = %d, checker = %d\n", err
, checker
);