https://gcc.gnu.org/bugzilla/show_bug.cgi?id=126940
--- Comment #3 from Tobias Burnus <burnus at gcc dot gnu.org> ---
First, the reason why the issue only shows up with offloading enabled:
!$acc data copyin(host_p, host_parr)
...
#if !ACC_MEM_SHARED
...
if (acc_is_present(parr, 1)) stop 6
#endif
...
!$acc end data
Namely, 'acc_is_present' is only called if offloading is enabled.
Here,
real, target, intent(in) :: parr(:), p2
such that 'parr' is not contiguous. And Fortran semantic might require packing
the argument in a function call.
* * *
Second: I have to admit that I do not understand why the contiguous check is
only now active - and not before? Or was it - but some additional check causes
this (like an elem_len != 0 check?)
JERRY, any idea? (I have not read your patch, admittedly.)
* * *
NOTE: OpenACC semantic requires that the argument is contiguous - i.e. for
valid code, there will be a runtime check for being contiguous - but no actual
packing is done.
* * *
Regarding the testcase, we could do:
--- a/libgomp/testsuite/libgomp.oacc-fortran/host_data-5.F90
+++ b/libgomp/testsuite/libgomp.oacc-fortran/host_data-5.F90
@@ -28 +28,2 @@ subroutine foo (p2, parr, host_p, host_parr, cond)
- real, target, intent(in) :: parr(:), p2
+ real, target, contiguous, intent(in) :: parr(:)
+ real, target, intent(in) :: p2
... or do what we state below.
* * *
On the specification side, OpenACC 2.0 to 2.5 has:
logical function acc_is_present( a )
type, dimension(:[,:]. . . ) :: a
logical function acc_is_present( a, len )
type :: a
integer :: len
OpenMP 2.6 changed this to:
logical function acc_is_present( a )
logical function acc_is_present( a, len )
type(*), dimension(..) :: a
integer :: len
* * *
GCC implements it since r5-6458-g41dbbb3789850d as:
+ function acc_is_present_32_h (a, len)
+ use iso_c_binding, only: c_int32_t
+ logical acc_is_present_32_h
+ !GCC$ ATTRIBUTES NO_ARG_CHECK :: a
+ type (*), dimension (*) :: a
+ integer (c_int32_t) len
+ end function
+
+ function acc_is_present_64_h (a, len)
+ use iso_c_binding, only: c_int64_t
+ logical acc_is_present_64_h
+ !GCC$ ATTRIBUTES NO_ARG_CHECK :: a
+ type (*), dimension (*) :: a
+ integer (c_int64_t) len
+ end function
+
+ function acc_is_present_array_h (a)
+ logical acc_is_present_array_h
+ type (*), dimension (..), contiguous :: a
+ end function
+ end interface
...
+ interface acc_is_present
+ procedure :: acc_is_present_32_h
+ procedure :: acc_is_present_64_h
+ procedure :: acc_is_present_array_h
+ end interface
I wonder whether:
(0) There should be an 'intent(in)' which aids optimization, e.g. for packing,
it avoid copy out and it make clear that the array values aren't modified.
(1) The 'contiguous' in 'acc_is_present_array_h' should be removed. If the
passed argument is noncontiguous, both packing and not packing will lead to
bogus code. - This requires in the implementation to change
acc_is_present_array_h = acc_is_present_l (a, sizeof (a)) == 1
to
acc_is_present_array_h = acc_is_present_l (loc(a), sizeof (a)) == 1
to avoid the packing in the library.
(2) Whether acc_is_present_{32,64}_h should be changed to
type (*), dimension (..) [, intent(in)] :: a
(and the specific function renamed - as we need to keep the old one for
backward compatibility.)
THOMAS, what do you think?