[PATCH] libgomp: Remove contiguous from assumed-rank array_h routines [PR96080, PR123280]

Christopher Albert <[email protected]>
Newsgroups gmane.comp.gcc.patches,gmane.comp.gcc.fortran
Message-ID <[email protected]>
All OpenACC Fortran runtime library routines with assumed-rank dummy
arguments (acc_copyin_array_h, acc_create_array_h, acc_copyout_array_h,
acc_delete_array_h, acc_is_present_array_h, and their async/finalize
variants) had 'contiguous' on the dummy argument.  When a non-contiguous
array was passed (assumed-shape dummy, Fortran pointer), gfortran
created a temporary copy to satisfy the contiguity requirement.  This
caused the runtime to operate on the copy's address rather than the
original data.

For acc_is_present this meant returning false for data that was actually
present on the device.  For acc_copyin/acc_create this meant mapping a
temporary that gets freed after the call.  For acc_copyout/acc_delete
this meant failing to find the original mapping.

Remove the contiguous attribute from all affected routines.  They only
pass the base address and size to the underlying C functions, so
contiguous storage is not required.

	PR libgomp/96080
	PR libgomp/123280

libgomp/ChangeLog:

	* openacc.f90: Remove contiguous attribute from assumed-rank
	dummy argument in all array_h routines and their interfaces.
	* testsuite/libgomp.oacc-fortran/pr123280.f90: New test.

Signed-off-by: Christopher Albert <[email protected]>
---
 libgomp/openacc.f90                           | 76 +++++++++----------
 .../libgomp.oacc-fortran/pr123280.f90         | 67 ++++++++++++++++
 2 files changed, 105 insertions(+), 38 deletions(-)
 create mode 100644 libgomp/testsuite/libgomp.oacc-fortran/pr123280.f90

diff --git a/libgomp/openacc.f90 b/libgomp/openacc.f90
index dfac1b00151..f720e6a7234 100644
--- a/libgomp/openacc.f90
+++ b/libgomp/openacc.f90
@@ -176,7 +176,7 @@ module openacc_internal
     end subroutine
 
     subroutine acc_copyin_array_h (a)
-      type (*), dimension (..), contiguous :: a
+      type (*), dimension (..) :: a
     end subroutine
 
     subroutine acc_present_or_copyin_32_h (a, len)
@@ -194,7 +194,7 @@ module openacc_internal
     end subroutine
 
     subroutine acc_present_or_copyin_array_h (a)
-      type (*), dimension (..), contiguous :: a
+      type (*), dimension (..) :: a
     end subroutine
 
     subroutine acc_create_32_h (a, len)
@@ -212,7 +212,7 @@ module openacc_internal
     end subroutine
 
     subroutine acc_create_array_h (a)
-      type (*), dimension (..), contiguous :: a
+      type (*), dimension (..) :: a
     end subroutine
 
     subroutine acc_present_or_create_32_h (a, len)
@@ -230,7 +230,7 @@ module openacc_internal
     end subroutine
 
     subroutine acc_present_or_create_array_h (a)
-      type (*), dimension (..), contiguous :: a
+      type (*), dimension (..) :: a
     end subroutine
 
     subroutine acc_copyout_32_h (a, len)
@@ -248,7 +248,7 @@ module openacc_internal
     end subroutine
 
     subroutine acc_copyout_array_h (a)
-      type (*), dimension (..), contiguous :: a
+      type (*), dimension (..) :: a
     end subroutine
 
     subroutine acc_copyout_finalize_32_h (a, len)
@@ -266,7 +266,7 @@ module openacc_internal
     end subroutine
 
     subroutine acc_copyout_finalize_array_h (a)
-      type (*), dimension (..), contiguous :: a
+      type (*), dimension (..) :: a
     end subroutine
 
     subroutine acc_copyout_finalize_async_32_h (a, len, async)
@@ -289,7 +289,7 @@ module openacc_internal
 
     subroutine acc_copyout_finalize_async_array_h (a, async)
       use openacc_kinds, only: acc_handle_kind
-      type (*), dimension (..), contiguous :: a
+      type (*), dimension (..) :: a
       integer (acc_handle_kind) async
     end subroutine
 
@@ -308,7 +308,7 @@ module openacc_internal
     end subroutine
 
     subroutine acc_delete_array_h (a)
-      type (*), dimension (..), contiguous :: a
+      type (*), dimension (..) :: a
     end subroutine
 
     subroutine acc_delete_finalize_32_h (a, len)
@@ -326,7 +326,7 @@ module openacc_internal
     end subroutine
 
     subroutine acc_delete_finalize_array_h (a)
