I stumbled over the following: GCC misses* two OpenACC 2.5 functions
in Fortran but not in C; actually, when looking deeper at it,
.texi and .map already contain everything, just the actual
implementation (in openacc.f90) and the interface (in openacc.f90
and in openacc_lib.h) were missing.
The attached patch fixes this - and also updates the documentation
a bit. - I intent to commit the patch tomorrow, unless there are
comments.
Tobias
PS: r9-3877-g58168bbf6f8fb4 is the commit that added all those
memory-handling functions; except for the bare acc_{delete,copyout}_finalize,
which was already added in r9-1357-g829c6349e96c5b - both commits
implementing OpenACC 2.5 features.
(*) GCC misses some other OpenACC routines, but those are also missing
for C; additionally there are also some other C-only functions,
but that's in line with the spec. Example for a missing routine:
acc_{g,s}et_default_async (→ PR93225).
libgomp: Add Fortran version of acc_copyout_finalize_async and acc_delete_finalize_async
OpenACC 2.5 added several functions for C and Fortran; while
acc_{copyout,delete}{,_finalize,_async} exist for both, for some
reasons only the C version of acc_{copyout,delete}_finalize_async
was actually added, even though the documentation (.texi) and
the .map file listed also the auxiliar Fortran functions!
OpenACC 2.5 added the Fortran version with the following odd
interface: 'type, dimension(:[,:]...)'. In OpenACC 2.6, it
was then updated to the Fortran 2018 syntax:
'type(*), dimension(..)', which is also used in openacc.f90
internally.
This commit now also updates the documentation to the newer
syntax - plus fixes a function-name typo: acc_delete_async_finalize
should have the _async at the end not in the middle!
libgomp/ChangeLog:
* libgomp.map (OACC_2.5): Move previously unimplemented
acc_{copyout,delete}_finalize_async_{32,64,array}_h_ to ...
(OACC_2.6.1): ... here.
* libgomp.texi (acc_copyin, acc_present_or_copyin, acc_create,
acc_present_or_create, acc_copyout, acc_update_device,
acc_update_self, acc_is_present): Use 'type(*), dimension(..)'
instead of 'type, dimension(:[,:]...)' for Fortran.
(acc_delete): Likewise; change acc_delete_async_finalize to
acc_delete_finalize_async.
* openacc.f90 (openacc_internal): Add interfaces for
acc_{copyout,delete}_finalize_async_{{32,64,array}_h,_l}.
(openacc): Add generic interfaces for
acc_copyout_finalize_async and acc_delete_finalize_async.
(acc_{copyout,delete}_finalize_async_{32,64,array}_h): New.
* openacc_lib.h: Add generic interfaces for
acc_copyout_finalize_async and acc_delete_finalize_async.
* testsuite/libgomp.oacc-fortran/pr92970-1.f90: New test.
libgomp/libgomp.map | 12 +-
libgomp/libgomp.texi | 88 ++++++------
libgomp/openacc.f90 | 148 ++++++++++++++++++++-
libgomp/openacc_lib.h | 52 ++++++++
.../testsuite/libgomp.oacc-fortran/pr92970-1.f90 | 71 ++++++++++
5 files changed, 320 insertions(+), 51 deletions(-)
diff --git a/libgomp/libgomp.map b/libgomp/libgomp.map
index f6aee7c0394..67e08a37116 100644
--- a/libgomp/libgomp.map
+++ b/libgomp/libgomp.map
@@ -562,9 +562,6 @@ OACC_2.5 {
acc_copyout_finalize_64_h_;
acc_copyout_finalize_array_h_;
acc_copyout_finalize_async;
- acc_copyout_finalize_async_32_h_;
- acc_copyout_finalize_async_64_h_;
- acc_copyout_finalize_async_array_h_;
acc_create_async;
acc_create_async_32_h_;
acc_create_async_64_h_;
@@ -578,9 +575,6 @@ OACC_2.5 {
acc_delete_finalize_64_h_;
acc_delete_finalize_array_h_;
acc_delete_finalize_async;
- acc_delete_finalize_async_32_h_;
- acc_delete_finalize_async_64_h_;
- acc_delete_finalize_async_array_h_;
acc_memcpy_from_device_async;
acc_memcpy_to_device_async;
acc_update_device_async;
@@ -617,6 +611,12 @@ OACC_2.6 {
OACC_2.6.1 {
global:
+ acc_copyout_finalize_async_32_h_;
+ acc_copyout_finalize_async_64_h_;
+ acc_copyout_finalize_async_array_h_;
+ acc_delete_finalize_async_32_h_;
+ acc_delete_finalize_async_64_h_;
+ acc_delete_finalize_async_array_h_;
acc_memcpy_device;
acc_memcpy_device_async;
} OACC_2.6;
diff --git a/libgomp/libgomp.texi b/libgomp/libgomp.texi
index 5518033f1f3..73c8c3edace 100644
--- a/libgomp/libgomp.texi
+++ b/libgomp/libgomp.texi
@@ -5361,15 +5361,15 @@ variable or array element and @var{len} specifies the length in bytes.
@item @emph{Fortran}:
@multitable @columnfractions .20 .80
@item @emph{Interface}: @tab @code{subroutine acc_copyin(a)}
-@item @tab @code{type, dimension(:[,:]...) :: a}
+@item @tab @code{type(*), dimension(..) :: a}
@item @emph{Interface}: @tab @code{subroutine acc_copyin(a, len)}
-@item @tab @code{type, dimension(:[,:]...) :: a}
+@item @tab @code{type(*), dimension(..) :: a}
@item @tab @code{integer len}
@item @emph{Interface}: @tab @code{subroutine acc_copyin_async(a, async)}
-@item @tab @code{type, dimension(:[,:]...) :: a}
+@item @tab @code{type(*), dimension(..) :: a}
@item @tab @code{integer(acc_handle_kind) :: async}
@item @emph{Interface}: @tab @code{subroutine acc_copyin_async(a, len, async)}
-@item @tab @code{type, dimension(:[,:]...) :: a}
+@item @tab @code{type(*), dimension(..) :: a}
@item @tab @code{integer len}
@item @tab @code{integer(acc_handle_kind) :: async}
@end multitable
@@ -5406,14 +5406,14 @@ backward compatibility with OpenACC 2.0; use @ref{acc_copyin} instead.
@item @emph{Fortran}:
@multitable @columnfractions .20 .80
@item @emph{Interface}: @tab @code{subroutine acc_present_or_copyin(a)}
-@item @tab @code{type, dimension(:[,:]...) :: a}
+@item @tab @code{type(*), dimension(..) :: a}
@item @emph{Interface}: @tab @code{subroutine acc_present_or_copyin(a, len)}
-@item @tab @code{type, dimension(:[,:]...) :: a}
+@item @tab @code{type(*), dimension(..) :: a}
@item @tab @code{integer len}
@item @emph{Interface}: @tab @code{subroutine acc_pcopyin(a)}
-@item @tab @code{type, dimension(:[,:]...) :: a}
+@item @tab @code{type(*), dimension(..) :: a}
@item @emph{Interface}: @tab @code{subroutine acc_pcopyin(a, len)}
-@item @tab @code{type, dimension(:[,:]...) :: a}
+@item @tab @code{type(*), dimension(..) :: a}
@item @tab @code{integer len}
@end multitable
@@ -5445,15 +5445,15 @@ array element and @var{len} specifies the length in bytes.
@item @emph{Fortran}:
@multitable @columnfractions .20 .80
@item @emph{Interface}: @tab @code{subroutine acc_create(a)}
-@item @tab @code{type, dimension(:[,:]...) :: a}
+@item @tab @code{type(*), dimension(..) :: a}
@item @emph{Interface}: @tab @code{subroutine acc_create(a, len)}
-@item @tab @code{type, dimension(:[,:]...) :: a}
+@item @tab @code{type(*), dimension(..) :: a}
@item @tab @code{integer len}
@item @emph{Interface}: @tab @code{subroutine acc_create_async(a, async)}
-@item @tab @code{type, dimension(:[,:]...) :: a}
+@item @tab @code{type(*), dimension(..) :: a}
@item @tab @code{integer(acc_handle_kind) :: async}
@item @emph{Interface}: @tab @code{subroutine acc_create_async(a, len, async)}
-@item @tab @code{type, dimension(:[,:]...) :: a}
+@item @tab @code{type(*), dimension(..) :: a}
@item @tab @code{integer len}
@item @tab @code{integer(acc_handle_kind) :: async}
@end multitable
@@ -5490,14 +5490,14 @@ backward compatibility with OpenACC 2.0; use @ref{acc_create} instead.
@item @emph{Fortran}:
@multitable @columnfractions .20 .80
@item @emph{Interface}: @tab @code{subroutine acc_present_or_create(a)}
-@item @tab @code{type, dimension(:[,:]...) :: a}
+@item @tab @code{type(*), dimension(..) :: a}
@item @emph{Interface}: @tab @code{subroutine acc_present_or_create(a, len)}
-@item @tab @code{type, dimension(:[,:]...) :: a}
+@item @tab @code{type(*), dimension(..) :: a}
@item @tab @code{integer len}
@item @emph{Interface}: @tab @code{subroutine acc_pcreate(a)}
-@item @tab @code{type, dimension(:[,:]...) :: a}
+@item @tab @code{type(*), dimension(..) :: a}
@item @emph{Interface}: @tab @code{subroutine acc_pcreate(a, len)}
-@item @tab @code{type, dimension(:[,:]...) :: a}
+@item @tab @code{type(*), dimension(..) :: a}
@item @tab @code{integer len}
@end multitable
@@ -5530,27 +5530,27 @@ array element and @var{len} specifies the length in bytes.
@item @emph{Fortran}:
@multitable @columnfractions .20 .80
@item @emph{Interface}: @tab @code{subroutine acc_copyout(a)}
-@item @tab @code{type, dimension(:[,:]...) :: a}
+@item @tab @code{type(*), dimension(..) :: a}
@item @emph{Interface}: @tab @code{subroutine acc_copyout(a, len)}
-@item @tab @code{type, dimension(:[,:]...) :: a}
+@item @tab @code{type(*), dimension(..) :: a}
@item @tab @code{integer len}
@item @emph{Interface}: @tab @code{subroutine acc_copyout_async(a, async)}
-@item @tab @code{type, dimension(:[,:]...) :: a}
+@item @tab @code{type(*), dimension(..) :: a}
@item @tab @code{integer(acc_handle_kind) :: async}
@item @emph{Interface}: @tab @code{subroutine acc_copyout_async(a, len, async)}
-@item @tab @code{type, dimension(:[,:]...) :: a}
+@item @tab @code{type(*), dimension(..) :: a}
@item @tab @code{integer len}
@item @tab @code{integer(acc_handle_kind) :: async}
@item @emph{Interface}: @tab @code{subroutine acc_copyout_finalize(a)}
-@item @tab @code{type, dimension(:[,:]...) :: a}
+@item @tab @code{type(*), dimension(..) :: a}
@item @emph{Interface}: @tab @code{subroutine acc_copyout_finalize(a, len)}
-@item @tab @code{type, dimension(:[,:]...) :: a}
+@item @tab @code{type(*), dimension(..) :: a}
@item @tab @code{integer len}
@item @emph{Interface}: @tab @code{subroutine acc_copyout_finalize_async(a, async)}
-@item @tab @code{type, dimension(:[,:]...) :: a}
+@item @tab @code{type(*), dimension(..) :: a}
@item @tab @code{integer(acc_handle_kind) :: async}
@item @emph{Interface}: @tab @code{subroutine acc_copyout_finalize_async(a, len, async)}
-@item @tab @code{type, dimension(:[,:]...) :: a}
+@item @tab @code{type(*), dimension(..) :: a}
@item @tab @code{integer len}
@item @tab @code{integer(acc_handle_kind) :: async}
@end multitable
@@ -5584,27 +5584,27 @@ array element and @var{len} specifies the length in bytes.
@item @emph{Fortran}:
@multitable @columnfractions .20 .80
@item @emph{Interface}: @tab @code{subroutine acc_delete(a)}
-@item @tab @code{type, dimension(:[,:]...) :: a}
+@item @tab @code{type(*), dimension(..) :: a}
@item @emph{Interface}: @tab @code{subroutine acc_delete(a, len)}
-@item @tab @code{type, dimension(:[,:]...) :: a}
+@item @tab @code{type(*), dimension(..) :: a}
@item @tab @code{integer len}
@item @emph{Interface}: @tab @code{subroutine acc_delete_async(a, async)}
-@item @tab @code{type, dimension(:[,:]...) :: a}
+@item @tab @code{type(*), dimension(..) :: a}
@item @tab @code{integer(acc_handle_kind) :: async}
@item @emph{Interface}: @tab @code{subroutine acc_delete_async(a, len, async)}
-@item @tab @code{type, dimension(:[,:]...) :: a}
+@item @tab @code{type(*), dimension(..) :: a}
@item @tab @code{integer len}
@item @tab @code{integer(acc_handle_kind) :: async}
@item @emph{Interface}: @tab @code{subroutine acc_delete_finalize(a)}
-@item @tab @code{type, dimension(:[,:]...) :: a}
+@item @tab @code{type(*), dimension(..) :: a}
@item @emph{Interface}: @tab @code{subroutine acc_delete_finalize(a, len)}
-@item @tab @code{type, dimension(:[,:]...) :: a}
+@item @tab @code{type(*), dimension(..) :: a}
@item @tab @code{integer len}
-@item @emph{Interface}: @tab @code{subroutine acc_delete_async_finalize(a, async)}
-@item @tab @code{type, dimension(:[,:]...) :: a}
+@item @emph{Interface}: @tab @code{subroutine acc_delete_finalize_async(a, async)}
+@item @tab @code{type(*), dimension(..) :: a}
@item @tab @code{integer(acc_handle_kind) :: async}
-@item @emph{Interface}: @tab @code{subroutine acc_delete_async_finalize(a, len, async)}
-@item @tab @code{type, dimension(:[,:]...) :: a}
+@item @emph{Interface}: @tab @code{subroutine acc_delete_finalize_async(a, len, async)}
+@item @tab @code{type(*), dimension(..) :: a}
@item @tab @code{integer len}
@item @tab @code{integer(acc_handle_kind) :: async}
@end multitable
@@ -5637,15 +5637,15 @@ array element and @var{len} specifies the length in bytes.
@item @emph{Fortran}:
@multitable @columnfractions .20 .80
@item @emph{Interface}: @tab @code{subroutine acc_update_device(a)}
-@item @tab @code{type, dimension(:[,:]...) :: a}
+@item @tab @code{type(*), dimension(..) :: a}
@item @emph{Interface}: @tab @code{subroutine acc_update_device(a, len)}
-@item @tab @code{type, dimension(:[,:]...) :: a}
+@item @tab @code{type(*), dimension(..) :: a}
@item @tab @code{integer len}
@item @emph{Interface}: @tab @code{subroutine acc_update_device_async(a, async)}
-@item @tab @code{type, dimension(:[,:]...) :: a}
+@item @tab @code{type(*), dimension(..) :: a}
@item @tab @code{integer(acc_handle_kind) :: async}
@item @emph{Interface}: @tab @code{subroutine acc_update_device_async(a, len, async)}
-@item @tab @code{type, dimension(:[,:]...) :: a}
+@item @tab @code{type(*), dimension(..) :: a}
@item @tab @code{integer len}
@item @tab @code{integer(acc_handle_kind) :: async}
@end multitable
@@ -5678,15 +5678,15 @@ array element and @var{len} specifies the length in bytes.
@item @emph{Fortran}:
@multitable @columnfractions .20 .80
@item @emph{Interface}: @tab @code{subroutine acc_update_self(a)}
-@item @tab @code{type, dimension(:[,:]...) :: a}
+@item @tab @code{type(*), dimension(..) :: a}
@item @emph{Interface}: @tab @code{subroutine acc_update_self(a, len)}
-@item @tab @code{type, dimension(:[,:]...) :: a}
+@item @tab @code{type(*), dimension(..) :: a}
@item @tab @code{integer len}
@item @emph{Interface}: @tab @code{subroutine acc_update_self_async(a, async)}
-@item @tab @code{type, dimension(:[,:]...) :: a}
+@item @tab @code{type(*), dimension(..) :: a}
@item @tab @code{integer(acc_handle_kind) :: async}
@item @emph{Interface}: @tab @code{subroutine acc_update_self_async(a, len, async)}
-@item @tab @code{type, dimension(:[,:]...) :: a}
+@item @tab @code{type(*), dimension(..) :: a}
@item @tab @code{integer len}
@item @tab @code{integer(acc_handle_kind) :: async}
@end multitable
@@ -5829,10 +5829,10 @@ a @code{false} is return to indicate the mapped memory is not present.
@item @emph{Fortran}:
@multitable @columnfractions .20 .80
@item @emph{Interface}: @tab @code{function acc_is_present(a)}
-@item @tab @code{type, dimension(:[,:]...) :: a}
+@item @tab @code{type(*), dimension(..) :: a}
@item @tab @code{logical acc_is_present}
@item @emph{Interface}: @tab @code{function acc_is_present(a, len)}
-@item @tab @code{type, dimension(:[,:]...) :: a}
+@item @tab @code{type(*), dimension(..) :: a}
@item @tab @code{integer len}
@item @tab @code{logical acc_is_present}
@end multitable
diff --git a/libgomp/openacc.f90 b/libgomp/openacc.f90
index 3f2db45617b..1d944275833 100644
--- a/libgomp/openacc.f90
+++ b/libgomp/openacc.f90
@@ -269,6 +269,30 @@ module openacc_internal
type (*), dimension (..), contiguous :: a
end subroutine
+ subroutine acc_copyout_finalize_async_32_h (a, len, async)
+ use iso_c_binding, only: c_int32_t
+ use openacc_kinds, only: acc_handle_kind
+ !GCC$ ATTRIBUTES NO_ARG_CHECK :: a
+ type (*), dimension (*) :: a
+ integer (c_int32_t) len
+ integer (acc_handle_kind) async
+ end subroutine
+
+ subroutine acc_copyout_finalize_async_64_h (a, len, async)
+ use iso_c_binding, only: c_int64_t
+ use openacc_kinds, only: acc_handle_kind
+ !GCC$ ATTRIBUTES NO_ARG_CHECK :: a
+ type (*), dimension (*) :: a
+ integer (c_int64_t) len
+ integer (acc_handle_kind) async
+ end subroutine
+
+ subroutine acc_copyout_finalize_async_array_h (a, async)
+ use openacc_kinds, only: acc_handle_kind
+ type (*), dimension (..), contiguous :: a
+ integer (acc_handle_kind) async
+ end subroutine
+
subroutine acc_delete_32_h (a, len)
use iso_c_binding, only: c_int32_t
!GCC$ ATTRIBUTES NO_ARG_CHECK :: a
@@ -458,6 +482,30 @@ module openacc_internal
integer (acc_handle_kind) async
end subroutine
+ subroutine acc_delete_finalize_async_32_h (a, len, async)
+ use iso_c_binding, only: c_int32_t
+ use openacc_kinds, only: acc_handle_kind
+ !GCC$ ATTRIBUTES NO_ARG_CHECK :: a
+ type (*), dimension (*) :: a
+ integer (c_int32_t) len
+ integer (acc_handle_kind) async
+ end subroutine
+
+ subroutine acc_delete_finalize_async_64_h (a, len, async)
+ use iso_c_binding, only: c_int64_t
+ use openacc_kinds, only: acc_handle_kind
+ !GCC$ ATTRIBUTES NO_ARG_CHECK :: a
+ type (*), dimension (*) :: a
+ integer (c_int64_t) len
+ integer (acc_handle_kind) async
+ end subroutine
+
+ subroutine acc_delete_finalize_async_array_h (a, async)
+ use openacc_kinds, only: acc_handle_kind
+ type (*), dimension (..), contiguous :: a
+ integer (acc_handle_kind) async
+ end subroutine
+
subroutine acc_update_device_async_32_h (a, len, async)
use iso_c_binding, only: c_int32_t
use openacc_kinds, only: acc_handle_kind
@@ -663,6 +711,15 @@ module openacc_internal
integer (c_size_t), value :: len
end subroutine
+ subroutine acc_copyout_finalize_async_l (a, len, async) &
+ bind (C, name = "acc_copyout_finalize_async")
+ use iso_c_binding, only: c_size_t, c_int
+ !GCC$ ATTRIBUTES NO_ARG_CHECK :: a
+ type (*), dimension (*) :: a
+ integer (c_size_t), value :: len
+ integer (c_int), value :: async
+ end subroutine
+
subroutine acc_delete_l (a, len) &
bind (C, name = "acc_delete")
use iso_c_binding, only: c_size_t
@@ -679,6 +736,15 @@ module openacc_internal
integer (c_size_t), value :: len
end subroutine
+ subroutine acc_delete_finalize_async_l (a, len, async) &
+ bind (C, name = "acc_delete_finalize_async")
+ use iso_c_binding, only: c_size_t, c_int
+ !GCC$ ATTRIBUTES NO_ARG_CHECK :: a
+ type (*), dimension (*) :: a
+ integer (c_size_t), value :: len
+ integer (c_int), value :: async
+ end subroutine
+
subroutine acc_update_device_l (a, len) &
bind (C, name = "acc_update_device")
use iso_c_binding, only: c_size_t
@@ -794,7 +860,8 @@ module openacc
public :: acc_deviceptr, acc_hostptr, acc_is_present
public :: acc_copyin_async, acc_create_async, acc_copyout_async
public :: acc_delete_async, acc_update_device_async, acc_update_self_async
- public :: acc_copyout_finalize, acc_delete_finalize
+ public :: acc_copyout_finalize, acc_copyout_finalize_async
+ public :: acc_delete_finalize, acc_delete_finalize_async
public :: acc_memcpy_to_device, acc_memcpy_to_device_async
public :: acc_memcpy_from_device, acc_memcpy_from_device_async
public :: acc_memcpy_device, acc_memcpy_device_async
@@ -946,6 +1013,12 @@ module openacc
procedure :: acc_copyout_finalize_array_h
end interface
+ interface acc_copyout_finalize_async
+ procedure :: acc_copyout_finalize_async_32_h
+ procedure :: acc_copyout_finalize_async_64_h
+ procedure :: acc_copyout_finalize_async_array_h
+ end interface
+
interface acc_delete
procedure :: acc_delete_32_h
procedure :: acc_delete_64_h
@@ -1136,6 +1209,12 @@ module openacc
procedure :: acc_delete_async_array_h
end interface
+ interface acc_delete_finalize_async
+ procedure :: acc_delete_finalize_async_32_h
+ procedure :: acc_delete_finalize_async_64_h
+ procedure :: acc_delete_finalize_async_array_h
+ end interface
+
interface acc_update_device_async
procedure :: acc_update_device_async_32_h
procedure :: acc_update_device_async_64_h
@@ -1439,6 +1518,40 @@ subroutine acc_copyout_finalize_array_h (a)
call acc_copyout_finalize_l (a, sizeof (a))
end subroutine
+subroutine acc_copyout_finalize_async_32_h (a, len, async)
+ use iso_c_binding, only: c_int32_t, c_size_t, c_int
+ use openacc_internal, only: acc_copyout_finalize_async_l
+ use openacc_kinds, only: acc_handle_kind
+ !GCC$ ATTRIBUTES NO_ARG_CHECK :: a
+ type (*), dimension (*) :: a
+ integer (c_int32_t) len
+ integer (acc_handle_kind) async
+ call acc_copyout_finalize_async_l (a, int (len, kind = c_size_t), &
+ int (async, kind = c_int))
+end subroutine
+
+subroutine acc_copyout_finalize_async_64_h (a, len, async)
+ use iso_c_binding, only: c_int64_t, c_size_t, c_int
+ use openacc_internal, only: acc_copyout_finalize_async_l
+ use openacc_kinds, only: acc_handle_kind
+ !GCC$ ATTRIBUTES NO_ARG_CHECK :: a
+ type (*), dimension (*) :: a
+ integer (c_int64_t) len
+ integer (acc_handle_kind) async
+ call acc_copyout_finalize_async_l (a, int (len, kind = c_size_t), &
+ int (async, kind = c_int))
+end subroutine
+
+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
+ integer (acc_handle_kind) async
+ call acc_copyout_finalize_async_l (a, sizeof (a), int (async, kind = c_int))
+end subroutine
+
+
subroutine acc_delete_32_h (a, len)
use iso_c_binding, only: c_int32_t, c_size_t
use openacc_internal, only: acc_delete_l
@@ -1686,6 +1799,39 @@ subroutine acc_delete_async_array_h (a, async)
call acc_delete_async_l (a, sizeof (a), int (async, kind = c_int))
end subroutine
+subroutine acc_delete_finalize_async_32_h (a, len, async)
+ use iso_c_binding, only: c_int32_t, c_size_t, c_int
+ use openacc_internal, only: acc_delete_finalize_async_l
+ use openacc_kinds, only: acc_handle_kind
+ !GCC$ ATTRIBUTES NO_ARG_CHECK :: a
+ type (*), dimension (*) :: a
+ integer (c_int32_t) len
+ integer (acc_handle_kind) async
+ call acc_delete_finalize_async_l (a, int (len, kind = c_size_t), &
+ int (async, kind = c_int))
+end subroutine
+
+subroutine acc_delete_finalize_async_64_h (a, len, async)
+ use iso_c_binding, only: c_int64_t, c_size_t, c_int
+ use openacc_internal, only: acc_delete_finalize_async_l
+ use openacc_kinds, only: acc_handle_kind
+ !GCC$ ATTRIBUTES NO_ARG_CHECK :: a
+ type (*), dimension (*) :: a
+ integer (c_int64_t) len
+ integer (acc_handle_kind) async
+ call acc_delete_finalize_async_l (a, int (len, kind = c_size_t),&
+ int (async, kind = c_int))
+end subroutine
+
+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
+ integer (acc_handle_kind) async
+ call acc_delete_finalize_async_l (a, sizeof (a), int (async, kind = c_int))
+end subroutine
+
subroutine acc_update_device_async_32_h (a, len, async)
use iso_c_binding, only: c_int32_t, c_size_t, c_int
use openacc_internal, only: acc_update_device_async_l
diff --git a/libgomp/openacc_lib.h b/libgomp/openacc_lib.h
index dbdc4d7bc40..d3eaaac392d 100644
--- a/libgomp/openacc_lib.h
+++ b/libgomp/openacc_lib.h
@@ -350,6 +350,32 @@
end subroutine
end interface
+ interface acc_copyout_finalize_async
+ subroutine acc_copyout_finalize_async_32_h (a, len, async)
+ use iso_c_binding, only: c_int32_t
+ import acc_handle_kind
+!GCC$ ATTRIBUTES NO_ARG_CHECK :: a
+ type (*), dimension (*) :: a
+ integer (c_int32_t) len
+ integer (acc_handle_kind) async
+ end subroutine
+
+ subroutine acc_copyout_finalize_async_64_h (a, len, async)
+ use iso_c_binding, only: c_int64_t
+ import acc_handle_kind
+!GCC$ ATTRIBUTES NO_ARG_CHECK :: a
+ type (*), dimension (*) :: a
+ integer (c_int64_t) len
+ integer (acc_handle_kind) async
+ end subroutine
+
+ subroutine acc_copyout_finalize_async_array_h (a, async_)
+ import acc_handle_kind
+ type (*), dimension (..), contiguous :: a
+ integer (acc_handle_kind) async_
+ end subroutine
+ end interface
+
interface acc_delete
subroutine acc_delete_32_h (a, len)
use iso_c_binding, only: c_int32_t
@@ -390,6 +416,32 @@
end subroutine
end interface
+ interface acc_delete_finalize_async
+ subroutine acc_delete_finalize_async_32_h (a, len, async)
+ use iso_c_binding, only: c_int32_t
+ import acc_handle_kind
+!GCC$ ATTRIBUTES NO_ARG_CHECK :: a
+ type (*), dimension (*) :: a
+ integer (c_int32_t) len
+ integer (acc_handle_kind) async
+ end subroutine
+
+ subroutine acc_delete_finalize_async_64_h (a, len, async)
+ use iso_c_binding, only: c_int64_t
+ import acc_handle_kind
+!GCC$ ATTRIBUTES NO_ARG_CHECK :: a
+ type (*), dimension (*) :: a
+ integer (c_int64_t) len
+ integer (acc_handle_kind) async
+ end subroutine
+
+ subroutine acc_delete_finalize_async_array_h (a, async_)
+ import acc_handle_kind
+ type (*), dimension (..), contiguous :: a
+ integer (acc_handle_kind) async_
+ end subroutine
+ end interface
+
interface acc_update_device
subroutine acc_update_device_32_h (a, len)
use iso_c_binding, only: c_int32_t
diff --git a/libgomp/testsuite/libgomp.oacc-fortran/pr92970-1.f90 b/libgomp/testsuite/libgomp.oacc-fortran/pr92970-1.f90
new file mode 100644
index 00000000000..d49b8ad2699
--- /dev/null
+++ b/libgomp/testsuite/libgomp.oacc-fortran/pr92970-1.f90
@@ -0,0 +1,71 @@
+! Verify that 'acc_delete' etc. on non-present data is a no-op.
+!
+! Fortran version to libgomp.oacc-c-c++-common/pr92970-1.c
+
+program main
+use openacc
+implicit none (type, external)
+
+integer :: a, b, async
+
+! Side remark: 'sizeof' is a GNU extension;
+! for standard conforming code, use c_sizeof or (in bits) storage_size.
+
+async = 0
+!$acc exit data copyout (a)
+ call acc_copyout (a, sizeof (a))
+!$acc exit data copyout (a) async (async)
+ async = async + 1
+ call acc_copyout_async (a, sizeof (a), async)
+ async = async + 1
+!$acc exit data copyout (a) finalize
+ call acc_copyout_finalize (a, sizeof (a))
+!$acc exit data copyout (a) finalize async (async)
+ async = async + 1
+ call acc_copyout_finalize_async (a, sizeof (a), async)
+ async = async + 1
+
+!$acc exit data delete (a)
+ call acc_delete (a, sizeof (a))
+!$acc exit data delete (a) async (async)
+ async = async + 1
+ call acc_delete_async (a, sizeof (a), async)
+ async = async + 1
+!$acc exit data delete (a) finalize
+ call acc_delete_finalize (a, sizeof (a))
+!$acc exit data delete (a) finalize async (async)
+ async = async + 1
+ call acc_delete_finalize_async (a, sizeof (a), async)
+ async = async + 1
+
+
+! Same but taking the byesize from the argument
+
+!$acc exit data copyout (b)
+ call acc_copyout (b)
+!$acc exit data copyout (b) async (async)
+ async = async + 1
+ call acc_copyout_async (b, async)
+ async = async + 1
+!$acc exit data copyout (b) finalize
+ call acc_copyout_finalize (b)
+!$acc exit data copyout (b) finalize async (async)
+ async = async + 1
+ call acc_copyout_finalize_async (b, async)
+ async = async + 1
+
+!$acc exit data delete (b)
+ call acc_delete (b)
+!$acc exit data delete (b) async (async)
+ async = async + 1
+ call acc_delete_async (b, async)
+ async = async + 1
+!$acc exit data delete (b) finalize
+ call acc_delete_finalize (b)
+!$acc exit data delete (b) finalize async (async)
+ async = async + 1
+ call acc_delete_finalize_async (b, async)
+ async = async + 1
+
+ call acc_wait_all ()
+end