xref: /llvm-project/openmp/runtime/test/tasking/omp_task_red_taskloop.c (revision 4457565757ea91207b7e5f2ce7b7bf173bfd2c0c)
1 // RUN: %libomp-compile-and-run
2 
3 // Parsing error until gcc8:
4 // UNSUPPORTED: gcc-4, gcc-5, gcc-6, gcc-7, gcc-8
5 
6 // Parsing error until clang11:
7 // UNSUPPORTED: clang-10, clang-9, clang-8, clang-7
8 
9 // No icc compiler support yet
10 // XFAIL: icc
11 
12 #include <stdio.h>
13 #include <omp.h>
14 
15 int r;
16 
work(int k,int l)17 int work(int k, int l)
18 {
19   return k + l + 1;
20 }
bar(int i)21 void bar(int i) {
22   #pragma omp taskgroup task_reduction(+:r)
23  { int th_gen = omp_get_thread_num();
24   #pragma omp task in_reduction(+:r) firstprivate(i, th_gen)
25   {
26     r += work(i, 0);
27 printf("executing task (%d, 0), th %d (gen by th %d)\n", i, omp_get_thread_num(), th_gen);
28   }
29   #pragma omp task in_reduction(+:r) firstprivate(i, th_gen)
30   {
31     r += work(i, 1);
32 printf("executing task (%d, 1), th %d (gen by th %d)\n", i, omp_get_thread_num(), th_gen);
33   }
34  }
35 }
foo()36 int foo() {
37   int i;
38   int th_gen = omp_get_thread_num();
39   #pragma omp taskgroup task_reduction(+:r)
40   {
41     bar(0);
42   }
43 printf("th %d passed bar0\n", th_gen);
44   #pragma omp taskloop reduction(+:r) firstprivate(th_gen)
45   for (i = 1; i < 4; ++i) {
46     bar(i);
47 printf("th %d (gen by th %d) passed bar%d in taskloop\n", omp_get_thread_num(), th_gen, i);
48   #pragma omp task in_reduction(+:r)
49     r += i;
50   }
51   return 0;
52 }
53 // res = ((1+2)+(2+3)+(3+4)+(4+5)+1+2+3) = 30
54 #define res 30
main()55 int main()
56 {
57   r = 0;
58   #pragma omp parallel num_threads(2)
59   { // barrier ensures threads have started before tasks creation
60     #pragma omp barrier
61     // single ensures no race condition between taskgroup reductions
62     #pragma omp single nowait
63       foo();
64   }
65   if (r == res) {
66     return 0;
67   } else {
68     printf("error r = %d (!= %d)\n", r, res);
69     return 1;
70   }
71 }
72