LLVM OpenMP 22.0.0git
omp_task_depend_all.c
Go to the documentation of this file.
1// clang-format off
2// RUN: %libomp-compile-and-run | FileCheck %s
3// REQUIRES: ompt
4
5// The runtime currently does not get dependency information from GCC.
6// UNSUPPORTED: gcc
7
8// Tests OMP 5.x task dependence "omp_all_memory",
9// emulates compiler codegen versions for new dep kind
10//
11// Task tree created:
12// task0 - task1 (in: i1, i2)
13// \
14// task2 (inoutset: i2), (in: i1)
15// /
16// task3 (omp_all_memory) via flag=0x80
17// /
18// task4 - task5 (in: i1, i2)
19// /
20// task6 (omp_all_memory) via addr=-1
21// /
22// task7 (omp_all_memory) via flag=0x80
23// /
24// task8 (in: i3)
25//
26
27// CHECK: ompt_event_dependences:
28// CHECK-SAME: ompt_dependence_type_in
29// CHECK-SAME: ompt_dependence_type_in
30// CHECK-SAME: ndeps=2
31
32// CHECK: ompt_event_dependences:
33// CHECK-SAME: ompt_dependence_type_in
34// CHECK-SAME: ompt_dependence_type_in
35// CHECK-SAME: ndeps=2
36
37// CHECK: ompt_event_dependences:
38// CHECK-SAME: ompt_dependence_type_in
39// CHECK-SAME: ompt_dependence_type_inoutset
40// CHECK-SAME: ndeps=2
41
42// CHECK: ompt_event_dependences:
43// CHECK-SAME: ompt_dependence_type_in
44// CHECK-SAME: ompt_dependence_type_out_all_memory
45// CHECK-SAME: ndeps=2
46
47// CHECK: ompt_event_dependences:
48// CHECK-SAME: ompt_dependence_type_in
49// CHECK-SAME: ompt_dependence_type_in
50// CHECK-SAME: ndeps=2
51
52// CHECK: ompt_event_dependences:
53// CHECK-SAME: ompt_dependence_type_in
54// CHECK-SAME: ompt_dependence_type_in
55// CHECK-SAME: ndeps=2
56
57// CHECK: ompt_event_dependences:
58// CHECK-SAME: ompt_dependence_type_out_all_memory
59// CHECK-SAME: ndeps=1
60
61// CHECK: ompt_event_dependences:
62// CHECK-SAME: ompt_dependence_type_out_all_memory
63// CHECK-SAME: ompt_dependence_type_mutexinoutset
64// CHECK-SAME: ndeps=2
65
66// CHECK: ompt_event_dependences:
67// CHECK-SAME: ompt_dependence_type_in
68// CHECK-SAME: ndeps=1
69// clang-format on
70
71#include "callback.h"
72#include <stdio.h>
73#include <omp.h>
74
75#ifdef _WIN32
76#include <windows.h>
77#define mysleep(n) Sleep(n)
78#else
79#include <unistd.h>
80#define mysleep(n) usleep((n)*1000)
81#endif
82
83// to check the # of concurrent tasks (must be 1 for MTX, <3 for other kinds)
84static int checker = 0;
85static int err = 0;
86#ifndef DELAY
87#define DELAY 100
88#endif
89
90// ---------------------------------------------------------------------------
91// internal data to emulate compiler codegen
92typedef struct DEP {
93 size_t addr;
94 size_t len;
95 unsigned char flags;
97#define DEP_ALL_MEM 0x80
98typedef struct task {
99 void **shareds;
100 void *entry;
101 int part_id;
102 void *destr_thunk;
103 int priority;
104 long long device_id;
105 int f_priv;
107#define TIED 1
108typedef int (*entry_t)(int, task_t *);
109typedef struct ID {
110 int reserved_1;
111 int flags;
112 int reserved_2;
113 int reserved_3;
114 char *psource;
116// thunk routine for tasks with ALL dependency
117int thunk_m(int gtid, task_t *ptask) {
118 int lcheck, th;
119#pragma omp atomic capture
120 lcheck = ++checker;
121 th = omp_get_thread_num();
122 printf("task m_%d, th %d, checker %d\n", ptask->f_priv, th, lcheck);
123 if (lcheck != 1) { // no more than 1 task at a time
124 err++;
125 printf("Error m1, checker %d != 1\n", lcheck);
126 }
127 mysleep(DELAY);
128#pragma omp atomic read
129 lcheck = checker; // must still be equal to 1
130 if (lcheck != 1) {
131 err++;
132 printf("Error m2, checker %d != 1\n", lcheck);
133 }
134#pragma omp atomic
135 --checker;
136 return 0;
137}
138// thunk routine for tasks with inoutset dependency
139int thunk_s(int gtid, task_t *ptask) {
140 int lcheck, th;
141#pragma omp atomic capture
142 lcheck = ++checker; // 1
143 th = omp_get_thread_num();
144 printf("task 2_%d, th %d, checker %d\n", ptask->f_priv, th, lcheck);
145 if (lcheck != 1) { // no more than 1 task at a time
146 err++;
147 printf("Error s1, checker %d != 1\n", lcheck);
148 }
149 mysleep(DELAY);
150#pragma omp atomic read
151 lcheck = checker; // must still be equal to 1
152 if (lcheck != 1) {
153 err++;
154 printf("Error s2, checker %d != 1\n", lcheck);
155 }
156#pragma omp atomic
157 --checker;
158 return 0;
159}
160
161#ifdef __cplusplus
162extern "C" {
163#endif
165task_t *__kmpc_omp_task_alloc(id *loc, int gtid, int flags, size_t sz,
166 size_t shar, entry_t rtn);
167int __kmpc_omp_task_with_deps(id *loc, int gtid, task_t *task, int ndeps,
168 dep *dep_lst, int nd_noalias, dep *noalias_lst);
169static id loc = {0, 2, 0, 0, ";file;func;0;0;;"};
170#ifdef __cplusplus
171} // extern "C"
172#endif
173// End of internal data
174// ---------------------------------------------------------------------------
175
176int main() {
177 char *ompx_all_memory = (void *)0xffffffffffffffff;
178 int i1, i2, i3;
181#pragma omp parallel
182 {
183#pragma omp single nowait
184 {
185 dep sdep[2];
186 task_t *ptr;
187 int gtid = __kmpc_global_thread_num(&loc);
188 int t = omp_get_thread_num();
189#pragma omp task depend(in : i1, i2)
190 { // task 0
191 int lcheck, th;
192#pragma omp atomic capture
193 lcheck = ++checker; // 1 or 2
194 th = omp_get_thread_num();
195 printf("task 0_%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("Error1, checker %d, not 1 or 2\n", lcheck);
199 }
200 mysleep(DELAY);
201#pragma omp atomic read
202 lcheck = checker; // 1 or 2
203 if (lcheck > 2 || lcheck < 1) {
204#pragma omp atomic
205 err++;
206 printf("Error2, checker %d, not 1 or 2\n", lcheck);
207 }
208#pragma omp atomic
209 --checker;
210 }
211#pragma omp task depend(in : i1, i2)
212 { // task 1
213 int lcheck, th;
214#pragma omp atomic capture
215 lcheck = ++checker; // 1 or 2
216 th = omp_get_thread_num();
217 printf("task 1_%d, th %d, checker %d\n", t, th, lcheck);
218 if (lcheck > 2 || lcheck < 1) {
219 err++; // no more than 2 tasks concurrently
220 printf("Error3, checker %d, not 1 or 2\n", lcheck);
221 }
222 mysleep(DELAY);
223#pragma omp atomic read
224 lcheck = checker; // 1 or 2
225 if (lcheck > 2 || lcheck < 1) {
226 err++;
227 printf("Error4, checker %d, not 1 or 2\n", lcheck);
228 }
229#pragma omp atomic
230 --checker;
231 }
232 // compiler codegen start
233 // task2
234 ptr = __kmpc_omp_task_alloc(&loc, gtid, TIED, sizeof(task_t), 0, thunk_s);
235 sdep[0].addr = (size_t)&i1;
236 sdep[0].len = 0; // not used
237 sdep[0].flags = 1; // IN
238 sdep[1].addr = (size_t)&i2;
239 sdep[1].len = 0; // not used
240 sdep[1].flags = 8; // INOUTSET
241 ptr->f_priv = t + 10; // init single first-private variable
242 __kmpc_omp_task_with_deps(&loc, gtid, ptr, 2, sdep, 0, 0);
243
244// task3
245#pragma omp task depend(in : i1) depend(inout : ompx_all_memory[0])
246 {
247 int lcheck, th;
248#pragma omp atomic capture
249 lcheck = ++checker;
250 th = omp_get_thread_num();
251 printf("task m_%d, th %d, checker %d\n", t, th, lcheck);
252 if (lcheck != 1) { // no more than 1 task at a time
253 err++;
254 printf("Error m1, checker %d != 1\n", lcheck);
255 }
256 mysleep(DELAY);
257#pragma omp atomic read
258 lcheck = checker; // must still be equal to 1
259 if (lcheck != 1) {
260 err++;
261 printf("Error m2, checker %d != 1\n", lcheck);
262 }
263#pragma omp atomic
264 --checker;
265 }
266 // compiler codegen end
267#pragma omp task depend(in : i1, i2)
268 { // task 4
269 int lcheck, th;
270#pragma omp atomic capture
271 lcheck = ++checker; // 1 or 2
272 th = omp_get_thread_num();
273 printf("task 4_%d, th %d, checker %d\n", t, th, lcheck);
274 if (lcheck > 2 || lcheck < 1) {
275 err++; // no more than 2 tasks concurrently
276 printf("Error5, checker %d, not 1 or 2\n", lcheck);
277 }
278 mysleep(DELAY);
279#pragma omp atomic read
280 lcheck = checker; // 1 or 2
281 if (lcheck > 2 || lcheck < 1) {
282 err++;
283 printf("Error6, checker %d, not 1 or 2\n", lcheck);
284 }
285#pragma omp atomic
286 --checker;
287 }
288#pragma omp task depend(in : i1, i2)
289 { // task 5
290 int lcheck, th;
291#pragma omp atomic capture
292 lcheck = ++checker; // 1 or 2
293 th = omp_get_thread_num();
294 printf("task 5_%d, th %d, checker %d\n", t, th, lcheck);
295 if (lcheck > 2 || lcheck < 1) {
296 err++; // no more than 2 tasks concurrently
297 printf("Error7, checker %d, not 1 or 2\n", lcheck);
298 }
299 mysleep(DELAY);
300#pragma omp atomic read
301 lcheck = checker; // 1 or 2
302 if (lcheck > 2 || lcheck < 1) {
303 err++;
304 printf("Error8, checker %d, not 1 or 2\n", lcheck);
305 }
306#pragma omp atomic
307 --checker;
308 }
309// task6
310#pragma omp task depend(inout : ompx_all_memory[0])
311 {
312 int lcheck, th;
313#pragma omp atomic capture
314 lcheck = ++checker;
315 th = omp_get_thread_num();
316 printf("task m_%d, th %d, checker %d\n", t, th, lcheck);
317 if (lcheck != 1) { // no more than 1 task at a time
318 err++;
319 printf("Error m1, checker %d != 1\n", lcheck);
320 }
321 mysleep(DELAY);
322#pragma omp atomic read
323 lcheck = checker; // must still be equal to 1
324 if (lcheck != 1) {
325 err++;
326 printf("Error m2, checker %d != 1\n", lcheck);
327 }
328#pragma omp atomic
329 --checker;
330 }
331// task7
332#pragma omp task depend(inout : ompx_all_memory[0]) depend(mutexinoutset : i3)
333 {
334 int lcheck, th;
335#pragma omp atomic capture
336 lcheck = ++checker;
337 th = omp_get_thread_num();
338 printf("task m_%d, th %d, checker %d\n", t, th, lcheck);
339 if (lcheck != 1) { // no more than 1 task at a time
340 err++;
341 printf("Error m1, checker %d != 1\n", lcheck);
342 }
343 mysleep(DELAY);
344#pragma omp atomic read
345 lcheck = checker; // must still be equal to 1
346 if (lcheck != 1) {
347 err++;
348 printf("Error m2, checker %d != 1\n", lcheck);
349 }
350#pragma omp atomic
351 --checker;
352 }
353#pragma omp task depend(in : i3)
354 { // task 8
355 int lcheck, th;
356#pragma omp atomic capture
357 lcheck = ++checker; // 1
358 th = omp_get_thread_num();
359 printf("task 8_%d, th %d, checker %d\n", t, th, lcheck);
360 if (lcheck != 1) {
361 err++;
362 printf("Error9, checker %d, != 1\n", lcheck);
363 }
364 mysleep(DELAY);
365#pragma omp atomic read
366 lcheck = checker;
367 if (lcheck != 1) {
368 err++;
369 printf("Error10, checker %d, != 1\n", lcheck);
370 }
371#pragma omp atomic
372 --checker;
373 }
374 } // single
375 } // parallel
376 if (err == 0 && checker == 0) {
377 printf("passed\n");
378 return 0;
379 } else {
380 printf("failed, err = %d, checker = %d\n", err, checker);
381 return 1;
382 }
383}
void const char const char int ITT_FORMAT __itt_group_sync x void const char ITT_FORMAT __itt_group_sync s void ITT_FORMAT __itt_group_sync p void ITT_FORMAT p void ITT_FORMAT p no args __itt_suppress_mode_t unsigned int void size_t ITT_FORMAT d void ITT_FORMAT p void ITT_FORMAT p __itt_model_site __itt_model_site_instance ITT_FORMAT p __itt_model_task __itt_model_task_instance ITT_FORMAT p void ITT_FORMAT p void ITT_FORMAT p void size_t ITT_FORMAT d void ITT_FORMAT p const wchar_t ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s no args void ITT_FORMAT p size_t ITT_FORMAT d no args const wchar_t const wchar_t ITT_FORMAT s __itt_heap_function void size_t int ITT_FORMAT d __itt_heap_function void ITT_FORMAT p __itt_heap_function void void size_t int ITT_FORMAT d no args no args unsigned int ITT_FORMAT u const __itt_domain __itt_id ITT_FORMAT lu const __itt_domain __itt_id __itt_id __itt_string_handle ITT_FORMAT p const __itt_domain __itt_id ITT_FORMAT p const __itt_domain __itt_id __itt_timestamp __itt_timestamp ITT_FORMAT lu const __itt_domain __itt_id __itt_id __itt_string_handle ITT_FORMAT p const __itt_domain ITT_FORMAT p const __itt_domain __itt_string_handle unsigned long long ITT_FORMAT lu const __itt_domain __itt_string_handle unsigned long long ITT_FORMAT lu const __itt_domain __itt_id __itt_string_handle __itt_metadata_type size_t void ITT_FORMAT p const __itt_domain __itt_id __itt_string_handle const wchar_t size_t ITT_FORMAT lu const __itt_domain __itt_id __itt_relation __itt_id ITT_FORMAT p const wchar_t int ITT_FORMAT __itt_group_mark d int
#define omp_set_num_threads
Definition: kmp_stub.cpp:34
#define omp_set_dynamic
Definition: kmp_stub.cpp:35
#define mysleep(n)
struct ID id
int thunk_s(int gtid, task_t *ptask)
struct DEP dep
#define DELAY
static int err
int(* entry_t)(int, task_t *)
int thunk_m(int gtid, task_t *ptask)
static id loc
int __kmpc_omp_task_with_deps(id *loc, int gtid, task_t *task, int ndeps, dep *dep_lst, int nd_noalias, dep *noalias_lst)
task_t * __kmpc_omp_task_alloc(id *loc, int gtid, int flags, size_t sz, size_t shar, entry_t rtn)
static int checker
int __kmpc_global_thread_num(id *)
#define TIED
struct task task_t
int main()
size_t len
unsigned char flags
size_t addr
int reserved_2
char * psource
int reserved_3
int reserved_1
void * entry
void ** shareds
void * destr_thunk
long long device_id