Hi Sandra, hello world,

Sandra Loosemore wrote:

This patch enables support for using non-constant expressions when specifying
iterators in the map clause of target constructs and to/from clauses of
target update constructs.

If I compare one testcase that counted the mallocs, I wondered
about two things: First, why does the interdiff show that there
is now 2 instead of 3 mallocs. And, second, why are there two
mallocs at all.

Looking at the dump, I see:

map(iterator(integer(kind=4) i=1:D.4756:D.4757, loop_label=<D.4858>, 
index=D.4857,
    elems=omp_iter_data.25, elems_count=iftmp.24):to:D.4947->ptr [pointer set, 
len: 64])
map(iterator(integer(kind=4) i=1:D.4756:D.4757, loop_label=<D.4858>, 
index=D.4857,
    elems=omp_iter_data.28, elems_count=iftmp.24):attach:D.4965->ptr.data 
[bias: D.4958])

Thus, this explains why there are internally two allocations. For that part,
I wonder whether it makes sense to use:

  ompiter.1 = malloc (size_of_first + size_of_second);
  ompiter.2 = ompiter.1 + size_of_first;

instead of

            D.5085 = __builtin_malloc (D.5084);
            omp_iter_data.25 = D.5085;
            D.5088 = __builtin_malloc (D.5087);
            omp_iter_data.28 = D.5088;

namely, how much does it matter to have this. I have no real
idea how much it will help with the performance nor whether
it affects alias analysis (but even if it does, it probably
does not matter).


Fortran also has the following rule:
"If a list item in a map clause is an associated pointer and
 the pointer is not the base pointer of another list item in
 a map clause on the same construct, then it is treated as if
 its pointer target is implicitly mapped in the same clause."


If I try the attached program, an extended version of
  gcc/testsuite/gfortran.dg/gomp/target-map-iterators-5.f90

I noticed:

- If I use run-time bounds (this patch) the testcase
  'f2' segfaults at runtime - even without offloading
  enabled ('OMP_TARGET_OFFLOAD=disabled') or configured.
  (and likewise with offloading)

The const-bound version works ('h2').


Additionally, when explicitly writing 'x(1)%ptr' instead
of an iterator, it works - while with the iterator, it fails
with: 'libgomp: pointer target not mapped for attach'

* * *

The second one is seemingly a preexisting issue,
but the first one seems to be in the new code.

* * *

I also wanted to create a C/C++ version of the test
where 's[i].p' is the pointer and 's[i].p[:n]' the
pointee without anything happening automatically.

But I run out of time - I need to go to a meeting,
but be back later today.

* * *

Note this is about trunk + 6/11 only; possibly, the struct
fixing patch might influence this, I have not tried.

* * *

Note that with OG15, the non-offload version works on OG15!
(i.e. OG15 with OMP_TARGET_OFFLOAD=disabled)

While with offload version, OG15 also fails:
  h1: host:     7FFC8A8A5A08 /     7FFC8A8A59F4
  libgomp: Out of memory allocating 1125781062471896 bytes

which implies that the special handling of MAX_INT64_T
does not work (why?).

BTW: Same result for OG14. I wonder why this happens and
whether I messed up with building the two OG branches?

* * *

Tobias
! f - iterator dynamic bounds
! h - iterator static bounds
! g - explicit mapping
! ...1 - use '...%ptr'
! ...2 - use '...%ptr(:)'
module m
  implicit none (type, external)
  type :: array_ptr
    integer, pointer :: ptr(:)
  end type
