LLVM OpenMP 22.0.0git
kmp_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// RUN: %libomp-compile-and-run
6// The runtime currently does not get dependency information from GCC.
7// UNSUPPORTED: gcc
8
9// Tests OMP 5.x task dependence "omp_all_memory",
10// emulates compiler codegen versions for new dep kind
11//
12// Task tree created:
13// task0 - task1 (in: i1, i2)
14// \
15// task2 (inoutset: i2), (in: i1)
16// /
17// task3 (omp_all_memory) via flag=0x80
18// /
19// task4 - task5 (in: i1, i2)
20// /
21// task6 (omp_all_memory) via addr=-1
22// /
23// task7 (omp_all_memory) via flag=0x80
24// /
25// task8 (in: i3)
26//
27
28// CHECK: ompt_event_dependences:
29// CHECK-SAME: ompt_dependence_type_in
30// CHECK-SAME: ompt_dependence_type_in
31// CHECK-SAME: ndeps=2
32
33// CHECK: ompt_event_dependences:
34// CHECK-SAME: ompt_dependence_type_in
35// CHECK-SAME: ompt_dependence_type_in
36// CHECK-SAME: ndeps=2
37
38// CHECK: ompt_event_dependences:
39// CHECK-SAME: ompt_dependence_type_in
40// CHECK-SAME: ompt_dependence_type_inoutset
41// CHECK-SAME: ndeps=2
42
43// CHECK: ompt_event_dependences:
44// CHECK-SAME: ompt_dependence_type_in
45// CHECK-SAME: ompt_dependence_type_out_all_memory
46// CHECK-SAME: ndeps=2
47
48// CHECK: ompt_event_dependences:
49// CHECK-SAME: ompt_dependence_type_in
50// CHECK-SAME: ompt_dependence_type_in
51// CHECK-SAME: ndeps=2
52
53// CHECK: ompt_event_dependences:
54// CHECK-SAME: ompt_dependence_type_in
55// CHECK-SAME: ompt_dependence_type_in
56// CHECK-SAME: ndeps=2
57
58// CHECK: ompt_event_dependences:
59// CHECK-SAME: ompt_dependence_type_out_all_memory
60// CHECK-SAME: ndeps=1
61
62// CHECK: ompt_event_dependences:
63// CHECK-SAME: ompt_dependence_type_out_all_memory
64// CHECK-SAME: ompt_dependence_type_mutexinoutset
65// CHECK-SAME: ndeps=2
66
67// CHECK: ompt_event_dependences:
68// CHECK-SAME: ompt_dependence_type_in
69// CHECK-SAME: ndeps=1
70// clang-format on
71
72#include "callback.h"
73#include <stdio.h>
74#include <omp.h>
75
76#ifdef _WIN32
77#include <windows.h>
78#define mysleep(n) Sleep(n)
79#else
80#include <unistd.h>
81#define mysleep(n) usleep((n)*1000)
82#endif
83
84// to check the # of concurrent tasks (must be 1 for MTX, <3 for other kinds)
85static int checker = 0;
86static int err = 0;
87#ifndef DELAY
88#define DELAY 100
89#endif
90
91// ---------------------------------------------------------------------------
92// internal data to emulate compiler codegen
93typedef struct DEP {
94 size_t addr;
95 size_t len;
96 unsigned char flags;
98#define DEP_ALL_MEM 0x80
99typedef struct task {
100 void **shareds;
101 void *entry;
105 long long device_id;
108#define TIED 1
109typedef int (*entry_t)(int, task_t *);
110typedef struct ID {
112 int flags;
115 char *psource;
116} id;
117// thunk routine for tasks with ALL dependency
118int thunk_m(int gtid, task_t *ptask) {
119 int lcheck, th;
120#pragma omp atomic capture
121 lcheck = ++checker;
122 th = omp_get_thread_num();
123 printf("task m_%d, th %d, checker %d\n", ptask->f_priv, th, lcheck);
124 if (lcheck != 1) { // no more than 1 task at a time
125 err++;
126 printf("Error m1, checker %d != 1\n", lcheck);
127 }
128 mysleep(DELAY);
129#pragma omp atomic read
130 lcheck = checker; // must still be equal to 1
131 if (lcheck != 1) {
132 err++;
133 printf("Error m2, checker %d != 1\n", lcheck);
134 }
135#pragma omp atomic
136 --checker;
137 return 0;
138}
139// thunk routine for tasks with inoutset dependency
140int thunk_s(int gtid, task_t *ptask) {
141 int lcheck, th;
142#pragma omp atomic capture
143 lcheck = ++checker; // 1
144 th = omp_get_thread_num();
145 printf("task 2_%d, th %d, checker %d\n", ptask->f_priv, th, lcheck);
146 if (lcheck != 1) { // no more than 1 task at a time
147 err++;
148 printf("Error s1, checker %d != 1\n", lcheck);
149 }
150 mysleep(DELAY);
151#pragma omp atomic read
152 lcheck = checker; // must still be equal to 1
153 if (lcheck != 1) {
154 err++;
155 printf("Error s2, checker %d != 1\n", lcheck);
156 }
157#pragma omp atomic
158 --checker;
159 return 0;
160}
161
162#ifdef __cplusplus
163extern "C" {
164#endif
166task_t *__kmpc_omp_task_alloc(id *loc, int gtid, int flags, size_t sz,
167 size_t shar, entry_t rtn);
168int __kmpc_omp_task_with_deps(id *loc, int gtid, task_t *task, int ndeps,
169 dep *dep_lst, int nd_noalias, dep *noalias_lst);
170static id loc = {0, 2, 0, 0, ";file;func;0;0;;"};
171#ifdef __cplusplus
172} // extern "C"
173#endif
174// End of internal data
175// ---------------------------------------------------------------------------
176
177int main() {
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 ptr = __kmpc_omp_task_alloc(&loc, gtid, TIED, sizeof(task_t), 0, thunk_m);
246 sdep[0].addr = (size_t)&i1; // to be ignored
247 sdep[0].len = 0; // not used
248 sdep[0].flags = 1; // IN
249 sdep[1].addr = 0;
250 sdep[1].len = 0; // not used
251 sdep[1].flags = DEP_ALL_MEM; // omp_all_memory
252 ptr->f_priv = t + 20; // init single first-private variable
253 __kmpc_omp_task_with_deps(&loc, gtid, ptr, 2, sdep, 0, 0);
254 // compiler codegen end
255#pragma omp task depend(in : i1, i2)
256 { // task 4
257 int lcheck, th;
258#pragma omp atomic capture
259 lcheck = ++checker; // 1 or 2
260 th = omp_get_thread_num();
261 printf("task 4_%d, th %d, checker %d\n", t, th, lcheck);
262 if (lcheck > 2 || lcheck < 1) {
263 err++; // no more than 2 tasks concurrently
264 printf("Error5, checker %d, not 1 or 2\n", lcheck);
265 }
266 mysleep(DELAY);
267#pragma omp atomic read
268 lcheck = checker; // 1 or 2
269 if (lcheck > 2 || lcheck < 1) {
270 err++;
271 printf("Error6, checker %d, not 1 or 2\n", lcheck);
272 }
273#pragma omp atomic
274 --checker;
275 }
276#pragma omp task depend(in : i1, i2)
277 { // task 5
278 int lcheck, th;
279#pragma omp atomic capture
280 lcheck = ++checker; // 1 or 2
281 th = omp_get_thread_num();
282 printf("task 5_%d, th %d, checker %d\n", t, th, lcheck);
283 if (lcheck > 2 || lcheck < 1) {
284 err++; // no more than 2 tasks concurrently
285 printf("Error7, checker %d, not 1 or 2\n", lcheck);
286 }
287 mysleep(DELAY);
288#pragma omp atomic read
289 lcheck = checker; // 1 or 2
290 if (lcheck > 2 || lcheck < 1) {
291 err++;
292 printf("Error8, checker %d, not 1 or 2\n", lcheck);
293 }
294#pragma omp atomic
295 --checker;
296 }
297 // compiler codegen start
298 // task6
299 ptr = __kmpc_omp_task_alloc(&loc, gtid, TIED, sizeof(task_t), 0, thunk_m);
300 sdep[0].addr = (size_t)(-1); // omp_all_memory
301 sdep[0].len = 0; // not used
302 sdep[0].flags = 2; // OUT
303 ptr->f_priv = t + 30; // init single first-private variable
304 __kmpc_omp_task_with_deps(&loc, gtid, ptr, 1, sdep, 0, 0);
305
306 // task7
307 ptr = __kmpc_omp_task_alloc(&loc, gtid, TIED, sizeof(task_t), 0, thunk_m);
308 sdep[0].addr = 0;
309 sdep[0].len = 0; // not used
310 sdep[0].flags = DEP_ALL_MEM; // omp_all_memory
311 sdep[1].addr = (size_t)&i3; // to be ignored
312 sdep[1].len = 0; // not used
313 sdep[1].flags = 4; // MUTEXINOUTSET
314 ptr->f_priv = t + 40; // init single first-private variable
315 __kmpc_omp_task_with_deps(&loc, gtid, ptr, 2, sdep, 0, 0);
316 // compiler codegen end
317#pragma omp task depend(in : i3)
318 { // task 8
319 int lcheck, th;
320#pragma omp atomic capture
321 lcheck = ++checker; // 1
322 th = omp_get_thread_num();
323 printf("task 8_%d, th %d, checker %d\n", t, th, lcheck);
324 if (lcheck != 1) {
325 err++;
326 printf("Error9, checker %d, != 1\n", lcheck);
327 }
328 mysleep(DELAY);
329#pragma omp atomic read
330 lcheck = checker;
331 if (lcheck != 1) {
332 err++;
333 printf("Error10, checker %d, != 1\n", lcheck);
334 }
335#pragma omp atomic
336 --checker;
337 }
338 } // single
339 } // parallel
340 if (err == 0 && checker == 0) {
341 printf("passed\n");
342 return 0;
343 } else {
344 printf("failed, err = %d, checker = %d\n", err, checker);
345 return 1;
346 }
347}
struct task * ptask
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)
int thunk_s(int gtid, task_t *ptask)
struct DEP dep
#define DELAY
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
#define DEP_ALL_MEM
int __kmpc_global_thread_num(id *)
#define TIED
struct task task_t
int main()
unsigned char flags
size_t addr
char * psource
void ** shareds
void * destr_thunk
long long device_id
static int err