Hi Thomas,

On 08/01/2025 10:04, Thomas Schwinge wrote:
Hi Paul-Antoine!

On 2024-12-16T19:35:01+0100, Paul-Antoine Arras <par...@baylibre.com> wrote:
On 15/11/2024 14:59, Tobias Burnus wrote:
Paul-Antoine Arras wrote:
This patch adds support for the `dispatch` construct and the
`adjust_args` clause to the Fortran front-end.

Handling of `adjust_args` across translation units is missing due
to PR115271.


First, can you add a run-time test?

[I think it helps to have at least one run-time test feature for every
major feature - as we had in the past e.g. C runtime tests and Fortran
compile time tests - but it turned out that some flags was not set,
causing the middle to ignore the feature completely ...]

Added libgomp/testsuite/libgomp.fortran/dispatch-1.f90.

I see this new test case FAIL (execution test SIGSEGV) for most (but not
all) offloading configurations, both GCN and nvptx:

     +PASS: libgomp.fortran/dispatch-1.f90   -O  (test for excess errors)
     +FAIL: libgomp.fortran/dispatch-1.f90   -O  execution test

Thanks for pointing that out! The testcase missed an OpenMP target directive. The attached patch should fix it.

Best,

PA

For example:

     [...]
     Thread 1 "a.out" received signal SIGSEGV, Segmentation fault.
     0x00000000004022fc in procedures::bar (d_bv=0x7fffc7002040, 
d_av=0x7fffc7000000, n=1024) at 
source-gcc/libgomp/testsuite/libgomp.fortran/dispatch-1.f90:59
     59            fp_bv(i) = fp_av(i) * i
     (gdb) bt
     #0  0x00000000004022fc in procedures::bar (d_bv=0x7fffc7002040, 
d_av=0x7fffc7000000, n=1024) at 
source-gcc/libgomp/testsuite/libgomp.fortran/dispatch-1.f90:59
     #1  0x0000000000401c41 in procedures::test (n=1024) at 
source-gcc/libgomp/testsuite/libgomp.fortran/dispatch-1.f90:86
     #2  0x0000000000402b1e in MAIN__ () at 
source-gcc/libgomp/testsuite/libgomp.fortran/dispatch-1.f90:115
     (gdb) print i
     $1 = 1
     (gdb) print fp_bv
     $2 = (0, <repeats 200 times>, ...)
     (gdb) print fp_av
     $3 = (0, <repeats 200 times>, ...)
     (gdb) print fp_bv(1)
     $4 = 0
     (gdb) print fp_av(1)
     $5 = 0
     (gdb) ptype fp_bv
     type = real(kind=8) (1024)
     (gdb) ptype fp_av
     type = real(kind=8) (1024)
     (gdb) up
     #1  0x0000000000401c41 in procedures::test (n=1024) at 
source-gcc/libgomp/testsuite/libgomp.fortran/dispatch-1.f90:86
     86            !$omp dispatch nocontext(n > 1024) novariants(n < 1024) 
device(last_dev)
     (gdb) print last_dev
     $6 = 0


Grüße
  Thomas