contains
  subroutine f1 (x, stride)
    type (array_ptr) :: x(:)
    integer :: stride

    print '("f1: host: ", z16, " / ", z16)', loc(x(1)%ptr), loc(x(3)%ptr)
    !$omp target map(to: x) map(iterator(i=lbound(x, 1):ubound(x, 1):stride), to: x(i)%ptr)
      print '("f1: dev:  ", z16, " / ", z16)', loc(x(1)%ptr), loc(x(3)%ptr)
      if (size(x(1)%ptr) /= 2) stop 1
      if (size(x(3)%ptr) /= 2) stop 2
      if (any (x(1)%ptr /= [1,2])) stop 3
      if (any (x(3)%ptr /= [111,222])) stop 4
    !$omp end target
  end subroutine

  subroutine f2 (x, stride)
    type (array_ptr) :: x(:)
    integer :: stride

    print '("f2: host: ", z16, " / ", z16)', loc(x(1)%ptr), loc(x(3)%ptr)
    !$omp target map(to: x) map(iterator(i=lbound(x, 1):ubound(x, 1):stride), to: x(i)%ptr(:))
      print '("f2: dev:  ", z16, " / ", z16)', loc(x(1)%ptr), loc(x(3)%ptr)
      if (size(x(1)%ptr) /= 2) stop 1
      if (size(x(3)%ptr) /= 2) stop 2
      if (any (x(1)%ptr /= [1,2])) stop 3
      if (any (x(3)%ptr /= [111,222])) stop 4
    !$omp end target
  end subroutine

  subroutine h1 (x)
    type (array_ptr) :: x(:)

    print '("h1: host: ", z16, " / ", z16)', loc(x(1)%ptr), loc(x(3)%ptr)
    !$omp target map(to: x) map(iterator(i=1:4:2), to: x(i)%ptr)
      print '("h1: dev:  ", z16, " / ", z16)', loc(x(1)%ptr), loc(x(3)%ptr)
      if (size(x(1)%ptr) /= 2) stop 1
      if (size(x(3)%ptr) /= 2) stop 2
      if (any (x(1)%ptr /= [1,2])) stop 3
      if (any (x(3)%ptr /= [111,222])) stop 4
    !$omp end target
  end subroutine

  subroutine h2 (x)
    type (array_ptr) :: x(:)

    print '("h2: host: ", z16, " / ", z16)', loc(x(1)%ptr), loc(x(3)%ptr)
    !$omp target map(to: x) map(iterator(i=1:4:2), to: x(i)%ptr(:))
      print '("h2: dev:  ", z16, " / ", z16)', loc(x(1)%ptr), loc(x(3)%ptr)
      if (size(x(1)%ptr) /= 2) stop 1
      if (size(x(3)%ptr) /= 2) stop 2
      if (any (x(1)%ptr /= [1,2])) stop 3
      if (any (x(3)%ptr /= [111,222])) stop 4
    !$omp end target
  end subroutine

  subroutine g1 (x)
    type (array_ptr) :: x(:)

    print '("g1: host: ", z16, " / ", z16)', loc(x(1)%ptr), loc(x(3)%ptr)
    !$omp target map(to: x) map(to: x(1)%ptr, x(3)%ptr)
      print '("g1: dev:  ", z16, " / ", z16)', loc(x(1)%ptr), loc(x(3)%ptr)
      if (size(x(1)%ptr) /= 2) stop 1
      if (size(x(3)%ptr) /= 2) stop 2
      if (any (x(1)%ptr /= [1,2])) stop 3
      if (any (x(3)%ptr /= [111,222])) stop 4
    !$omp end target
  end subroutine

  subroutine g2 (x)
    type (array_ptr) :: x(:)

    print '("g2: host: ", z16, " / ", z16)', loc(x(1)%ptr), loc(x(3)%ptr)
    !$omp target map(to: x) map(to: x(1)%ptr(:), x(3)%ptr(:))
      print '("g2: dev:  ", z16, " / ", z16)', loc(x(1)%ptr), loc(x(3)%ptr)
      if (size(x(1)%ptr) /= 2) stop 1
      if (size(x(3)%ptr) /= 2) stop 2
      if (any (x(1)%ptr /= [1,2])) stop 3
      if (any (x(3)%ptr /= [111,222])) stop 4
    !$omp end target
  end subroutine
end module

use m
implicit none (type, external)
integer, target :: x1(2)
integer, target :: x2(3)
integer, target :: x3(2)
integer, target :: x4(4)
type(array_ptr) :: var(1:4)

x1 = [1,2]
x2 = [11,22,33]
x3 = [111,222]
x4 = [1111,2222,3333,4444]
var(1)%ptr => x1
var(2)%ptr => x2
var(3)%ptr => x3
var(4)%ptr => x4

call g1(var) ! Works
call g2(var) ! Works

!call h1(var)
!call h2(var)
! Both:
! Works without offload (not configured or host fallback)
! fails with offloading:  libgomp: pointer target not mapped for attach


call f1(var, 2)
! no offloading configured/host fallback -> works
! with offloading          -> libgomp: pointer target not mapped for attach

call f2(var, 2) ! Program received signal SIGSEGV: Segmentation fault - invalid memory reference.
!                  ^ independend whether offloading has been configured or not

end 

Reply via email to