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 17 int work(int k, int l) 18 { 19 return k + l + 1; 20 } 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 } 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 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