From 8b3f1edf9b38cb8a88c0a101a675d092bf6135d2 Mon Sep 17 00:00:00 2001 From: Tobias Burnus <tburnus@baylibre.com> Date: Tue, 27 Feb 2024 17:30:38 +0100 Subject: [PATCH] OpenACC: Add Fortran routines acc_{alloc,free,hostptr,deviceptr,memcpy_{to,from}_device*} These routines map simply to the C counterpart and are meanwhile defined in OpenACC 3.3. (There are additional routine changes, including the Fortran addition of acc_attach/acc_detach, that require more work than a simple addition of an interface and are therefore excluded.) libgomp/ChangeLog: * libgomp.texi (OpenACC Runtime Library Routines): Document new 3.3 routines that simply map to their C counterpart. * openacc.f90 (openacc): Add them. * openacc_lib.h: Likewise. * testsuite/libgomp.oacc-fortran/acc_host_device_ptr.f90: New test. * testsuite/libgomp.oacc-fortran/acc-memcpy.f90: New test. * testsuite/libgomp.oacc-fortran/acc-memcpy-2.f90: New test. * testsuite/libgomp.oacc-c-c++-common/lib-59.c: Crossref to f90 test. * testsuite/libgomp.oacc-c-c++-common/lib-60.c: Likewise. * testsuite/libgomp.oacc-c-c++-common/lib-95.c: Likewise. --- libgomp/libgomp.texi | 171 ++++++++++++++---- libgomp/openacc.f90 | 99 +++++++++- libgomp/openacc_lib.h | 94 +++++++++- .../libgomp.oacc-c-c++-common/lib-59.c | 2 + .../libgomp.oacc-c-c++-common/lib-60.c | 2 + .../libgomp.oacc-c-c++-common/lib-95.c | 2 + .../libgomp.oacc-fortran/acc-memcpy-2.f90 | 42 +++++ .../libgomp.oacc-fortran/acc-memcpy.f90 | 47 +++++ .../acc_host_device_ptr.f90 | 43 +++++ 9 files changed, 446 insertions(+), 56 deletions(-) create mode 100644 libgomp/testsuite/libgomp.oacc-fortran/acc-memcpy-2.f90 create mode 100644 libgomp/testsuite/libgomp.oacc-fortran/acc-memcpy.f90 create mode 100644 libgomp/testsuite/libgomp.oacc-fortran/acc_host_device_ptr.f90 diff --git a/libgomp/libgomp.texi b/libgomp/libgomp.texi index 0aea737350a7..bf5c7a76fc99 100644 --- a/libgomp/libgomp.texi +++ b/libgomp/libgomp.texi @@ -2157,8 +2157,6 @@ dimensions. Running this routine in a @code{target} region is not supported except on the initial device. - - @item @emph{C/C++} @multitable @columnfractions .20 .80 @item @emph{Prototype}: @tab @code{int omp_target_memcpy_rect_async(void *dst,} @@ -4684,7 +4682,6 @@ returns @code{false}. @item @tab @code{logical acc_on_device} @end multitable - @item @emph{Reference}: @uref{https://www.openacc.org, OpenACC specification v2.6}, section 3.2.17. @@ -4696,17 +4693,24 @@ returns @code{false}. @section @code{acc_malloc} -- Allocate device memory. @table @asis @item @emph{Description} -This function allocates @var{len} bytes of device memory. It returns +This function allocates @var{bytes} bytes of device memory. It returns the device address of the allocated memory. @item @emph{C/C++}: @multitable @columnfractions .20 .80 -@item @emph{Prototype}: @tab @code{d_void* acc_malloc(size_t len);} +@item @emph{Prototype}: @tab @code{d_void* acc_malloc(size_t bytes);} +@end multitable + +@item @emph{Fortran}: +@multitable @columnfractions .20 .80 +@item @emph{Interface}: @tab @code{type(c_ptr) function acc_malloc(bytes)} +@item @tab @code{integer(c_size_t), value :: bytes} @end multitable @item @emph{Reference}: @uref{https://www.openacc.org, OpenACC specification v2.6}, section -3.2.18. +3.2.18. @uref{https://www.openacc.org, openacc specification v3.3}, section +3.2.16. @end table @@ -4715,16 +4719,23 @@ the device address of the allocated memory. @section @code{acc_free} -- Free device memory. @table @asis @item @emph{Description} -Free previously allocated device memory at the device address @code{a}. +Free previously allocated device memory at the device address @code{data_dev}. @item @emph{C/C++}: @multitable @columnfractions .20 .80 -@item @emph{Prototype}: @tab @code{acc_free(d_void *a);} +@item @emph{Prototype}: @tab @code{void acc_free(d_void *data_dev);} +@end multitable + +@item @emph{Fortran}: +@multitable @columnfractions .20 .80 +@item @emph{Interface}: @tab @code{subroutine acc_free(data_dev)} +@item @tab @code{type(c_ptr), value :: data_dev} @end multitable @item @emph{Reference}: @uref{https://www.openacc.org, OpenACC specification v2.6}, section -3.2.19. +3.2.19. @uref{https://www.openacc.org, openacc specification v3.3}, section +3.2.17. @end table @@ -5092,17 +5103,26 @@ array element and @var{len} specifies the length in bytes. @table @asis @item @emph{Description} This function maps previously allocated device and host memory. The device -memory is specified with the device address @var{d}. The host memory is -specified with the host address @var{h} and a length of @var{len}. +memory is specified with the device address @var{data_dev}. The host memory is +specified with the host address @var{data_arg} and a length of @var{bytes}. @item @emph{C/C++}: @multitable @columnfractions .20 .80 -@item @emph{Prototype}: @tab @code{acc_map_data(h_void *h, d_void *d, size_t len);} +@item @emph{Prototype}: @tab @code{void acc_map_data(h_void *data_arg, d_void *data_dev, size_t bytes);} +@end multitable + +@item @emph{Fortran}: +@multitable @columnfractions .20 .80 +@item @emph{Interface}: @tab @code{subroutine acc_map_data(data_arg, data_dev, bytes)} +@item @tab @code{type(*), dimension(*) :: data_arg} +@item @tab @code{type(c_ptr), value :: data_dev} +@item @tab @code{integer(c_size_t), value :: bytes} @end multitable @item @emph{Reference}: @uref{https://www.openacc.org, OpenACC specification v2.6}, section -3.2.26. +3.2.26. @uref{https://www.openacc.org, OpenACC specification v3.3}, section +3.2.21. @end table @@ -5112,16 +5132,23 @@ specified with the host address @var{h} and a length of @var{len}. @table @asis @item @emph{Description} This function unmaps previously mapped device and host memory. The latter -specified by @var{h}. +specified by @var{data_arg}. @item @emph{C/C++}: @multitable @columnfractions .20 .80 -@item @emph{Prototype}: @tab @code{acc_unmap_data(h_void *h);} +@item @emph{Prototype}: @tab @code{void acc_unmap_data(h_void *data_arg);} +@end multitable + +@item @emph{Fortran}: +@multitable @columnfractions .20 .80 +@item @emph{Interface}: @tab @code{subroutine acc_unmap_data(data_arg)} +@item @tab @code{type(*), dimension(*) :: data_arg} @end multitable @item @emph{Reference}: @uref{https://www.openacc.org, OpenACC specification v2.6}, section -3.2.27. +3.2.27. @uref{https://www.openacc.org, OpenACC specification v3.3}, section +3.2.22. @end table @@ -5131,16 +5158,23 @@ specified by @var{h}. @table @asis @item @emph{Description} This function returns the device address that has been mapped to the -host address specified by @var{h}. +host address specified by @var{data_arg}. @item @emph{C/C++}: @multitable @columnfractions .20 .80 -@item @emph{Prototype}: @tab @code{void *acc_deviceptr(h_void *h);} +@item @emph{Prototype}: @tab @code{void *acc_deviceptr(h_void *data_arg);} +@end multitable + +@item @emph{Fortran}: +@multitable @columnfractions .20 .80 +@item @emph{Interface}: @tab @code{type(c_ptr) function acc_deviceptr(data_arg)} +@item @tab @code{type(*), dimension(*) :: data_arg} @end multitable @item @emph{Reference}: @uref{https://www.openacc.org, OpenACC specification v2.6}, section -3.2.28. +3.2.28. @uref{https://www.openacc.org, OpenACC specification v3.3}, section +3.2.23. @end table @@ -5150,16 +5184,23 @@ host address specified by @var{h}. @table @asis @item @emph{Description} This function returns the host address that has been mapped to the -device address specified by @var{d}. +device address specified by @var{data_dev}. @item @emph{C/C++}: @multitable @columnfractions .20 .80 -@item @emph{Prototype}: @tab @code{void *acc_hostptr(d_void *d);} +@item @emph{Prototype}: @tab @code{void *acc_hostptr(d_void *data_dev);} +@end multitable + +@item @emph{Fortran}: +@multitable @columnfractions .20 .80 +@item @emph{Interface}: @tab @code{type(c_ptr) function acc_hostptr(data_dev)} +@item @tab @code{type(c_ptr), value :: data_dev} @end multitable @item @emph{Reference}: @uref{https://www.openacc.org, OpenACC specification v2.6}, section -3.2.29. +3.2.29. @uref{https://www.openacc.org, OpenACC specification v3.3}, section +3.2.24. @end table @@ -5207,18 +5248,34 @@ a @code{false} is return to indicate the mapped memory is not present. @section @code{acc_memcpy_to_device} -- Copy host memory to device memory. @table @asis @item @emph{Description} -This function copies host memory specified by host address of @var{src} to -device memory specified by the device address @var{dest} for a length of -@var{bytes} bytes. +This function copies host memory specified by host address of +@var{data_host_src} to device memory specified by the device address +@var{data_dev_dest} for a length of @var{bytes} bytes. @item @emph{C/C++}: @multitable @columnfractions .20 .80 -@item @emph{Prototype}: @tab @code{acc_memcpy_to_device(d_void *dest, h_void *src, size_t bytes);} +@item @emph{Prototype}: @tab @code{void acc_memcpy_to_device(d_void* data_dev_dest,} +@item @tab @code{h_void* data_host_src, size_t bytes);} +@item @emph{Prototype}: @tab @code{void acc_memcpy_to_device_async(d_void* data_dev_dest,} +@item @tab @code{h_void* data_host_src, size_t bytes, int async_arg);} +@end multitable + +@item @emph{Fortran}: +@multitable @columnfractions .20 .80 +@item @emph{Interface}: @tab @code{subroutine acc_memcpy_to_device(data_dev_dest, &} +@item @tab @code{data_host_src, bytes)} +@item @emph{Interface}: @tab @code{subroutine acc_memcpy_to_device_async(data_dev_dest, &} +@item @tab @code{data_host_src, bytes, async_arg)} +@item @tab @code{type(c_ptr), value :: data_dev_dest} +@item @tab @code{type(*), dimension(*) :: data_host_src} +@item @tab @code{integer(c_size_t), value :: bytes} +@item @tab @code{integer(acc_handle_kind), value :: async_arg} @end multitable @item @emph{Reference}: @uref{https://www.openacc.org, OpenACC specification v2.6}, section -3.2.31. +3.2.31 @uref{https://www.openacc.org, OpenACC specification v3.3}, section +3.2.26. @end table @@ -5227,18 +5284,34 @@ device memory specified by the device address @var{dest} for a length of @section @code{acc_memcpy_from_device} -- Copy device memory to host memory. @table @asis @item @emph{Description} -This function copies host memory specified by host address of @var{src} from -device memory specified by the device address @var{dest} for a length of -@var{bytes} bytes. +This function copies device memory specified by device address of +@var{data_dev_src} to host memory specified by the host address +@var{data_host_dest} for a length of @var{bytes} bytes. @item @emph{C/C++}: @multitable @columnfractions .20 .80 -@item @emph{Prototype}: @tab @code{acc_memcpy_from_device(d_void *dest, h_void *src, size_t bytes);} +@item @emph{Prototype}: @tab @code{void acc_memcpy_from_device(h_void* data_host_dest,} +@item @tab @code{d_void* data_dev_src, size_t bytes);} +@item @emph{Prototype}: @tab @code{void acc_memcpy_from_device_async(h_void* data_host_dest,} +@item @tab @code{d_void* data_dev_src, size_t bytes, int async_arg);} +@end multitable + +@item @emph{Fortran}: +@multitable @columnfractions .20 .80 +@item @emph{Interface}: @tab @code{subroutine acc_memcpy_from_device(data_host_dest, &} +@item @tab @code{data_dev_src, bytes)} +@item @emph{Interface}: @tab @code{subroutine acc_memcpy_from_device_async(data_host_dest, &} +@item @tab @code{data_dev_src, bytes, async_arg)} +@item @tab @code{type(*), dimension(*) :: data_host_dest} +@item @tab @code{type(c_ptr), value :: data_dev_src} +@item @tab @code{integer(c_size_t), value :: bytes} +@item @tab @code{integer(acc_handle_kind), value :: async_arg} @end multitable @item @emph{Reference}: @uref{https://www.openacc.org, OpenACC specification v2.6}, section -3.2.32. +3.2.32. @uref{https://www.openacc.org, OpenACC specification v3.3}, section +3.2.27. @end table @@ -5252,13 +5325,23 @@ address to pointing to the corresponding device data. @item @emph{C/C++}: @multitable @columnfractions .20 .80 -@item @emph{Prototype}: @tab @code{acc_attach(h_void **ptr);} -@item @emph{Prototype}: @tab @code{acc_attach_async(h_void **ptr, int async);} +@item @emph{Prototype}: @tab @code{void acc_attach(h_void **ptr_addr);} +@item @emph{Prototype}: @tab @code{void acc_attach_async(h_void **ptr_addr, int async);} @end multitable +@c @item @emph{Fortran}: +@c @multitable @columnfractions .20 .80 +@c @item @emph{Interface}: @tab @code{subroutine acc_attach(ptr_addr)} +@c @item @emph{Interface}: @tab @code{subroutine acc_attach_async(ptr_addr, async_arg)} +@c @item @tab @code{type(*), dimension(..) :: ptr_addr} +@c @item @tab @code{integer(acc_handle_kind), value :: async_arg} +@c @end multitable + @item @emph{Reference}: @uref{https://www.openacc.org, OpenACC specification v2.6}, section 3.2.34. +@c @uref{https://www.openacc.org, OpenACC specification v3.3}, section +@c 3.2.29. @end table @@ -5272,15 +5355,27 @@ address to pointing to the corresponding host data. @item @emph{C/C++}: @multitable @columnfractions .20 .80 -@item @emph{Prototype}: @tab @code{acc_detach(h_void **ptr);} -@item @emph{Prototype}: @tab @code{acc_detach_async(h_void **ptr, int async);} -@item @emph{Prototype}: @tab @code{acc_detach_finalize(h_void **ptr);} -@item @emph{Prototype}: @tab @code{acc_detach_finalize_async(h_void **ptr, int async);} +@item @emph{Prototype}: @tab @code{void acc_detach(h_void **ptr_addr);} +@item @emph{Prototype}: @tab @code{void acc_detach_async(h_void **ptr_addr, int async);} +@item @emph{Prototype}: @tab @code{void acc_detach_finalize(h_void **ptr_addr);} +@item @emph{Prototype}: @tab @code{void acc_detach_finalize_async(h_void **ptr_addr, int async);} @end multitable +@c @item @emph{Fortran}: +@c @multitable @columnfractions .20 .80 +@c @item @emph{Interface}: @tab @code{subroutine acc_detach(ptr_addr)} +@c @item @emph{Interface}: @tab @code{subroutine acc_detach_async(ptr_addr, async_arg)} +@c @item @emph{Interface}: @tab @code{subroutine acc_detach_finalize(ptr_addr)} +@c @item @emph{Interface}: @tab @code{subroutine acc_detach_finalize_async(ptr_addr, async_arg)} +@c @item @tab @code{type(*), dimension(..) :: ptr_addr} +@c @item @tab @code{integer(acc_handle_kind), value :: async_arg} +@c @end multitable + @item @emph{Reference}: @uref{https://www.openacc.org, OpenACC specification v2.6}, section 3.2.35. +@c @uref{https://www.openacc.org, OpenACC specification v3.3}, section +@c 3.2.29. @end table diff --git a/libgomp/openacc.f90 b/libgomp/openacc.f90 index 7270653a98a9..4e24ee46a977 100644 --- a/libgomp/openacc.f90 +++ b/libgomp/openacc.f90 @@ -787,13 +787,16 @@ module openacc public :: acc_async_test, acc_async_test_all public :: acc_wait, acc_async_wait, acc_wait_async public :: acc_wait_all, acc_async_wait_all, acc_wait_all_async - public :: acc_init, acc_shutdown, acc_on_device + public :: acc_init, acc_shutdown, acc_on_device, acc_malloc, acc_free public :: acc_copyin, acc_present_or_copyin, acc_pcopyin, acc_create public :: acc_present_or_create, acc_pcreate, acc_copyout, acc_delete - public :: acc_update_device, acc_update_self, acc_is_present + public :: acc_update_device, acc_update_self, acc_map_data, acc_unmap_data + 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_memcpy_to_device, acc_memcpy_to_device_async + public :: acc_memcpy_from_device, acc_memcpy_from_device_async integer, parameter :: openacc_version = 201711 @@ -871,8 +874,19 @@ module openacc procedure :: acc_on_device_h end interface - ! acc_malloc: Only available in C/C++ - ! acc_free: Only available in C/C++ + interface + type(c_ptr) function acc_malloc (bytes) bind(C) + use iso_c_binding, only: c_ptr, c_size_t + integer(c_size_t), value :: bytes + end function + end interface + + interface + subroutine acc_free (data_dev) bind(C) + use iso_c_binding, only: c_ptr + type(c_ptr), value :: data_dev + end subroutine + end interface ! As vendor extension, the following code supports both 32bit and 64bit ! arguments for "size"; the OpenACC standard only permits default-kind @@ -953,10 +967,34 @@ module openacc procedure :: acc_update_self_array_h end interface - ! acc_map_data: Only available in C/C++ - ! acc_unmap_data: Only available in C/C++ - ! acc_deviceptr: Only available in C/C++ - ! acc_hostptr: Only available in C/C++ + interface + subroutine acc_map_data (data_arg, data_dev, bytes) bind(C) + use iso_c_binding, only: c_ptr, c_size_t + type(*), dimension(*) :: data_arg + type(c_ptr), value :: data_dev + integer(c_size_t), value :: bytes + end subroutine + end interface + + interface + subroutine acc_unmap_data (data_arg) bind(C) + type(*), dimension(*) :: data_arg + end subroutine + end interface + + interface + type(c_ptr) function acc_deviceptr (data_arg) bind(C) + use iso_c_binding, only: c_ptr + type(*), dimension(*) :: data_arg + end function + end interface + + interface + type(c_ptr) function acc_hostptr (data_dev) bind(C) + use iso_c_binding, only: c_ptr + type(c_ptr), value :: data_dev + end function + end interface interface acc_is_present procedure :: acc_is_present_32_h @@ -964,8 +1002,49 @@ module openacc procedure :: acc_is_present_array_h end interface - ! acc_memcpy_to_device: Only available in C/C++ - ! acc_memcpy_from_device: Only available in C/C++ + interface + subroutine acc_memcpy_to_device (data_dev_dest, data_host_src, & + bytes) bind(C) + use iso_c_binding, only: c_ptr, c_size_t + type(c_ptr), value :: data_dev_dest + type(*),dimension(*) :: data_host_src + integer(c_size_t), value :: bytes + end subroutine + end interface + + interface + subroutine acc_memcpy_to_device_async (data_dev_dest, data_host_src, & + bytes, async_arg) bind(C) + use iso_c_binding, only: c_ptr, c_size_t + import :: acc_handle_kind + type(c_ptr), value :: data_dev_dest + type(*),dimension(*) :: data_host_src + integer(c_size_t), value :: bytes + integer(acc_handle_kind), value :: async_arg + end subroutine + end interface + + interface + subroutine acc_memcpy_from_device (data_host_dest, data_dev_src, & + bytes) bind(C) + use iso_c_binding, only: c_ptr, c_size_t + type(*),dimension(*) :: data_host_dest + type(c_ptr), value :: data_dev_src + integer(c_size_t), value :: bytes + end subroutine + end interface + + interface + subroutine acc_memcpy_from_device_async (data_host_dest, data_dev_src, & + bytes, async_arg) bind(C) + use iso_c_binding, only: c_ptr, c_size_t + import :: acc_handle_kind + type(*),dimension(*) :: data_host_dest + type(c_ptr), value :: data_dev_src + integer(c_size_t), value :: bytes + integer(acc_handle_kind), value :: async_arg + end subroutine + end interface interface acc_copyin_async procedure :: acc_copyin_async_32_h diff --git a/libgomp/openacc_lib.h b/libgomp/openacc_lib.h index dfbf0a75a8f1..913c3f1aa3dc 100644 --- a/libgomp/openacc_lib.h +++ b/libgomp/openacc_lib.h @@ -204,8 +204,19 @@ end function end interface - ! acc_malloc: Only available in C/C++ - ! acc_free: Only available in C/C++ + interface + type(c_ptr) function acc_malloc(bytes) bind(C) + use iso_c_binding, only: c_ptr, c_size_t + integer(c_size_t), value :: bytes + end function + end interface + + interface + subroutine acc_free(data_dev) bind(C) + use iso_c_binding, only: c_ptr + type(c_ptr), value :: data_dev + end subroutine + end interface interface acc_copyin subroutine acc_copyin_32_h (a, len) @@ -419,10 +430,34 @@ end subroutine end interface - ! acc_map_data: Only available in C/C++ - ! acc_unmap_data: Only available in C/C++ - ! acc_deviceptr: Only available in C/C++ - ! acc_hostptr: Only available in C/C++ + interface + subroutine acc_map_data(data_arg, data_dev, bytes) bind(C) + use iso_c_binding, only: c_ptr, c_size_t + type(*), dimension(*) :: data_arg + type(c_ptr), value :: data_dev + integer(c_size_t), value :: bytes + end subroutine + end interface + + interface + subroutine acc_unmap_data(data_arg) bind(C) + type(*), dimension(*) :: data_arg + end subroutine + end interface + + interface + type(c_ptr) function acc_deviceptr(data_arg) bind(C) + use iso_c_binding, only: c_ptr + type(*), dimension(*) :: data_arg + end function + end interface + + interface + type(c_ptr) function acc_hostptr(data_dev) bind(C) + use iso_c_binding, only: c_ptr + type(c_ptr), value :: data_dev + end function + end interface interface acc_is_present function acc_is_present_32_h (a, len) @@ -447,8 +482,51 @@ end function end interface - ! acc_memcpy_to_device: Only available in C/C++ - ! acc_memcpy_from_device: Only available in C/C++ + interface + subroutine acc_memcpy_to_device(data_dev_dest, data_host_src, & + & bytes) bind(C) + use iso_c_binding, only: c_ptr, c_size_t + type(c_ptr), value :: data_dev_dest + type(*),dimension(*) :: data_host_src + integer(c_size_t), value :: bytes + end subroutine + end interface + + interface + subroutine acc_memcpy_to_device_async(data_dev_dest, & + & data_host_src, bytes, & + & async_arg) bind(C) + use iso_c_binding, only: c_ptr, c_size_t + import :: acc_handle_kind + type(c_ptr), value :: data_dev_dest + type(*),dimension(*) :: data_host_src + integer(c_size_t), value :: bytes + integer(acc_handle_kind), value :: async_arg + end subroutine + end interface + + interface + subroutine acc_memcpy_from_device(data_host_dest, & + & data_dev_src, bytes) bind(C) + use iso_c_binding, only: c_ptr, c_size_t + type(*),dimension(*) :: data_host_dest + type(c_ptr), value :: data_dev_src + integer(c_size_t), value :: bytes + end subroutine + end interface + + interface + subroutine acc_memcpy_from_device_async(data_host_dest, & + & data_dev_src, bytes, & + & async_arg) bind(C) + use iso_c_binding, only: c_ptr, c_size_t + import :: acc_handle_kind + type(*),dimension(*) :: data_host_dest + type(c_ptr), value :: data_dev_src + integer(c_size_t), value :: bytes + integer(acc_handle_kind), value :: async_arg + end subroutine + end interface interface acc_copyin_async subroutine acc_copyin_async_32_h (a, len, async) diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-59.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-59.c index 2f087aedccb1..323e3ff1fbf4 100644 --- a/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-59.c +++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-59.c @@ -1,6 +1,8 @@ /* { dg-do run } */ /* { dg-skip-if "" { *-*-* } { "*" } { "-DACC_MEM_SHARED=0" } } */ +/* Fortran testcase is at libgomp.oacc-fortran/acc_host_device_ptr.f90. */ + #include <stdlib.h> #include <openacc.h> #include <stdint.h> diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-60.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-60.c index ccae728e3dc1..70cbcb8b0130 100644 --- a/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-60.c +++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-60.c @@ -1,6 +1,8 @@ /* { dg-do run } */ /* { dg-skip-if "" { *-*-* } { "*" } { "-DACC_MEM_SHARED=0" } } */ +/* Fortran testcase is at libgomp.oacc-fortran/acc-memcpy.f90. */ + #include <string.h> #include <stdlib.h> #include <openacc.h> diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-95.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-95.c index 842fb849e79e..bcbb399a62b2 100644 --- a/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-95.c +++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/lib-95.c @@ -1,6 +1,8 @@ /* { dg-do run } */ /* { dg-skip-if "" { *-*-* } { "*" } { "-DACC_MEM_SHARED=0" } } */ +/* Fortran version at libgomp.oacc-fortran/acc-memcpy-2.f90. */ + #include <string.h> #include <stdlib.h> #include <openacc.h> diff --git a/libgomp/testsuite/libgomp.oacc-fortran/acc-memcpy-2.f90 b/libgomp/testsuite/libgomp.oacc-fortran/acc-memcpy-2.f90 new file mode 100644 index 000000000000..55a5907e91b0 --- /dev/null +++ b/libgomp/testsuite/libgomp.oacc-fortran/acc-memcpy-2.f90 @@ -0,0 +1,42 @@ +! { dg-do run } +! { dg-skip-if "" { *-*-* } { "*" } { "-DACC_MEM_SHARED=0" } } + +! Fortran version of libgomp.oacc-c-c++-common/lib-95.c + +program main + use iso_c_binding + use openacc + implicit none (type, external) + + integer(c_size_t), parameter :: N = 127 + integer(c_size_t) :: i + integer(acc_handle_kind) :: q = 5 + integer(kind=1), allocatable :: h(:), g(:) + type(c_ptr) :: d + + q = 5 + + allocate (h(-N:N), g(-N:N)) + do i = -N, N + g(i) = i + end do + + call acc_create_async (h, 2*N + 1, q) + + call acc_memcpy_to_device_async (acc_deviceptr (h), g, 2*N + 1, q) + + call acc_wait (q) + + h = 0 + + call acc_update_self_async (h, 2*N + 1, q + 1) + call acc_delete_async (h, 2*N + 1, q + 1) + + call acc_wait (q + 1) + + do i = -N, N + if (h(i) /= i) & + stop 1 + end do + deallocate (h, g) +end diff --git a/libgomp/testsuite/libgomp.oacc-fortran/acc-memcpy.f90 b/libgomp/testsuite/libgomp.oacc-fortran/acc-memcpy.f90 new file mode 100644 index 000000000000..670dc50ff071 --- /dev/null +++ b/libgomp/testsuite/libgomp.oacc-fortran/acc-memcpy.f90 @@ -0,0 +1,47 @@ +! { dg-do run } +! { dg-skip-if "" { *-*-* } { "*" } { "-DACC_MEM_SHARED=0" } } + +! based on libgomp.oacc-c-c++-common/lib-60.c + +program main + use openacc + use iso_fortran_env + use iso_c_binding + implicit none (type, external) + integer(int8), allocatable :: char(:) + type(c_ptr) :: dptr + integer(c_intptr_t) :: i + integer(int8) :: j + + allocate(char(-128:127)) + do i = -128, 127 + char(j) = int (j, int8) + end do + + dptr = acc_malloc (256_c_size_t) + call acc_memcpy_to_device (dptr, char, 255_c_size_t) + + do i = 0, 255 + if (acc_is_present (transfer (transfer(char, i) + i, dptr), 1)) & + stop 1 + end do + + char = 0_int8 + + call acc_memcpy_from_device (char, dptr, 256_c_size_t) + + do i = -128, 127 + char(i) = int (j, int8) + if (char(i) /= j) & + stop 2 + end do + + do i = 0, 255 + if (acc_is_present (transfer (transfer(char, i) + i, dptr), 1)) & + stop 3 + end do + + call acc_free (dptr) + + deallocate (char) +end diff --git a/libgomp/testsuite/libgomp.oacc-fortran/acc_host_device_ptr.f90 b/libgomp/testsuite/libgomp.oacc-fortran/acc_host_device_ptr.f90 new file mode 100644 index 000000000000..07d6386c6de1 --- /dev/null +++ b/libgomp/testsuite/libgomp.oacc-fortran/acc_host_device_ptr.f90 @@ -0,0 +1,43 @@ +! { dg-do run } +! { dg-skip-if "" { *-*-* } { "*" } { "-DACC_MEM_SHARED=0" } } + +! Fortran version of libgomp.oacc-c-c++-common/lib-59.c + +program main + use iso_c_binding + use openacc + implicit none (type, external) + + integer(c_size_t), parameter :: N = 256 + character(c_char), allocatable, target :: h_data(:) + type(c_ptr) :: dptr, dptr_t + integer(c_intptr_t) :: iptr, i + + allocate(h_data(0:N)) + dptr = acc_malloc (N+1) + + call acc_map_data (h_data, dptr, N+1) + + ! The following assumes sizeof(void*) being the same on host and device: + do i = 0, N + dptr_t = transfer (transfer(dptr, iptr) + i, dptr_t) + if (.not. c_associated (acc_hostptr (dptr_t), c_loc (h_data(i)))) & + stop 1 + if (.not. c_associated (dptr_t, acc_deviceptr (h_data(i)))) & + stop 2 + end do + + call acc_unmap_data (h_data) + + do i = 0, N + dptr_t = transfer (transfer(dptr, iptr) + i, dptr_t) + if (c_associated (acc_hostptr (dptr_t))) & + stop 3 + if (c_associated (acc_deviceptr (h_data(i)))) & + stop 4 + end do + + call acc_free (dptr) + + deallocate (h_data) +end -- GitLab