diff options
author | Kwok Cheung Yeung <kcy@codesourcery.com> | 2021-01-21 05:38:47 -0800 |
---|---|---|
committer | Kwok Cheung Yeung <kcy@codesourcery.com> | 2021-02-25 14:47:11 -0800 |
commit | d656bfda2d8316627d0bbb18b10954e6aaf3c88c (patch) | |
tree | 9054f33271d1e28f4bb63a203980b5ca35fd7df6 /libgomp/testsuite | |
parent | 7fb9a1e929db520fd741e60d84ec1a58581a8299 (diff) | |
download | gcc-d656bfda2d8316627d0bbb18b10954e6aaf3c88c.zip gcc-d656bfda2d8316627d0bbb18b10954e6aaf3c88c.tar.gz gcc-d656bfda2d8316627d0bbb18b10954e6aaf3c88c.tar.bz2 |
openmp: Fix intermittent hanging of task-detach-6 libgomp tests [PR98738]
This adds support for the task detach clause to taskwait and taskgroup, and
simplifies the handling of the detach clause by moving most of the extra
handling required for detach tasks to omp_fulfill_event.
2021-02-25 Kwok Cheung Yeung <kcy@codesourcery.com>
Jakub Jelinek <jakub@redhat.com>
libgomp/
PR libgomp/98738
* libgomp.h (enum gomp_task_kind): Add GOMP_TASK_DETACHED.
(struct gomp_task): Replace detach and completion_sem fields with
union containing completion_sem and detach_team. Add deferred_p
field.
(struct gomp_team): Remove task_detach_queue.
* task.c: Include assert.h.
(gomp_init_task): Initialize deferred_p and completion_sem fields.
Rearrange initialization order of fields.
(task_fulfilled_p): Delete.
(GOMP_task): Use address of task as the event handle. Remove
initialization of detach field. Initialize deferred_p field.
Use automatic local for completion_sem. Initialize detach_team field
for deferred tasks.
(gomp_barrier_handle_tasks): Remove handling of task_detach_queue.
Set kind of suspended detach task to GOMP_TASK_DETACHED and
decrement task_running_count. Move finish_cancelled block out of
else branch. Relocate call to gomp_team_barrier_done.
(GOMP_taskwait): Handle tasks with completion events that have not
been fulfilled.
(GOMP_taskgroup_end): Likewise.
(omp_fulfill_event): Use address of task as event handle. Post to
completion_sem for undeferred tasks. Clear detach_team if task
has not finished. For finished tasks, handle post-execution tasks,
call gomp_team_barrier_wake if necessary, and free task.
* team.c (gomp_new_team): Remove initialization of task_detach_queue.
(free_team): Remove free of task_detach_queue.
* testsuite/libgomp.c-c++-common/task-detach-1.c: Fix formatting.
* testsuite/libgomp.c-c++-common/task-detach-2.c: Fix formatting.
* testsuite/libgomp.c-c++-common/task-detach-3.c: Fix formatting.
* testsuite/libgomp.c-c++-common/task-detach-4.c: Fix formatting.
* testsuite/libgomp.c-c++-common/task-detach-5.c: Fix formatting.
Change data-sharing of detach events on enclosing parallel to private.
* testsuite/libgomp.c-c++-common/task-detach-6.c: Likewise. Remove
taskwait directive.
* testsuite/libgomp.c-c++-common/task-detach-7.c: New.
* testsuite/libgomp.c-c++-common/task-detach-8.c: New.
* testsuite/libgomp.c-c++-common/task-detach-9.c: New.
* testsuite/libgomp.c-c++-common/task-detach-10.c: New.
* testsuite/libgomp.c-c++-common/task-detach-11.c: New.
* testsuite/libgomp.fortran/task-detach-1.f90: Fix formatting.
* testsuite/libgomp.fortran/task-detach-2.f90: Fix formatting.
* testsuite/libgomp.fortran/task-detach-3.f90: Fix formatting.
* testsuite/libgomp.fortran/task-detach-4.f90: Fix formatting.
* testsuite/libgomp.fortran/task-detach-5.f90: Fix formatting.
Change data-sharing of detach events on enclosing parallel to private.
* testsuite/libgomp.fortran/task-detach-6.f90: Likewise. Remove
taskwait directive.
* testsuite/libgomp.fortran/task-detach-7.f90: New.
* testsuite/libgomp.fortran/task-detach-8.f90: New.
* testsuite/libgomp.fortran/task-detach-9.f90: New.
* testsuite/libgomp.fortran/task-detach-10.f90: New.
* testsuite/libgomp.fortran/task-detach-11.f90: New.
Diffstat (limited to 'libgomp/testsuite')
22 files changed, 416 insertions, 42 deletions
diff --git a/libgomp/testsuite/libgomp.c-c++-common/task-detach-1.c b/libgomp/testsuite/libgomp.c-c++-common/task-detach-1.c index 8583e37..14932b0 100644 --- a/libgomp/testsuite/libgomp.c-c++-common/task-detach-1.c +++ b/libgomp/testsuite/libgomp.c-c++-common/task-detach-1.c @@ -14,10 +14,10 @@ int main (void) #pragma omp parallel #pragma omp single { - #pragma omp task detach(detach_event1) + #pragma omp task detach (detach_event1) x++; - #pragma omp task detach(detach_event2) + #pragma omp task detach (detach_event2) { y++; omp_fulfill_event (detach_event1); diff --git a/libgomp/testsuite/libgomp.c-c++-common/task-detach-10.c b/libgomp/testsuite/libgomp.c-c++-common/task-detach-10.c new file mode 100644 index 0000000..10d6746 --- /dev/null +++ b/libgomp/testsuite/libgomp.c-c++-common/task-detach-10.c @@ -0,0 +1,45 @@ +/* { dg-do run } */ + +#include <omp.h> +#include <assert.h> + +/* Test tasks with detach clause on an offload device. Each device + thread spawns off a chain of tasks in a taskgroup, that can then + be executed by any available thread. */ + +int main (void) +{ + int x = 0, y = 0, z = 0; + int thread_count; + omp_event_handle_t detach_event1, detach_event2; + + #pragma omp target map (tofrom: x, y, z) map (from: thread_count) + #pragma omp parallel private (detach_event1, detach_event2) + #pragma omp taskgroup + { + #pragma omp single + thread_count = omp_get_num_threads (); + + #pragma omp task detach (detach_event1) untied + #pragma omp atomic update + x++; + + #pragma omp task detach (detach_event2) untied + { + #pragma omp atomic update + y++; + omp_fulfill_event (detach_event1); + } + + #pragma omp task untied + { + #pragma omp atomic update + z++; + omp_fulfill_event (detach_event2); + } + } + + assert (x == thread_count); + assert (y == thread_count); + assert (z == thread_count); +} diff --git a/libgomp/testsuite/libgomp.c-c++-common/task-detach-11.c b/libgomp/testsuite/libgomp.c-c++-common/task-detach-11.c new file mode 100644 index 0000000..dd002dc --- /dev/null +++ b/libgomp/testsuite/libgomp.c-c++-common/task-detach-11.c @@ -0,0 +1,13 @@ +/* { dg-do run } */ + +#include <omp.h> + +/* Test the detach clause when the task is undeferred. */ + +int main (void) +{ + omp_event_handle_t event; + + #pragma omp task detach (event) + omp_fulfill_event (event); +} diff --git a/libgomp/testsuite/libgomp.c-c++-common/task-detach-2.c b/libgomp/testsuite/libgomp.c-c++-common/task-detach-2.c index 943ac2a..3e33c40 100644 --- a/libgomp/testsuite/libgomp.c-c++-common/task-detach-2.c +++ b/libgomp/testsuite/libgomp.c-c++-common/task-detach-2.c @@ -12,13 +12,13 @@ int main (void) omp_event_handle_t detach_event1, detach_event2; int x = 0, y = 0, z = 0; - #pragma omp parallel num_threads(1) + #pragma omp parallel num_threads (1) #pragma omp single { - #pragma omp task detach(detach_event1) + #pragma omp task detach (detach_event1) x++; - #pragma omp task detach(detach_event2) + #pragma omp task detach (detach_event2) { y++; omp_fulfill_event (detach_event1); diff --git a/libgomp/testsuite/libgomp.c-c++-common/task-detach-3.c b/libgomp/testsuite/libgomp.c-c++-common/task-detach-3.c index 2609fb1..c85857d 100644 --- a/libgomp/testsuite/libgomp.c-c++-common/task-detach-3.c +++ b/libgomp/testsuite/libgomp.c-c++-common/task-detach-3.c @@ -14,16 +14,16 @@ int main (void) #pragma omp parallel #pragma omp single { - #pragma omp task depend(out:dep) detach(detach_event) + #pragma omp task depend (out:dep) detach (detach_event) x++; #pragma omp task { y++; - omp_fulfill_event(detach_event); + omp_fulfill_event (detach_event); } - #pragma omp task depend(in:dep) + #pragma omp task depend (in:dep) z++; } diff --git a/libgomp/testsuite/libgomp.c-c++-common/task-detach-4.c b/libgomp/testsuite/libgomp.c-c++-common/task-detach-4.c index eeb9554..cd0d2b3 100644 --- a/libgomp/testsuite/libgomp.c-c++-common/task-detach-4.c +++ b/libgomp/testsuite/libgomp.c-c++-common/task-detach-4.c @@ -14,10 +14,10 @@ int main (void) #pragma omp parallel #pragma omp single - #pragma omp task detach(detach_event) + #pragma omp task detach (detach_event) { x++; - omp_fulfill_event(detach_event); + omp_fulfill_event (detach_event); } assert (x == 1); diff --git a/libgomp/testsuite/libgomp.c-c++-common/task-detach-5.c b/libgomp/testsuite/libgomp.c-c++-common/task-detach-5.c index 5a01517..382f377 100644 --- a/libgomp/testsuite/libgomp.c-c++-common/task-detach-5.c +++ b/libgomp/testsuite/libgomp.c-c++-common/task-detach-5.c @@ -12,16 +12,16 @@ int main (void) int thread_count; omp_event_handle_t detach_event1, detach_event2; - #pragma omp parallel firstprivate(detach_event1, detach_event2) + #pragma omp parallel private (detach_event1, detach_event2) { #pragma omp single - thread_count = omp_get_num_threads(); + thread_count = omp_get_num_threads (); - #pragma omp task detach(detach_event1) untied + #pragma omp task detach (detach_event1) untied #pragma omp atomic update x++; - #pragma omp task detach(detach_event2) untied + #pragma omp task detach (detach_event2) untied { #pragma omp atomic update y++; diff --git a/libgomp/testsuite/libgomp.c-c++-common/task-detach-6.c b/libgomp/testsuite/libgomp.c-c++-common/task-detach-6.c index b5f68cc..e5c2291 100644 --- a/libgomp/testsuite/libgomp.c-c++-common/task-detach-6.c +++ b/libgomp/testsuite/libgomp.c-c++-common/task-detach-6.c @@ -13,11 +13,11 @@ int main (void) int thread_count; omp_event_handle_t detach_event1, detach_event2; - #pragma omp target map(tofrom: x, y, z) map(from: thread_count) - #pragma omp parallel firstprivate(detach_event1, detach_event2) + #pragma omp target map (tofrom: x, y, z) map (from: thread_count) + #pragma omp parallel private (detach_event1, detach_event2) { #pragma omp single - thread_count = omp_get_num_threads(); + thread_count = omp_get_num_threads (); #pragma omp task detach(detach_event1) untied #pragma omp atomic update @@ -36,8 +36,6 @@ int main (void) z++; omp_fulfill_event (detach_event2); } - - #pragma omp taskwait } assert (x == thread_count); diff --git a/libgomp/testsuite/libgomp.c-c++-common/task-detach-7.c b/libgomp/testsuite/libgomp.c-c++-common/task-detach-7.c new file mode 100644 index 0000000..3f025d6 --- /dev/null +++ b/libgomp/testsuite/libgomp.c-c++-common/task-detach-7.c @@ -0,0 +1,45 @@ +/* { dg-do run } */ + +#include <omp.h> +#include <assert.h> + +/* Test tasks with detach clause. Each thread spawns off a chain of tasks, + that can then be executed by any available thread. Each thread uses + taskwait to wait for the child tasks to complete. */ + +int main (void) +{ + int x = 0, y = 0, z = 0; + int thread_count; + omp_event_handle_t detach_event1, detach_event2; + + #pragma omp parallel private (detach_event1, detach_event2) + { + #pragma omp single + thread_count = omp_get_num_threads (); + + #pragma omp task detach (detach_event1) untied + #pragma omp atomic update + x++; + + #pragma omp task detach (detach_event2) untied + { + #pragma omp atomic update + y++; + omp_fulfill_event (detach_event1); + } + + #pragma omp task untied + { + #pragma omp atomic update + z++; + omp_fulfill_event (detach_event2); + } + + #pragma omp taskwait + } + + assert (x == thread_count); + assert (y == thread_count); + assert (z == thread_count); +} diff --git a/libgomp/testsuite/libgomp.c-c++-common/task-detach-8.c b/libgomp/testsuite/libgomp.c-c++-common/task-detach-8.c new file mode 100644 index 0000000..6f77f12 --- /dev/null +++ b/libgomp/testsuite/libgomp.c-c++-common/task-detach-8.c @@ -0,0 +1,47 @@ +/* { dg-do run } */ + +#include <omp.h> +#include <assert.h> + +/* Test tasks with detach clause on an offload device. Each device + thread spawns off a chain of tasks, that can then be executed by + any available thread. Each thread uses taskwait to wait for the + child tasks to complete. */ + +int main (void) +{ + int x = 0, y = 0, z = 0; + int thread_count; + omp_event_handle_t detach_event1, detach_event2; + + #pragma omp target map (tofrom: x, y, z) map (from: thread_count) + #pragma omp parallel private (detach_event1, detach_event2) + { + #pragma omp single + thread_count = omp_get_num_threads (); + + #pragma omp task detach (detach_event1) untied + #pragma omp atomic update + x++; + + #pragma omp task detach (detach_event2) untied + { + #pragma omp atomic update + y++; + omp_fulfill_event (detach_event1); + } + + #pragma omp task untied + { + #pragma omp atomic update + z++; + omp_fulfill_event (detach_event2); + } + + #pragma omp taskwait + } + + assert (x == thread_count); + assert (y == thread_count); + assert (z == thread_count); +} diff --git a/libgomp/testsuite/libgomp.c-c++-common/task-detach-9.c b/libgomp/testsuite/libgomp.c-c++-common/task-detach-9.c new file mode 100644 index 0000000..5316ca5 --- /dev/null +++ b/libgomp/testsuite/libgomp.c-c++-common/task-detach-9.c @@ -0,0 +1,43 @@ +/* { dg-do run } */ + +#include <omp.h> +#include <assert.h> + +/* Test tasks with detach clause. Each thread spawns off a chain of tasks + in a taskgroup, that can then be executed by any available thread. */ + +int main (void) +{ + int x = 0, y = 0, z = 0; + int thread_count; + omp_event_handle_t detach_event1, detach_event2; + + #pragma omp parallel private (detach_event1, detach_event2) + #pragma omp taskgroup + { + #pragma omp single + thread_count = omp_get_num_threads (); + + #pragma omp task detach (detach_event1) untied + #pragma omp atomic update + x++; + + #pragma omp task detach (detach_event2) untied + { + #pragma omp atomic update + y++; + omp_fulfill_event (detach_event1); + } + + #pragma omp task untied + { + #pragma omp atomic update + z++; + omp_fulfill_event (detach_event2); + } + } + + assert (x == thread_count); + assert (y == thread_count); + assert (z == thread_count); +} diff --git a/libgomp/testsuite/libgomp.fortran/task-detach-1.f90 b/libgomp/testsuite/libgomp.fortran/task-detach-1.f90 index 217bf65..c53b1ca 100644 --- a/libgomp/testsuite/libgomp.fortran/task-detach-1.f90 +++ b/libgomp/testsuite/libgomp.fortran/task-detach-1.f90 @@ -11,11 +11,11 @@ program task_detach_1 !$omp parallel !$omp single - !$omp task detach(detach_event1) + !$omp task detach (detach_event1) x = x + 1 !$omp end task - !$omp task detach(detach_event2) + !$omp task detach (detach_event2) y = y + 1 call omp_fulfill_event (detach_event1) !$omp end task diff --git a/libgomp/testsuite/libgomp.fortran/task-detach-10.f90 b/libgomp/testsuite/libgomp.fortran/task-detach-10.f90 new file mode 100644 index 0000000..61f0ea8 --- /dev/null +++ b/libgomp/testsuite/libgomp.fortran/task-detach-10.f90 @@ -0,0 +1,44 @@ +! { dg-do run } + +! Test tasks with detach clause on an offload device. Each device +! thread spawns off a chain of tasks in a taskgroup, that can then +! be executed by any available thread. + +program task_detach_10 + use omp_lib + + integer (kind=omp_event_handle_kind) :: detach_event1, detach_event2 + integer :: x = 0, y = 0, z = 0 + integer :: thread_count + + !$omp target map (tofrom: x, y, z) map (from: thread_count) + !$omp parallel private (detach_event1, detach_event2) + !$omp taskgroup + !$omp single + thread_count = omp_get_num_threads () + !$omp end single + + !$omp task detach (detach_event1) untied + !$omp atomic update + x = x + 1 + !$omp end task + + !$omp task detach (detach_event2) untied + !$omp atomic update + y = y + 1 + call omp_fulfill_event (detach_event1) + !$omp end task + + !$omp task untied + !$omp atomic update + z = z + 1 + call omp_fulfill_event (detach_event2) + !$omp end task + !$omp end taskgroup + !$omp end parallel + !$omp end target + + if (x /= thread_count) stop 1 + if (y /= thread_count) stop 2 + if (z /= thread_count) stop 3 +end program diff --git a/libgomp/testsuite/libgomp.fortran/task-detach-11.f90 b/libgomp/testsuite/libgomp.fortran/task-detach-11.f90 new file mode 100644 index 0000000..b33baff --- /dev/null +++ b/libgomp/testsuite/libgomp.fortran/task-detach-11.f90 @@ -0,0 +1,13 @@ +! { dg-do run } + +! Test the detach clause when the task is undeferred. + +program task_detach_11 + use omp_lib + + integer (kind=omp_event_handle_kind) :: detach_event + + !$omp task detach (detach_event) + call omp_fulfill_event (detach_event) + !$omp end task +end program diff --git a/libgomp/testsuite/libgomp.fortran/task-detach-2.f90 b/libgomp/testsuite/libgomp.fortran/task-detach-2.f90 index ecb4829..68e3ff2 100644 --- a/libgomp/testsuite/libgomp.fortran/task-detach-2.f90 +++ b/libgomp/testsuite/libgomp.fortran/task-detach-2.f90 @@ -10,13 +10,13 @@ program task_detach_2 integer (kind=omp_event_handle_kind) :: detach_event1, detach_event2 integer :: x = 0, y = 0, z = 0 - !$omp parallel num_threads(1) + !$omp parallel num_threads (1) !$omp single - !$omp task detach(detach_event1) + !$omp task detach (detach_event1) x = x + 1 !$omp end task - !$omp task detach(detach_event2) + !$omp task detach (detach_event2) y = y + 1 call omp_fulfill_event (detach_event1) !$omp end task diff --git a/libgomp/testsuite/libgomp.fortran/task-detach-3.f90 b/libgomp/testsuite/libgomp.fortran/task-detach-3.f90 index bdf93a5..5ac68d5 100644 --- a/libgomp/testsuite/libgomp.fortran/task-detach-3.f90 +++ b/libgomp/testsuite/libgomp.fortran/task-detach-3.f90 @@ -12,16 +12,16 @@ program task_detach_3 !$omp parallel !$omp single - !$omp task depend(out:dep) detach(detach_event) + !$omp task depend (out:dep) detach (detach_event) x = x + 1 !$omp end task !$omp task y = y + 1 - call omp_fulfill_event(detach_event) + call omp_fulfill_event (detach_event) !$omp end task - !$omp task depend(in:dep) + !$omp task depend (in:dep) z = z + 1 !$omp end task !$omp end single diff --git a/libgomp/testsuite/libgomp.fortran/task-detach-4.f90 b/libgomp/testsuite/libgomp.fortran/task-detach-4.f90 index 6d0843c..159624c 100644 --- a/libgomp/testsuite/libgomp.fortran/task-detach-4.f90 +++ b/libgomp/testsuite/libgomp.fortran/task-detach-4.f90 @@ -11,9 +11,9 @@ program task_detach_4 !$omp parallel !$omp single - !$omp task detach(detach_event) + !$omp task detach (detach_event) x = x + 1 - call omp_fulfill_event(detach_event) + call omp_fulfill_event (detach_event) !$omp end task !$omp end single !$omp end parallel diff --git a/libgomp/testsuite/libgomp.fortran/task-detach-5.f90 b/libgomp/testsuite/libgomp.fortran/task-detach-5.f90 index 955d687..95bd132 100644 --- a/libgomp/testsuite/libgomp.fortran/task-detach-5.f90 +++ b/libgomp/testsuite/libgomp.fortran/task-detach-5.f90 @@ -10,17 +10,17 @@ program task_detach_5 integer :: x = 0, y = 0, z = 0 integer :: thread_count - !$omp parallel firstprivate(detach_event1, detach_event2) + !$omp parallel private (detach_event1, detach_event2) !$omp single - thread_count = omp_get_num_threads() + thread_count = omp_get_num_threads () !$omp end single - !$omp task detach(detach_event1) untied + !$omp task detach (detach_event1) untied !$omp atomic update x = x + 1 !$omp end task - !$omp task detach(detach_event2) untied + !$omp task detach (detach_event2) untied !$omp atomic update y = y + 1 call omp_fulfill_event (detach_event1); diff --git a/libgomp/testsuite/libgomp.fortran/task-detach-6.f90 b/libgomp/testsuite/libgomp.fortran/task-detach-6.f90 index 0fe2155..b2c476f 100644 --- a/libgomp/testsuite/libgomp.fortran/task-detach-6.f90 +++ b/libgomp/testsuite/libgomp.fortran/task-detach-6.f90 @@ -11,30 +11,28 @@ program task_detach_6 integer :: x = 0, y = 0, z = 0 integer :: thread_count - !$omp target map(tofrom: x, y, z) map(from: thread_count) - !$omp parallel firstprivate(detach_event1, detach_event2) + !$omp target map (tofrom: x, y, z) map (from: thread_count) + !$omp parallel private (detach_event1, detach_event2) !$omp single - thread_count = omp_get_num_threads() + thread_count = omp_get_num_threads () !$omp end single - !$omp task detach(detach_event1) untied + !$omp task detach (detach_event1) untied !$omp atomic update x = x + 1 !$omp end task - !$omp task detach(detach_event2) untied + !$omp task detach (detach_event2) untied !$omp atomic update y = y + 1 - call omp_fulfill_event (detach_event1); + call omp_fulfill_event (detach_event1) !$omp end task !$omp task untied !$omp atomic update z = z + 1 - call omp_fulfill_event (detach_event2); + call omp_fulfill_event (detach_event2) !$omp end task - - !$omp taskwait !$omp end parallel !$omp end target diff --git a/libgomp/testsuite/libgomp.fortran/task-detach-7.f90 b/libgomp/testsuite/libgomp.fortran/task-detach-7.f90 new file mode 100644 index 0000000..32e715e --- /dev/null +++ b/libgomp/testsuite/libgomp.fortran/task-detach-7.f90 @@ -0,0 +1,42 @@ +! { dg-do run } + +! Test tasks with detach clause. Each thread spawns off a chain of tasks, +! that can then be executed by any available thread. Each thread uses +! taskwait to wait for the child tasks to complete. + +program task_detach_7 + use omp_lib + + integer (kind=omp_event_handle_kind) :: detach_event1, detach_event2 + integer :: x = 0, y = 0, z = 0 + integer :: thread_count + + !$omp parallel private (detach_event1, detach_event2) + !$omp single + thread_count = omp_get_num_threads() + !$omp end single + + !$omp task detach (detach_event1) untied + !$omp atomic update + x = x + 1 + !$omp end task + + !$omp task detach (detach_event2) untied + !$omp atomic update + y = y + 1 + call omp_fulfill_event (detach_event1) + !$omp end task + + !$omp task untied + !$omp atomic update + z = z + 1 + call omp_fulfill_event (detach_event2) + !$omp end task + + !$omp taskwait + !$omp end parallel + + if (x /= thread_count) stop 1 + if (y /= thread_count) stop 2 + if (z /= thread_count) stop 3 +end program diff --git a/libgomp/testsuite/libgomp.fortran/task-detach-8.f90 b/libgomp/testsuite/libgomp.fortran/task-detach-8.f90 new file mode 100644 index 0000000..e760eab --- /dev/null +++ b/libgomp/testsuite/libgomp.fortran/task-detach-8.f90 @@ -0,0 +1,45 @@ +! { dg-do run } + +! Test tasks with detach clause on an offload device. Each device +! thread spawns off a chain of tasks, that can then be executed by +! any available thread. Each thread uses taskwait to wait for the +! child tasks to complete. + +program task_detach_8 + use omp_lib + + integer (kind=omp_event_handle_kind) :: detach_event1, detach_event2 + integer :: x = 0, y = 0, z = 0 + integer :: thread_count + + !$omp target map (tofrom: x, y, z) map (from: thread_count) + !$omp parallel private (detach_event1, detach_event2) + !$omp single + thread_count = omp_get_num_threads () + !$omp end single + + !$omp task detach (detach_event1) untied + !$omp atomic update + x = x + 1 + !$omp end task + + !$omp task detach (detach_event2) untied + !$omp atomic update + y = y + 1 + call omp_fulfill_event (detach_event1) + !$omp end task + + !$omp task untied + !$omp atomic update + z = z + 1 + call omp_fulfill_event (detach_event2) + !$omp end task + + !$omp taskwait + !$omp end parallel + !$omp end target + + if (x /= thread_count) stop 1 + if (y /= thread_count) stop 2 + if (z /= thread_count) stop 3 +end program diff --git a/libgomp/testsuite/libgomp.fortran/task-detach-9.f90 b/libgomp/testsuite/libgomp.fortran/task-detach-9.f90 new file mode 100644 index 0000000..540c6de --- /dev/null +++ b/libgomp/testsuite/libgomp.fortran/task-detach-9.f90 @@ -0,0 +1,41 @@ +! { dg-do run } + +! Test tasks with detach clause. Each thread spawns off a chain of tasks +! in a taskgroup, that can then be executed by any available thread. + +program task_detach_9 + use omp_lib + + integer (kind=omp_event_handle_kind) :: detach_event1, detach_event2 + integer :: x = 0, y = 0, z = 0 + integer :: thread_count + + !$omp parallel private (detach_event1, detach_event2) + !$omp taskgroup + !$omp single + thread_count = omp_get_num_threads () + !$omp end single + + !$omp task detach (detach_event1) untied + !$omp atomic update + x = x + 1 + !$omp end task + + !$omp task detach (detach_event2) untied + !$omp atomic update + y = y + 1 + call omp_fulfill_event (detach_event1); + !$omp end task + + !$omp task untied + !$omp atomic update + z = z + 1 + call omp_fulfill_event (detach_event2); + !$omp end task + !$omp end taskgroup + !$omp end parallel + + if (x /= thread_count) stop 1 + if (y /= thread_count) stop 2 + if (z /= thread_count) stop 3 +end program |