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

Reply via email to