-      type (*), dimension (..), contiguous :: a
+      type (*), dimension (..) :: a
     end subroutine
 
     subroutine acc_update_device_32_h (a, len)
@@ -344,7 +344,7 @@ module openacc_internal
     end subroutine
 
     subroutine acc_update_device_array_h (a)
-      type (*), dimension (..), contiguous :: a
+      type (*), dimension (..) :: a
     end subroutine
 
     subroutine acc_update_self_32_h (a, len)
@@ -362,7 +362,7 @@ module openacc_internal
     end subroutine
 
     subroutine acc_update_self_array_h (a)
-      type (*), dimension (..), contiguous :: a
+      type (*), dimension (..) :: a
     end subroutine
 
     function acc_is_present_32_h (a, len)
@@ -383,7 +383,7 @@ module openacc_internal
 
     function acc_is_present_array_h (a)
       logical acc_is_present_array_h
-      type (*), dimension (..), contiguous :: a
+      type (*), dimension (..) :: a
     end function
 
     subroutine acc_copyin_async_32_h (a, len, async)
@@ -406,7 +406,7 @@ module openacc_internal
 
     subroutine acc_copyin_async_array_h (a, async)
       use openacc_kinds, only: acc_handle_kind
-      type (*), dimension (..), contiguous :: a
+      type (*), dimension (..) :: a
       integer (acc_handle_kind) async
     end subroutine
 
@@ -430,7 +430,7 @@ module openacc_internal
 
     subroutine acc_create_async_array_h (a, async)
       use openacc_kinds, only: acc_handle_kind
-      type (*), dimension (..), contiguous :: a
+      type (*), dimension (..) :: a
       integer (acc_handle_kind) async
     end subroutine
 
@@ -454,7 +454,7 @@ module openacc_internal
 
     subroutine acc_copyout_async_array_h (a, async)
       use openacc_kinds, only: acc_handle_kind
-      type (*), dimension (..), contiguous :: a
+      type (*), dimension (..) :: a
       integer (acc_handle_kind) async
     end subroutine
 
@@ -478,7 +478,7 @@ module openacc_internal
 
     subroutine acc_delete_async_array_h (a, async)
       use openacc_kinds, only: acc_handle_kind
-      type (*), dimension (..), contiguous :: a
+      type (*), dimension (..) :: a
       integer (acc_handle_kind) async
     end subroutine
 
@@ -502,7 +502,7 @@ module openacc_internal
 
     subroutine acc_delete_finalize_async_array_h (a, async)
       use openacc_kinds, only: acc_handle_kind
-      type (*), dimension (..), contiguous :: a
+      type (*), dimension (..) :: a
       integer (acc_handle_kind) async
     end subroutine
 
@@ -526,7 +526,7 @@ module openacc_internal
 
     subroutine acc_update_device_async_array_h (a, async)
       use openacc_kinds, only: acc_handle_kind
-      type (*), dimension (..), contiguous :: a
+      type (*), dimension (..) :: a
       integer (acc_handle_kind) async
     end subroutine
 
@@ -550,7 +550,7 @@ module openacc_internal
 
     subroutine acc_update_self_async_array_h (a, async)
       use openacc_kinds, only: acc_handle_kind
-      type (*), dimension (..), contiguous :: a
+      type (*), dimension (..) :: a
       integer (acc_handle_kind) async
     end subroutine
   end interface
@@ -1394,7 +1394,7 @@ end subroutine
 
 subroutine acc_copyin_array_h (a)
   use openacc_internal, only: acc_copyin_l
-  type (*), dimension (..), contiguous :: a
+  type (*), dimension (..) :: a
   call acc_copyin_l (a, sizeof (a))
 end subroutine
 
@@ -1418,7 +1418,7 @@ end subroutine
 
 subroutine acc_present_or_copyin_array_h (a)
   use openacc_internal, only: acc_present_or_copyin_l
-  type (*), dimension (..), contiguous :: a
+  type (*), dimension (..) :: a
   call acc_present_or_copyin_l (a, sizeof (a))
 end subroutine
 
@@ -1442,7 +1442,7 @@ end subroutine
 
 subroutine acc_create_array_h (a)
   use openacc_internal, only: acc_create_l
-  type (*), dimension (..), contiguous :: a
+  type (*), dimension (..) :: a
   call acc_create_l (a, sizeof (a))
 end subroutine
 
@@ -1466,7 +1466,7 @@ end subroutine
 
 subroutine acc_present_or_create_array_h (a)
   use openacc_internal, only: acc_present_or_create_l
