1 // RUN: %libomp-compile-and-run
2 
3 #include <stdio.h>
4 #include <omp.h>
5 
6 int r;
7 
8 int work(int k, int l)
9 {
10   return k + l + 1;
11 }
12 void bar(int i) {
13   #pragma omp taskgroup task_reduction(+:r)
14  { int th_gen = omp_get_thread_num();
15   #pragma omp task in_reduction(+:r) firstprivate(i, th_gen)
16   {
17     r += work(i, 0);
18 printf("executing task (%d, 0), th %d (gen by th %d)\n", i, omp_get_thread_num(), th_gen);
19   }
20   #pragma omp task in_reduction(+:r) firstprivate(i, th_gen)
21   {
22     r += work(i, 1);
23 printf("executing task (%d, 1), th %d (gen by th %d)\n", i, omp_get_thread_num(), th_gen);
24   }
25  }
26 }
27 int foo() {
28   int i;
29   int th_gen = omp_get_thread_num();
30   #pragma omp taskgroup task_reduction(+:r)
31   {
32     bar(0);
33   }
34 printf("th %d passed bar0\n", th_gen);
35   #pragma omp taskloop reduction(+:r) firstprivate(th_gen)
36   for (i = 1; i < 4; ++i) {
37     bar(i);
38 printf("th %d (gen by th %d) passed bar%d in taskloop\n", omp_get_thread_num(), th_gen, i);
39   #pragma omp task in_reduction(+:r)
40     r += i;
41   }
42   return 0;
43 }
44 // res = 2*((1+2)+(2+3)+(3+4)+(4+5)+1+2+3) = 60
45 #define res 60
46 int main()
47 {
48   r = 0;
49   #pragma omp parallel num_threads(2)
50     foo();
51   if (r == res) {
52     return 0;
53   } else {
54     printf("error r = %d (!= %d)\n", r, res);
55     return 1;
56   }
57 }
58