Hi Paul-Antoine!
On 2024-12-16T19:35:01+0100, Paul-Antoine Arras <[email protected]> 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
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