[llvm] Stop including unordered_map (NFC)
[llvm-project.git] / openmp / runtime / test / tasking / omp51_task_dep_inoutset.c
bloba7787ff3da53aca88aa0cfb3393591da9070cae8
1 // RUN: %libomp-compile-and-run
2 // RUN: %libomp-cxx-compile-and-run
3 // UNSUPPORTED: gcc
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
8 //
9 // Task tree created:
10 // task0 - task1 (in)
11 // \
12 // task2 - task3 (inoutset)
13 // /
14 // task3 - task4 (in)
15 // /
16 // task6 <-->task7 (mutexinoutset)
17 // \ /
18 // task8 (in)
20 #include <stdio.h>
21 #include <omp.h>
23 #ifdef _WIN32
24 #include <windows.h>
25 #define mysleep(n) Sleep(n)
26 #else
27 #include <unistd.h>
28 #define mysleep(n) usleep((n)*1000)
29 #endif
31 // to check the # of concurrent tasks (must be 1 for MTX, <3 for other kinds)
32 static int volatile checker = 0;
33 static int err = 0;
34 #ifndef DELAY
35 #define DELAY 100
36 #endif
38 // ---------------------------------------------------------------------------
39 // internal data to emulate compiler codegen
40 typedef struct DEP {
41 size_t addr;
42 size_t len;
43 unsigned char flags;
44 } dep;
45 typedef struct task {
46 void** shareds;
47 void* entry;
48 int part_id;
49 void* destr_thunk;
50 int priority;
51 long long device_id;
52 int f_priv;
53 } task_t;
54 #define TIED 1
55 typedef int(*entry_t)(int, task_t*);
56 typedef struct ID {
57 int reserved_1;
58 int flags;
59 int reserved_2;
60 int reserved_3;
61 char *psource;
62 } id;
63 // thunk routine for tasks with MTX dependency
64 int thunk_m(int gtid, task_t* ptask) {
65 int th = omp_get_thread_num();
66 #pragma omp atomic
67 ++checker;
68 printf("task _%d, th %d\n", ptask->f_priv, th);
69 if (checker != 1) { // no more than 1 task at a time
70 err++;
71 printf("Error1, checker %d != 1\n", checker);
73 mysleep(DELAY);
74 if (checker != 1) { // no more than 1 task at a time
75 err++;
76 printf("Error2, checker %d != 1\n", checker);
78 #pragma omp atomic
79 --checker;
80 return 0;
82 // thunk routine for tasks with inoutset dependency
83 int thunk_s(int gtid, task_t* ptask) {
84 int th = omp_get_thread_num();
85 #pragma omp atomic
86 ++checker;
87 printf("task _%d, th %d\n", ptask->f_priv, th);
88 if (checker > 2) { // no more than 2 tasks concurrently
89 err++;
90 printf("Error1, checker %d > 2\n", checker);
92 mysleep(DELAY);
93 if (checker > 2) { // no more than 2 tasks concurrently
94 err++;
95 printf("Error2, checker %d > 2\n", checker);
97 #pragma omp atomic
98 --checker;
99 return 0;
102 #ifdef __cplusplus
103 extern "C" {
104 #endif
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;;"};
112 #ifdef __cplusplus
113 } // extern "C"
114 #endif
115 // End of internal data
116 // ---------------------------------------------------------------------------
118 int main()
120 int i1,i2,i3;
121 omp_set_num_threads(4);
122 omp_set_dynamic(0);
123 #pragma omp parallel
125 #pragma omp single nowait
127 dep sdep[2];
128 task_t *ptr;
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);
134 #pragma omp atomic
135 ++checker;
136 if (checker > 2) { // no more than 2 tasks concurrently
137 err++;
138 printf("Error1, checker %d > 2\n", checker);
140 mysleep(DELAY);
141 if (checker > 2) { // no more than 2 tasks concurrently
142 err++;
143 printf("Error1, checker %d > 2\n", checker);
145 #pragma omp atomic
146 --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);
151 #pragma omp atomic
152 ++checker;
153 if (checker > 2) { // no more than 2 tasks concurrently
154 err++;
155 printf("Error1, checker %d > 2\n", checker);
157 mysleep(DELAY);
158 if (checker > 2) { // no more than 2 tasks concurrently
159 err++;
160 printf("Error1, checker %d > 2\n", checker);
162 #pragma omp atomic
163 --checker;
165 // compiler codegen start
166 // task2
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);
177 // task3
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);
186 #pragma omp atomic
187 ++checker;
188 if (checker > 2) { // no more than 2 tasks concurrently
189 err++;
190 printf("Error1, checker %d > 2\n", checker);
192 mysleep(DELAY);
193 if (checker > 2) { // no more than 2 tasks concurrently
194 err++;
195 printf("Error1, checker %d > 2\n", checker);
197 #pragma omp atomic
198 --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);
203 #pragma omp atomic
204 ++checker;
205 if (checker > 2) { // no more than 2 tasks concurrently
206 err++;
207 printf("Error1, checker %d > 2\n", checker);
209 mysleep(DELAY);
210 if (checker > 2) { // no more than 2 tasks concurrently
211 err++;
212 printf("Error1, checker %d > 2\n", checker);
214 #pragma omp atomic
215 --checker;
217 // compiler codegen start
218 // task6
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);
229 // task7
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);
237 #pragma omp atomic
238 ++checker;
239 if (checker != 1) { // last task should run exclusively
240 err++;
241 printf("Error1, checker %d != 1\n", checker); }
242 mysleep(DELAY);
243 if (checker != 1) { // last task should run exclusively
244 err++;
245 printf("Error1, checker %d != 1\n", checker); }
246 #pragma omp atomic
247 --checker;
249 } // single
250 } // parallel
251 if (err == 0) {
252 printf("passed\n");
253 return 0;
254 } else {
255 printf("failed\n");
256 return 1;