Hi all, hello PA,
Tobias Burnus wrote:
Paul-Antoine Arras wrote:
See the revised patch attached and my comments below.
I have not looked in depth at the patch, but managed to
write C-ism code, which caused a segfault (due to a missing "call"),
Additional comments: Can you hoist the condition out of the loop in:
+ for (gfc_omp_namelist *n = *head; n != NULL; n = n->next) + if
(need_device_ptr_p) + n->u.need_device_ptr = true;
* * *
I was about to complain that it didn't handle VALUE + OPTIONAL
correctly, but that's a generic gfortran bug (or two):
->https://gcc.gnu.org/PR118080
* * *
There is a bug - 'nowait' is not propagated. Trying:
!$omp dispatch depend(inout:x) nowait
call g(a)
!$omp end dispatch
gives (-fdump-tree-gimple): #pragma omp taskwait depend(inout:&x) nowait
but doing the equivalent !$omp dispatch depend(inout:x) call g(a) !$omp
end dispatch nowait gives: #pragma omp taskwait depend(inout:&x) i.e.
the 'nowait' got lost. * * *
Similar the original C code, which to my knowledge is now
fixed + tested for, there is an issue related to handling nested
function calls.
I think the attached testcase is fine, but it segfaults unless
the default device is the initial device. The problem is that
the pointer conversion also happens for the inner function but
it should only do so for the outer one.
See attached testcase. – I think it can be seen by looking at the
dump (and adding an -fdump-tree-gimple + scan test probably won't
harm, as not everyone has a GPU and we might implement map as
selfmap on APUs).
Otherwise LGTM.
Tobias
module m
use omp_lib
use iso_c_binding
implicit none(type,external)
contains
integer function f(x, y1, y2, z1, z2)
allocatable :: f
integer, value :: x
type(c_ptr), value :: y1, y2
type(c_ptr) :: z1, z2
if (x == 1) then ! HOST
block
integer, pointer :: iy1, iy2, iz1, iz2
call c_f_pointer (y1, iy1)
call c_f_pointer (y2, iy2)
call c_f_pointer (z1, iz1)
call c_f_pointer (z2, iz2)
f = (iy1 + iy2) + 10 * (iz1+iz2)
end block
else
!$omp target is_device_ptr(y1, y2, z1, z2) map(from: f)
block
integer, pointer :: iy1, iy2, iz1, iz2
call c_f_pointer (y1, iy1)
call c_f_pointer (y2, iy2)
call c_f_pointer (z1, iz1)
call c_f_pointer (z2, iz2)
f = -(iy1+iy2)*23 -127 * (iz1+iz2) - x * 3
end block
end if
end
integer function g(x, y1, y2, z1, z2)
!$omp declare variant(f) match(construct={dispatch}) adjust_args(need_device_ptr : y1, y2, z1, z2)
allocatable :: g
integer, value :: x
type(c_ptr), value :: y1, y2
type(c_ptr) :: z1, z2
g = x
end
end
program main
use m
implicit none (type, external)
integer, target :: v1, v2
integer :: res, ref
v1 = 5
v2 = 11
ref = 5*2 + 10 * 11*2
ref = -(5*2)*23 -127 * (11*2) - ref * 3
!$omp target data map(v1,v2)
res = func (c_loc(v1), c_loc(v1), c_loc(v2), c_loc(v2))
!$omp end target data
if (res /= ref) stop 1
contains
integer function func(x1, x2, x3, x4)
use m
implicit none(type,external)
type(c_ptr) :: x1, x2, x3, x4
value :: x1, x3
!$omp dispatch
func = g(g(1,x1,x2,x3,x4), x1,x2,x3,x4)
end
end