1 // RUN: %libomp-compile-and-run
2 // RUN: %libomp-cxx-compile-and-run
5 // Tests OMP 5.0 task dependences "mutexinoutset" and 5.1 "inoutset",
6 // emulates compiler codegen for new dep kinds
7 // Mutually exclusive tasks get same input dependency info array
12 // task2 - task3 (inoutset)
16 // task6 <-->task7 (mutexinoutset)
25 #define mysleep(n) Sleep(n)
28 #define mysleep(n) usleep((n)*1000)
31 // to check the # of concurrent tasks (must be 1 for MTX, <3 for other kinds)
32 static int volatile checker
= 0;
38 // ---------------------------------------------------------------------------
39 // internal data to emulate compiler codegen
55 typedef int(*entry_t
)(int, task_t
*);
63 // thunk routine for tasks with MTX dependency
64 int thunk_m(int gtid
, task_t
* ptask
) {
65 int th
= omp_get_thread_num();
68 printf("task _%d, th %d\n", ptask
->f_priv
, th
);
69 if (checker
!= 1) { // no more than 1 task at a time
71 printf("Error1, checker %d != 1\n", checker
);
74 if (checker
!= 1) { // no more than 1 task at a time
76 printf("Error2, checker %d != 1\n", checker
);
82 // thunk routine for tasks with inoutset dependency
83 int thunk_s(int gtid
, task_t
* ptask
) {
84 int th
= omp_get_thread_num();
87 printf("task _%d, th %d\n", ptask
->f_priv
, th
);
88 if (checker
> 2) { // no more than 2 tasks concurrently
90 printf("Error1, checker %d > 2\n", checker
);
93 if (checker
> 2) { // no more than 2 tasks concurrently
95 printf("Error2, checker %d > 2\n", checker
);
105 int __kmpc_global_thread_num(id
*);
106 extern task_t
* __kmpc_omp_task_alloc(id
*loc
, int gtid
, int flags
,
107 size_t sz
, size_t shar
, entry_t rtn
);
109 __kmpc_omp_task_with_deps(id
*loc
, int gtid
, task_t
*task
, int nd
, dep
*dep_lst
,
110 int nd_noalias
, dep
*noalias_dep_lst
);
111 static id loc
= {0, 2, 0, 0, ";file;func;0;0;;"};
115 // End of internal data
116 // ---------------------------------------------------------------------------
121 omp_set_num_threads(4);
125 #pragma omp single nowait
129 int gtid
= __kmpc_global_thread_num(&loc
);
130 int t
= omp_get_thread_num();
131 #pragma omp task depend(in: i1, i2)
132 { int th
= omp_get_thread_num();
133 printf("task 0_%d, th %d\n", t
, th
);
136 if (checker
> 2) { // no more than 2 tasks concurrently
138 printf("Error1, checker %d > 2\n", checker
);
141 if (checker
> 2) { // no more than 2 tasks concurrently
143 printf("Error1, checker %d > 2\n", checker
);
148 #pragma omp task depend(in: i1, i2)
149 { int th
= omp_get_thread_num();
150 printf("task 1_%d, th %d\n", t
, th
);
153 if (checker
> 2) { // no more than 2 tasks concurrently
155 printf("Error1, checker %d > 2\n", checker
);
158 if (checker
> 2) { // no more than 2 tasks concurrently
160 printf("Error1, checker %d > 2\n", checker
);
165 // compiler codegen start
167 ptr
= __kmpc_omp_task_alloc(&loc
, gtid
, TIED
, sizeof(task_t
), 0, thunk_s
);
168 sdep
[0].addr
= (size_t)&i1
;
169 sdep
[0].len
= 0; // not used
170 sdep
[0].flags
= 1; // IN
171 sdep
[1].addr
= (size_t)&i2
;
172 sdep
[1].len
= 0; // not used
173 sdep
[1].flags
= 8; // INOUTSET
174 ptr
->f_priv
= t
+ 10; // init single first-private variable
175 __kmpc_omp_task_with_deps(&loc
, gtid
, ptr
, 2, sdep
, 0, 0);
178 ptr
= __kmpc_omp_task_alloc(&loc
, gtid
, TIED
, sizeof(task_t
), 0, thunk_s
);
179 ptr
->f_priv
= t
+ 20; // init single first-private variable
180 __kmpc_omp_task_with_deps(&loc
, gtid
, ptr
, 2, sdep
, 0, 0);
181 // compiler codegen end
182 t
= omp_get_thread_num();
183 #pragma omp task depend(in: i1, i2)
184 { int th
= omp_get_thread_num();
185 printf("task 4_%d, th %d\n", t
, th
);
188 if (checker
> 2) { // no more than 2 tasks concurrently
190 printf("Error1, checker %d > 2\n", checker
);
193 if (checker
> 2) { // no more than 2 tasks concurrently
195 printf("Error1, checker %d > 2\n", checker
);
200 #pragma omp task depend(in: i1, i2)
201 { int th
= omp_get_thread_num();
202 printf("task 5_%d, th %d\n", t
, th
);
205 if (checker
> 2) { // no more than 2 tasks concurrently
207 printf("Error1, checker %d > 2\n", checker
);
210 if (checker
> 2) { // no more than 2 tasks concurrently
212 printf("Error1, checker %d > 2\n", checker
);
217 // compiler codegen start
219 ptr
= __kmpc_omp_task_alloc(&loc
, gtid
, TIED
, sizeof(task_t
), 0, thunk_m
);
220 sdep
[0].addr
= (size_t)&i1
;
221 sdep
[0].len
= 0; // not used
222 sdep
[0].flags
= 4; // MUTEXINOUTSET
223 sdep
[1].addr
= (size_t)&i3
;
224 sdep
[1].len
= 0; // not used
225 sdep
[1].flags
= 4; // MUTEXINOUTSET
226 ptr
->f_priv
= t
+ 30; // init single first-private variable
227 __kmpc_omp_task_with_deps(&loc
, gtid
, ptr
, 2, sdep
, 0, 0);
230 ptr
= __kmpc_omp_task_alloc(&loc
, gtid
, TIED
, sizeof(task_t
), 0, thunk_m
);
231 ptr
->f_priv
= t
+ 40; // init single first-private variable
232 __kmpc_omp_task_with_deps(&loc
, gtid
, ptr
, 2, sdep
, 0, 0);
233 // compiler codegen end
234 #pragma omp task depend(in: i3)
235 { int th
= omp_get_thread_num();
236 printf("task 8_%d, th %d\n", t
, th
);
239 if (checker
!= 1) { // last task should run exclusively
241 printf("Error1, checker %d != 1\n", checker
); }
243 if (checker
!= 1) { // last task should run exclusively
245 printf("Error1, checker %d != 1\n", checker
); }