-  type (*), dimension (..), contiguous :: a
+  type (*), dimension (..) :: a
   call acc_present_or_create_l (a, sizeof (a))
 end subroutine
 
@@ -1490,7 +1490,7 @@ end subroutine
 
 subroutine acc_copyout_array_h (a)
   use openacc_internal, only: acc_copyout_l
-  type (*), dimension (..), contiguous :: a
+  type (*), dimension (..) :: a
   call acc_copyout_l (a, sizeof (a))
 end subroutine
 
@@ -1514,7 +1514,7 @@ end subroutine
 
 subroutine acc_copyout_finalize_array_h (a)
   use openacc_internal, only: acc_copyout_finalize_l
-  type (*), dimension (..), contiguous :: a
+  type (*), dimension (..) :: a
   call acc_copyout_finalize_l (a, sizeof (a))
 end subroutine
 
@@ -1546,7 +1546,7 @@ subroutine acc_copyout_finalize_async_array_h (a, async)
   use iso_c_binding, only: c_int
   use openacc_internal, only: acc_copyout_finalize_async_l
   use openacc_kinds, only: acc_handle_kind
-  type (*), dimension (..), contiguous :: a
+  type (*), dimension (..) :: a
   integer (acc_handle_kind) async
   call acc_copyout_finalize_async_l (a, sizeof (a), int (async, kind = c_int))
 end subroutine
@@ -1572,7 +1572,7 @@ end subroutine
 
 subroutine acc_delete_array_h (a)
   use openacc_internal, only: acc_delete_l
-  type (*), dimension (..), contiguous :: a
+  type (*), dimension (..) :: a
   call acc_delete_l (a, sizeof (a))
 end subroutine
 
@@ -1596,7 +1596,7 @@ end subroutine
 
 subroutine acc_delete_finalize_array_h (a)
   use openacc_internal, only: acc_delete_finalize_l
-  type (*), dimension (..), contiguous :: a
+  type (*), dimension (..) :: a
   call acc_delete_finalize_l (a, sizeof (a))
 end subroutine
 
@@ -1620,7 +1620,7 @@ end subroutine
 
 subroutine acc_update_device_array_h (a)
   use openacc_internal, only: acc_update_device_l
-  type (*), dimension (..), contiguous :: a
+  type (*), dimension (..) :: a
   call acc_update_device_l (a, sizeof (a))
 end subroutine
 
@@ -1644,7 +1644,7 @@ end subroutine
 
 subroutine acc_update_self_array_h (a)
   use openacc_internal, only: acc_update_self_l
-  type (*), dimension (..), contiguous :: a
+  type (*), dimension (..) :: a
   call acc_update_self_l (a, sizeof (a))
 end subroutine
 
@@ -1671,7 +1671,7 @@ end function
 function acc_is_present_array_h (a)
   use openacc_internal, only: acc_is_present_l
   logical acc_is_present_array_h
-  type (*), dimension (..), contiguous :: a
+  type (*), dimension (..) :: a
   acc_is_present_array_h = acc_is_present_l (a, sizeof (a)) /= 0
 end function
 
@@ -1701,7 +1701,7 @@ subroutine acc_copyin_async_array_h (a, async)
   use iso_c_binding, only: c_int
   use openacc_internal, only: acc_copyin_async_l
   use openacc_kinds, only: acc_handle_kind
-  type (*), dimension (..), contiguous :: a
+  type (*), dimension (..) :: a
   integer (acc_handle_kind) async
   call acc_copyin_async_l (a, sizeof (a), int (async, kind = c_int))
 end subroutine
@@ -1732,7 +1732,7 @@ subroutine acc_create_async_array_h (a, async)
   use iso_c_binding, only: c_int
   use openacc_internal, only: acc_create_async_l
   use openacc_kinds, only: acc_handle_kind
-  type (*), dimension (..), contiguous :: a
+  type (*), dimension (..) :: a
   integer (acc_handle_kind) async
   call acc_create_async_l (a, sizeof (a), int (async, kind = c_int))
 end subroutine
@@ -1763,7 +1763,7 @@ subroutine acc_copyout_async_array_h (a, async)
   use iso_c_binding, only: c_int
   use openacc_internal, only: acc_copyout_async_l
   use openacc_kinds, only: acc_handle_kind
-  type (*), dimension (..), contiguous :: a
+  type (*), dimension (..) :: a
   integer (acc_handle_kind) async
   call acc_copyout_async_l (a, sizeof (a), int (async, kind = c_int))
 end subroutine
