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 #include "omp_my_sleep.h" 19 20 int *buf; 21 22 int foo(int n) 23 { 24 int ret = 0; 25 for (int i = 0; i < n; ++i) { 26 omp_event_handle_t event; 27 #pragma omp task detach(event) firstprivate(i,n) shared(ret) 28 { 29 for (int j = 0; j < n; ++j) { 30 #pragma omp task firstprivate(event,i,j,n) shared(ret) default(none) depend(out:ret) 31 { 32 //printf("Task %i, %i: %i\n", i, j, omp_get_thread_num()); 33 my_sleep(.01); 34 #pragma omp atomic 35 ret++; 36 #if _OPENMP 37 if (j == n-1) { 38 //printf("Task %i, %i: omp_fulfill_event()\n", i, j); 39 omp_fulfill_event(event); 40 } 41 #endif 42 } 43 } 44 } 45 } 46 // the taskwait only guarantees the outer tasks to complete. 47 #pragma omp taskwait 48 49 return ret; 50 } 51 52 53 int main() 54 { 55 int ret; 56 #pragma omp parallel num_threads(4) 57 #pragma omp master 58 { 59 ret = foo(8); 60 } 61 printf("%i\n", ret); 62 return !(ret == 64); 63 } 64