--- /dev/null
+++ libgomp/testsuite/libgomp.fortran/dispatch-1.f90
@@ -0,0 +1,120 @@
+module procedures
+  use iso_c_binding, only: c_ptr, c_f_pointer
+  use omp_lib
+  implicit none
+
+  contains
+
+  function foo(bv, av, n) result(res)
+    implicit none
+    integer :: res, n, i
+    type(c_ptr) :: bv
+    type(c_ptr) :: av
+    real(8), pointer :: fp_bv(:), fp_av(:)  ! Fortran pointers for array access
+    !$omp declare variant(bar) match(construct={dispatch}) 
adjust_args(need_device_ptr: bv, av)
+    !$omp declare variant(baz) match(implementation={vendor(gnu)})
+
+    ! Associate C pointers with Fortran pointers
+    call c_f_pointer(bv, fp_bv, [n])
+    call c_f_pointer(av, fp_av, [n])
+
+    ! Perform operations using Fortran pointers
+    do i = 1, n
+      fp_bv(i) = fp_av(i) * i
+    end do
+    res = -1
+  end function foo
+
+  function baz(d_bv, d_av, n) result(res)
+    implicit none
+    integer :: res, n, i
+    type(c_ptr) :: d_bv
+    type(c_ptr) :: d_av
+    real(8), pointer :: fp_bv(:), fp_av(:)  ! Fortran pointers for array access
+
+    ! Associate C pointers with Fortran pointers
+    call c_f_pointer(d_bv, fp_bv, [n])
+    call c_f_pointer(d_av, fp_av, [n])
+
+    !$omp distribute parallel do
+    do i = 1, n
+      fp_bv(i) = fp_av(i) * i
+    end do
+    res = -3
+  end function baz
+
+  function bar(d_bv, d_av, n) result(res)
+    implicit none
+    integer :: res, n, i
+    type(c_ptr) :: d_bv
+    type(c_ptr) :: d_av
+    real(8), pointer :: fp_bv(:), fp_av(:)  ! Fortran pointers for array access
+
+    ! Associate C pointers with Fortran pointers
+    call c_f_pointer(d_bv, fp_bv, [n])
+    call c_f_pointer(d_av, fp_av, [n])
+
+    ! Perform operations on target
+    do i = 1, n
+      fp_bv(i) = fp_av(i) * i
+    end do
+    res = -2
+  end function bar
+
+  function test(n) result(res)
+    use iso_c_binding, only: c_ptr, c_loc
+    implicit none
+    integer :: n, res, i, f, ff, last_dev
+    real(8), allocatable, target :: av(:), bv(:), d_bv(:)
+    real(8), parameter :: e = 2.71828d0
+    type(c_ptr) :: c_av, c_bv, c_d_bv
+
+    allocate(av(n), bv(n), d_bv(n))
+
+    ! Initialize arrays
+    do i = 1, n
+      av(i) = e * i
+      bv(i) = 0.0d0
+      d_bv(i) = 0.0d0
+    end do
+
+    last_dev = omp_get_num_devices() - 1
+
+    c_av = c_loc(av)
+    c_d_bv = c_loc(d_bv)
+    !$omp target data map(to: av(:n)) map(from: d_bv(:n)) device(last_dev) 
if(n == 1024)
+      !$omp dispatch nocontext(n > 1024) novariants(n < 1024) device(last_dev)
+      f = foo(c_d_bv, c_av, n)
+    !$omp end target data
+
+    c_bv = c_loc(bv)
+    ff = foo(c_bv, c_loc(av), n)
+
+    ! Verify results
+    do i = 1, n
+      if (d_bv(i) /= bv(i)) then
+        write(0,*) 'ERROR at ', i, ': ', d_bv(i), ' (act) != ', bv(i), ' (exp)'
+        res = 1
+        return
+      end if
+    end do
+
+    res = f
+    deallocate(av, bv, d_bv)
+  end function test
+end module procedures
+
+program main
+  use procedures
+  implicit none
+  integer :: ret
+
+  ret = test(1023)
+  if (ret /= -1) stop 1
+
+  ret = test(1024)
+  if (ret /= -2) stop 1
+
+  ret = test(1025)
+  if (ret /= -3) stop 1
+end program main


--
PA
commit 516705cc1d774c2a8e1b410e8b169a79ba8ad819
Author: Paul-Antoine Arras <par...@baylibre.com>
Date:   Mon Jan 13 12:57:15 2025 +0100

    Add missing target directive in OpenMP dispatch Fortran runtime test
    
    Without the target directive, the test would run on the host but still try to
    use device pointers, which causes a segfault.
    
    libgomp/ChangeLog:
    
            * testsuite/libgomp.fortran/dispatch-1.f90: Add missing target
            directive.

diff --git libgomp/testsuite/libgomp.fortran/dispatch-1.f90 libgomp/testsuite/libgomp.fortran/dispatch-1.f90
index 7b2f03f9d68..8be0d2d2179 100644
--- libgomp/testsuite/libgomp.fortran/dispatch-1.f90
+++ libgomp/testsuite/libgomp.fortran/dispatch-1.f90
@@ -55,6 +55,7 @@ module procedures
     call c_f_pointer(d_av, fp_av, [n])
 
     ! Perform operations on target
+    !$omp target is_device_ptr(fp_bv, fp_av)
     do i = 1, n
       fp_bv(i) = fp_av(i) * i
     end do

Reply via email to