@@ -1794,7 +1794,7 @@ subroutine acc_delete_async_array_h (a, async)
   use iso_c_binding, only: c_int
   use openacc_internal, only: acc_delete_async_l
   use openacc_kinds, only: acc_handle_kind
-  type (*), dimension (..), contiguous :: a
+  type (*), dimension (..) :: a
   integer (acc_handle_kind) async
   call acc_delete_async_l (a, sizeof (a), int (async, kind = c_int))
 end subroutine
@@ -1827,7 +1827,7 @@ subroutine acc_delete_finalize_async_array_h (a, async)
   use iso_c_binding, only: c_int
   use openacc_internal, only: acc_delete_finalize_async_l
   use openacc_kinds, only: acc_handle_kind
-  type (*), dimension (..), contiguous :: a
+  type (*), dimension (..) :: a
   integer (acc_handle_kind) async
   call acc_delete_finalize_async_l (a, sizeof (a), int (async, kind = c_int))
 end subroutine
@@ -1858,7 +1858,7 @@ subroutine acc_update_device_async_array_h (a, async)
   use iso_c_binding, only: c_int
   use openacc_internal, only: acc_update_device_async_l
   use openacc_kinds, only: acc_handle_kind
-  type (*), dimension (..), contiguous :: a
+  type (*), dimension (..) :: a
   integer (acc_handle_kind) async
   call acc_update_device_async_l (a, sizeof (a), int (async, kind = c_int))
 end subroutine
@@ -1889,7 +1889,7 @@ subroutine acc_update_self_async_array_h (a, async)
   use iso_c_binding, only: c_int
   use openacc_internal, only: acc_update_self_async_l
   use openacc_kinds, only: acc_handle_kind
-  type (*), dimension (..), contiguous :: a
+  type (*), dimension (..) :: a
   integer (acc_handle_kind) async
   call acc_update_self_async_l (a, sizeof (a), int (async, kind = c_int))
 end subroutine
diff --git a/libgomp/testsuite/libgomp.oacc-fortran/pr123280.f90 b/libgomp/testsuite/libgomp.oacc-fortran/pr123280.f90
new file mode 100644
index 00000000000..6ed6a714c30
--- /dev/null
+++ b/libgomp/testsuite/libgomp.oacc-fortran/pr123280.f90
@@ -0,0 +1,67 @@
+! PR libgomp/123280, PR libgomp/96080
+! { dg-do run }
+! { dg-skip-if "" { *-*-* } { "*" } { "-DACC_MEM_SHARED=0" } }
+!
+! Test that acc_is_present works correctly for assumed-shape dummy arguments
+! and Fortran pointers. Before the fix, these cases would create a copy
+! (due to the contiguous attribute), causing the lookup to fail.
+
+program pr123280
+  use openacc
+  implicit none
+
+  real, allocatable, target :: arr(:)
+  real, pointer :: ptr(:)
+  integer, parameter :: n = 100
+
+  allocate(arr(n))
+  arr = 1.0
+  ptr => arr
+
+  !$acc enter data copyin(arr)
+
+  ! Test 1: Direct check should pass
+  if (.not. acc_is_present(arr)) stop 1
+
+  ! Test 2: Check via subroutine with assumed-shape should pass
+  call check_assumed_shape(arr)
+
+  ! Test 3: Check via subroutine with explicit contiguous should pass
+  call check_contiguous(arr)
+
+  ! Test 4: Check pointer to mapped target (PR 96080)
+  if (.not. acc_is_present(ptr)) stop 4
+
+  ! Test 5: Check pointer in subroutine
+  call check_pointer(ptr)
+
+  ! Test 6: Check pointer passed as assumed-shape
+  call check_assumed_shape(ptr)
+
+  !$acc exit data delete(arr)
+
+contains
+
+  subroutine check_assumed_shape(x)
+    real, intent(in) :: x(:)
+
+    ! This used to fail because gfortran created a copy of the array
+    ! to satisfy the contiguous requirement in acc_is_present_array_h.
+    if (.not. acc_is_present(x)) stop 2
+  end subroutine check_assumed_shape
+
+  subroutine check_contiguous(x)
+    real, intent(in), contiguous :: x(:)
+
+    ! With explicit contiguous on the dummy, no copy should be needed.
+    if (.not. acc_is_present(x)) stop 3
+  end subroutine check_contiguous
+
+  subroutine check_pointer(p)
+    real, pointer, intent(in) :: p(:)
+
+    ! Pointer argument should detect mapped target (PR 96080).
+    if (.not. acc_is_present(p)) stop 5
+  end subroutine check_pointer
+
+end program pr123280
-- 
2.53.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.