1*37234499Sagozillon! Offloading test checking the use of the depend clause on the target construct 2d7e185ccSPranav Bhandarkar! REQUIRES: flang, amdgcn-amd-amdhsa 3d7e185ccSPranav Bhandarkar! UNSUPPORTED: nvptx64-nvidia-cuda 4d7e185ccSPranav Bhandarkar! UNSUPPORTED: nvptx64-nvidia-cuda-LTO 5d7e185ccSPranav Bhandarkar! UNSUPPORTED: aarch64-unknown-linux-gnu 6d7e185ccSPranav Bhandarkar! UNSUPPORTED: aarch64-unknown-linux-gnu-LTO 71a0cf245SJan Patrick Lehr! UNSUPPORTED: x86_64-unknown-linux-gnu 81a0cf245SJan Patrick Lehr! UNSUPPORTED: x86_64-unknown-linux-gnu-LTO 9d7e185ccSPranav Bhandarkar 10d7e185ccSPranav Bhandarkar! RUN: %libomptarget-compile-fortran-run-and-check-generic 11d7e185ccSPranav Bhandarkarprogram main 12d7e185ccSPranav Bhandarkar implicit none 13d7e185ccSPranav Bhandarkar integer :: a = 0 14d7e185ccSPranav Bhandarkar INTERFACE 15d7e185ccSPranav Bhandarkar FUNCTION omp_get_device_num() BIND(C) 16d7e185ccSPranav Bhandarkar USE, INTRINSIC :: iso_c_binding, ONLY: C_INT 17d7e185ccSPranav Bhandarkar integer :: omp_get_device_num 18d7e185ccSPranav Bhandarkar END FUNCTION omp_get_device_num 19d7e185ccSPranav Bhandarkar END INTERFACE 20d7e185ccSPranav Bhandarkar 21d7e185ccSPranav Bhandarkar call foo(5, a) 22d7e185ccSPranav Bhandarkar print*, "======= FORTRAN Test passed! =======" 23d7e185ccSPranav Bhandarkar print*, "foo(5) returned ", a, ", expected 6\n" 24d7e185ccSPranav Bhandarkar 25d7e185ccSPranav Bhandarkar ! stop 0 26d7e185ccSPranav Bhandarkar contains 27d7e185ccSPranav Bhandarkar subroutine foo(N, r) 28d7e185ccSPranav Bhandarkar integer, intent(in) :: N 29d7e185ccSPranav Bhandarkar integer, intent(out) :: r 30d7e185ccSPranav Bhandarkar integer :: z, i, accumulator 31d7e185ccSPranav Bhandarkar z = 1 32d7e185ccSPranav Bhandarkar accumulator = 0 33d7e185ccSPranav Bhandarkar ! Spawn 3 threads 34d7e185ccSPranav Bhandarkar !$omp parallel num_threads(3) 35d7e185ccSPranav Bhandarkar 36d7e185ccSPranav Bhandarkar ! A single thread will then create two tasks - one is the 'producer' and 37d7e185ccSPranav Bhandarkar ! potentially slower task that updates 'z' to 'N'. The second is an 38d7e185ccSPranav Bhandarkar ! offloaded target task that increments 'z'. If the depend clauses work 39d7e185ccSPranav Bhandarkar ! properly, the target task should wait for the 'producer' task to 40d7e185ccSPranav Bhandarkar ! complete before incrementing 'z'. We use 'omp single' here because the 41d7e185ccSPranav Bhandarkar ! depend clause establishes dependencies between sibling tasks only. 42d7e185ccSPranav Bhandarkar ! This is the easiest way of creating two sibling tasks. 43d7e185ccSPranav Bhandarkar !$omp single 44d7e185ccSPranav Bhandarkar !$omp task depend(out: z) shared(z) 45d7e185ccSPranav Bhandarkar do i=1, 32766 46d7e185ccSPranav Bhandarkar ! dumb loop nest to slow down the update of 'z'. 47d7e185ccSPranav Bhandarkar ! Adding a function call slows down the producer to the point 48d7e185ccSPranav Bhandarkar ! that removing the depend clause from the target construct below 49d7e185ccSPranav Bhandarkar ! frequently results in the wrong answer. 50d7e185ccSPranav Bhandarkar accumulator = accumulator + omp_get_device_num() 51d7e185ccSPranav Bhandarkar end do 52d7e185ccSPranav Bhandarkar z = N 53d7e185ccSPranav Bhandarkar !$omp end task 54d7e185ccSPranav Bhandarkar 55d7e185ccSPranav Bhandarkar ! z is 5 now. Increment z to 6. 56d7e185ccSPranav Bhandarkar !$omp target map(tofrom: z) depend(in:z) 57d7e185ccSPranav Bhandarkar z = z + 1 58d7e185ccSPranav Bhandarkar !$omp end target 59d7e185ccSPranav Bhandarkar !$omp end single 60d7e185ccSPranav Bhandarkar !$omp end parallel 61d7e185ccSPranav Bhandarkar ! Use 'accumulator' so it is not optimized away by the compiler. 62d7e185ccSPranav Bhandarkar print *, accumulator 63d7e185ccSPranav Bhandarkar r = z 64d7e185ccSPranav Bhandarkar end subroutine foo 65d7e185ccSPranav Bhandarkar 66d7e185ccSPranav Bhandarkar!CHECK: ======= FORTRAN Test passed! ======= 67d7e185ccSPranav Bhandarkar!CHECK: foo(5) returned 6 , expected 6 68d7e185ccSPranav Bhandarkarend program main 69