xref: /llvm-project/openmp/runtime/test/tasking/omp_record_replay_deps.cpp (revision 36d4e4c9b5f6cd0577b6029055b825caaec2dd11)
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 
9 int val;
10 // Compiler-generated code (emulation)
11 typedef struct ident {
12     void* dummy;
13 } ident_t;
14 
15 
16 #ifdef __cplusplus
17 extern "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 
sub()24 void sub() {
25   #pragma omp atomic
26   val -= DECREMENT;
27 }
28 
add()29 void add() {
30   #pragma omp atomic
31   val += DECREMENT;
32 }
33 
mult()34 void 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 
main()40 int 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