1! { dg-do run } 2! { dg-require-effective-target offload_device } 3 4module e_51_6_mod 5integer, parameter :: THRESHOLD = 500 6contains 7 subroutine init (v1, v2, N) 8 integer :: i, N 9 real :: v1(N), v2(N) 10 do i = 1, N 11 v1(i) = i + 2.0 12 v2(i) = i - 3.0 13 end do 14 end subroutine 15 16 subroutine init_again (v1, v2, N) 17 integer :: i, N 18 real :: v1(N), v2(N) 19 do i = 1, N 20 v1(i) = i - 3.0 21 v2(i) = i + 2.0 22 end do 23 end subroutine 24 25 subroutine check (p, N) 26 integer :: i, N 27 real, parameter :: EPS = 0.00001 28 real :: diff, p(N) 29 do i = 1, N 30 diff = p(i) - 2 * (i + 2.0) * (i - 3.0) 31 if (diff > EPS .or. -diff > EPS) call abort 32 end do 33 end subroutine 34 35 subroutine vec_mult (N) 36 use omp_lib, only: omp_is_initial_device 37 real :: p(N), v1(N), v2(N) 38 integer :: i, N 39 call init (v1, v2, N) 40 !$omp target data if(N > THRESHOLD) map(from: p) 41 !$omp target if(N > THRESHOLD) map(to: v1, v2) 42 if (omp_is_initial_device ()) call abort 43 !$omp parallel do 44 do i = 1, N 45 p(i) = v1(i) * v2(i) 46 end do 47 !$omp end target 48 call init_again (v1, v2, N) 49 !$omp target if(N > THRESHOLD) map(to: v1, v2) 50 if (omp_is_initial_device ()) call abort 51 !$omp parallel do 52 do i = 1, N 53 p(i) = p(i) + v1(i) * v2(i) 54 end do 55 !$omp end target 56 !$omp end target data 57 call check (p, N) 58 end subroutine 59end module 60 61program e_51_6 62 use e_51_6_mod, only : vec_mult 63 integer :: n 64 n = 1000 65 call vec_mult (n) 66end program 67