xref: /llvm-project/openmp/runtime/test/tasking/omp_record_replay_multiTDGs.cpp (revision 36d4e4c9b5f6cd0577b6029055b825caaec2dd11)
1 // REQUIRES: ompx_taskgraph
2 // RUN: %libomp-cxx-compile-and-run
3 #include <iostream>
4 #include <cassert>
5 #define NT 20
6 #define MULTIPLIER 100
7 #define DECREMENT 5
8 
9 // Compiler-generated code (emulation)
10 typedef struct ident {
11     void* dummy;
12 } ident_t;
13 
14 int val;
15 #ifdef __cplusplus
16 extern "C" {
17   int __kmpc_global_thread_num(ident_t *);
18   int __kmpc_start_record_task(ident_t *, int, int, int);
19   void __kmpc_end_record_task(ident_t *, int, int , int);
20 }
21 #endif
22 
sub()23 void sub() {
24   #pragma omp atomic
25   val -= DECREMENT;
26 }
27 
add()28 void add() {
29   #pragma omp atomic
30   val += DECREMENT;
31 }
32 
mult()33 void mult() {
34   // no atomicity needed, can only be executed by 1 thread
35   // and no concurrency with other tasks possible
36   val *= MULTIPLIER;
37 }
38 
main()39 int main() {
40   int num_tasks = 0;
41   int *x, *y;
42   #pragma omp parallel
43   #pragma omp single
44   for (int iter = 0; iter < NT; ++iter) {
45     int gtid = __kmpc_global_thread_num(nullptr);
46     int res =  __kmpc_start_record_task(nullptr, gtid, /* kmp_tdg_flags */ 0, /* tdg_id */0);
47     if (res) {
48       num_tasks++;
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     res =  __kmpc_start_record_task(nullptr, gtid, /* kmp_tdg_flags */ 0, /* tdg_id */1);
58     if (res) {
59       num_tasks++;
60       #pragma omp task depend(out:y)
61       add();
62       #pragma omp task depend(out:x)
63       sub();
64       #pragma omp task depend(in:x,y)
65       mult();
66     }
67     __kmpc_end_record_task(nullptr, gtid, /* kmp_tdg_flags */0, /* tdg_id */1);
68   }
69 
70   assert(num_tasks==2);
71   assert(val==0);
72 
73   std::cout << "Passed" << std::endl;
74   return 0;
75 }
76 // CHECK: Passed
77