1// REQUIRES: ompx_taskgraph
2// RUN: %libomp-cxx-compile-and-run
3#include <iostream>
4#include <cassert>
5#define NT 100
6#define MULTIPLIER 100
7#define DECREMENT 5
8
9int val;
10// Compiler-generated code (emulation)
11typedef struct ident {
12 void* dummy;
13} ident_t;
14
15
16#ifdef __cplusplus
17extern "C" {
18 int __kmpc_global_thread_num(ident_t *);
19 int __kmpc_start_record_task(ident_t *, int, int, int);
20 void __kmpc_end_record_task(ident_t *, int, int, int);
21}
22#endif
23
24void sub() {
25 #pragma omp atomic
26 val -= DECREMENT;
27}
28
29void add() {
30 #pragma omp atomic
31 val += DECREMENT;
32}
33
34void mult() {
35 // no atomicity needed, can only be executed by 1 thread
36 // and no concurrency with other tasks possible
37 val *= MULTIPLIER;
38}
39
40int main() {
41 val = 0;
42 int *x, *y;
43 #pragma omp parallel
44 #pragma omp single
45 for (int iter = 0; iter < NT; ++iter) {
46 int gtid = __kmpc_global_thread_num(nullptr);
47 int res = __kmpc_start_record_task(nullptr, gtid, /* kmp_tdg_flags */0, /* tdg_id */0);
48 if (res) {
49 #pragma omp task depend(out:y)
50 add();
51 #pragma omp task depend(out:x)
52 sub();
53 #pragma omp task depend(in:x,y)
54 mult();
55 }
56 __kmpc_end_record_task(nullptr, gtid, /* kmp_tdg_flags */0, /* tdg_id */0);
57 }
58 assert(val==0);
59
60 std::cout << "Passed" << std::endl;
61 return 0;
62}
63// CHECK: Passed
64

source code of openmp/runtime/test/tasking/omp_record_replay_deps.cpp