1! { dg-do run }
2
3! Test tasks with detach clause on an offload device.  Each device
4! thread spawns off a chain of tasks, that can then be executed by
5! any available thread.  Each thread uses taskwait to wait for the
6! child tasks to complete.
7
8program task_detach_8
9  use omp_lib
10
11  integer (kind=omp_event_handle_kind) :: detach_event1, detach_event2
12  integer :: x = 0, y = 0, z = 0
13  integer :: thread_count
14
15  !$omp target map (tofrom: x, y, z) map (from: thread_count)
16    !$omp parallel private (detach_event1, detach_event2)
17      !$omp single
18	thread_count = omp_get_num_threads ()
19      !$omp end single
20
21      !$omp task detach (detach_event1) untied
22	!$omp atomic update
23	  x = x + 1
24      !$omp end task
25
26      !$omp task detach (detach_event2) untied
27	!$omp atomic update
28	  y = y + 1
29	call omp_fulfill_event (detach_event1)
30      !$omp end task
31
32      !$omp task untied
33	!$omp atomic update
34	  z = z + 1
35	call omp_fulfill_event (detach_event2)
36      !$omp end task
37
38      !$omp taskwait
39    !$omp end parallel
40  !$omp end target
41
42  if (x /= thread_count) stop 1
43  if (y /= thread_count) stop 2
44  if (z /= thread_count) stop 3
45end program
46