1 // RUN: %libomp-compile-and-run 2 3 // Checked gcc 10.1 still does not support detach clause on task construct. 4 // UNSUPPORTED: gcc-4, gcc-5, gcc-6, gcc-7, gcc-8, gcc-9, gcc-10 5 // gcc 11 introduced detach clause, but gomp interface in libomp has no support 6 // XFAIL: gcc-11, gcc-12 7 // clang supports detach clause since version 11. 8 // UNSUPPORTED: clang-10, clang-9, clang-8, clang-7 9 // icc compiler does not support detach clause. 10 // UNSUPPORTED: icc 11 12 // The outer detachable task creates multiple child tasks with dependencies 13 // when the last inner task incremented ret, the task calls omp_fulfill_event 14 // to release the outer task. 15 16 #include <omp.h> 17 #include <stdio.h> 18 19 int *buf; 20 21 int foo(int n) 22 { 23 int ret = 0; 24 for (int i = 0; i < n; ++i) { 25 omp_event_handle_t event; 26 #pragma omp task detach(event) firstprivate(i,n) shared(ret) default(none) 27 { 28 for (int j = 0; j < n; ++j) { 29 #pragma omp task firstprivate(event,i,j,n) shared(ret) default(none) depend(out:ret) 30 { 31 //printf("Task %i, %i: %i\n", i, j, omp_get_thread_num()); 32 #pragma omp atomic 33 ret++; 34 #if _OPENMP 35 if (j == n-1) { 36 //printf("Task %i, %i: omp_fulfill_event()\n", i, j); 37 omp_fulfill_event(event); 38 } 39 #endif 40 } 41 } 42 } 43 } 44 // the taskwait only guarantees the outer tasks to complete. 45 #pragma omp taskwait 46 47 return ret; 48 } 49 50 51 int main() 52 { 53 int ret; 54 #pragma omp parallel 55 #pragma omp master 56 { 57 ret = foo(8); 58 } 59 printf("%i\n", ret); 60 //CHECK: 64 61 return 0; 62 } 63