Look at the following code:
subroutine changeDevice2(vals,xMax,val) implicit none integer :: xMax, val, i integer, dimension(xMax) :: vals !$omp target !$omp parallel do do i=1,xMax if(vals(0).EQ.val) then vals(1)=2 endif enddo write(*,*) "Try returning from 2" !$omp end target write(*,*) "Returned from 2" end subroutine subroutine changeDevice1(val) implicit none integer :: val,i integer, allocatable :: vals(:) integer :: xMax xMax = 100 allocate(vals(xMax)) vals = 1 !$omp target map(vals) !$omp parallel do do i=1,xMax if(vals(0).EQ.val) then vals(1)=2 endif enddo write(*,*) "Try returning from 1" !$omp end target write(*,*) "Returned from 1" end subroutine subroutine changeDeviceWorks(val) implicit none integer :: val,valLoc,i integer, allocatable :: vals(:) integer :: xMax xMax = 100 allocate(vals(xMax)) vals = 1 valLoc=val !$omp target map(vals) !$omp parallel do do i=1,xMax if(vals(0).EQ.valLoc) then vals(1)=2 endif enddo write(*,*) "Try returning from works" !$omp end target write(*,*) "Returned from works" end subroutine program fortTest implicit none integer, allocatable :: vals(:) integer :: xMax xMax = 100 allocate(vals(xMax)) vals = 1 call changeDeviceWorks(1) call changeDevice1(1) !$omp target data map(vals) call changeDevice2(vals,xMax,1) !$omp end target data end
The changeDevice1 and changeDevice2 methods will never return from their target regions.
Using a local variable instead of the parameter works (see changeDeviceWorks)
Also removing the !$omp parallel do makes it return.
I consider this as critical as it renders quite some applications not working and occasionally even hangs the whole login session when trying to abort the program.