69 lines · plain
1! Offloading test checking the use of the depend clause on the target construct2! REQUIRES: flang, amdgcn-amd-amdhsa3! UNSUPPORTED: nvptx64-nvidia-cuda4! UNSUPPORTED: nvptx64-nvidia-cuda-LTO5! UNSUPPORTED: aarch64-unknown-linux-gnu6! UNSUPPORTED: aarch64-unknown-linux-gnu-LTO7! UNSUPPORTED: x86_64-unknown-linux-gnu8! UNSUPPORTED: x86_64-unknown-linux-gnu-LTO9 10! RUN: %libomptarget-compile-fortran-run-and-check-generic11program main12 implicit none13 integer :: a = 014 INTERFACE15 FUNCTION omp_get_device_num() BIND(C)16 USE, INTRINSIC :: iso_c_binding, ONLY: C_INT17 integer :: omp_get_device_num18 END FUNCTION omp_get_device_num19 END INTERFACE20 21 call foo(5, a)22 print*, "======= FORTRAN Test passed! ======="23 print*, "foo(5) returned ", a, ", expected 6\n"24 25 ! stop 026 contains27 subroutine foo(N, r)28 integer, intent(in) :: N29 integer, intent(out) :: r30 integer :: z, i, accumulator31 z = 132 accumulator = 033 ! Spawn 3 threads34 !$omp parallel num_threads(3)35 36 ! A single thread will then create two tasks - one is the 'producer' and37 ! potentially slower task that updates 'z' to 'N'. The second is an38 ! offloaded target task that increments 'z'. If the depend clauses work39 ! properly, the target task should wait for the 'producer' task to40 ! complete before incrementing 'z'. We use 'omp single' here because the41 ! depend clause establishes dependencies between sibling tasks only.42 ! This is the easiest way of creating two sibling tasks.43 !$omp single44 !$omp task depend(out: z) shared(z)45 do i=1, 3276646 ! dumb loop nest to slow down the update of 'z'.47 ! Adding a function call slows down the producer to the point48 ! that removing the depend clause from the target construct below49 ! frequently results in the wrong answer.50 accumulator = accumulator + omp_get_device_num()51 end do52 z = N53 !$omp end task54 55 ! z is 5 now. Increment z to 6.56 !$omp target map(tofrom: z) depend(in:z)57 z = z + 158 !$omp end target59 !$omp end single60 !$omp end parallel61 ! Use 'accumulator' so it is not optimized away by the compiler.62 print *, accumulator63 r = z64 end subroutine foo65 66!CHECK: ======= FORTRAN Test passed! =======67!CHECK: foo(5) returned 6 , expected 668end program main69