public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc/devel/omp/gcc-12] libgomp: Fix USM bugs
@ 2022-12-16 11:28 Andrew Stubbs
  0 siblings, 0 replies; only message in thread
From: Andrew Stubbs @ 2022-12-16 11:28 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:2ab62864c292f5d1d8b5a499cdf434346d46a924

commit 2ab62864c292f5d1d8b5a499cdf434346d46a924
Author: Andrew Stubbs <ams@codesourcery.com>
Date:   Fri Dec 2 16:37:58 2022 +0000

    libgomp: Fix USM bugs
    
    Fix up some USM corner cases.
    
    libgomp/ChangeLog:
    
            * libgomp.h (OFFSET_USM): New macro.
            * target.c (gomp_map_pointer): Handle USM mappings.
            (gomp_map_val): Handle OFFSET_USM.
            (gomp_map_vars_internal): Move USM check earlier, and use OFFSET_USM.
            Add OFFSET_USM check to the second mapping pass.
            * testsuite/libgomp.fortran/usm-1.f90: New test.
            * testsuite/libgomp.fortran/usm-2.f90: New test.

Diff:
---
 libgomp/ChangeLog.omp                       | 10 +++++++++
 libgomp/libgomp.h                           |  1 +
 libgomp/target.c                            | 25 ++++++++++++++--------
 libgomp/testsuite/libgomp.fortran/usm-1.f90 | 28 ++++++++++++++++++++++++
 libgomp/testsuite/libgomp.fortran/usm-2.f90 | 33 +++++++++++++++++++++++++++++
 5 files changed, 88 insertions(+), 9 deletions(-)

diff --git a/libgomp/ChangeLog.omp b/libgomp/ChangeLog.omp
index a0d0271f63b..068f4810100 100644
--- a/libgomp/ChangeLog.omp
+++ b/libgomp/ChangeLog.omp
@@ -1,3 +1,13 @@
+2022-12-16  Andrew Stubbs  <ams@codesourcery.com>
+
+	* libgomp.h (OFFSET_USM): New macro.
+	* target.c (gomp_map_pointer): Handle USM mappings.
+	(gomp_map_val): Handle OFFSET_USM.
+	(gomp_map_vars_internal): Move USM check earlier, and use OFFSET_USM.
+	Add OFFSET_USM check to the second mapping pass.
+	* testsuite/libgomp.fortran/usm-1.f90: New test.
+	* testsuite/libgomp.fortran/usm-2.f90: New test.
+
 2022-12-13  Marcel Vollweiler  <marcel@codesourcery.com>
 
 	* target.c (omp_target_is_accessible): Handle unified shared memory.
diff --git a/libgomp/libgomp.h b/libgomp/libgomp.h
index e5345ebee53..7d55f3cf825 100644
--- a/libgomp/libgomp.h
+++ b/libgomp/libgomp.h
@@ -1196,6 +1196,7 @@ struct target_mem_desc;
 #define OFFSET_INLINED (~(uintptr_t) 0)
 #define OFFSET_POINTER (~(uintptr_t) 1)
 #define OFFSET_STRUCT (~(uintptr_t) 2)
+#define OFFSET_USM (~(uintptr_t) 3)
 
 /* Auxiliary structure for infrequently-used or API-specific data.  */
 
diff --git a/libgomp/target.c b/libgomp/target.c
index 2cd8e2a65dd..cda53d636d1 100644
--- a/libgomp/target.c
+++ b/libgomp/target.c
@@ -692,6 +692,9 @@ gomp_map_pointer (struct target_mem_desc *tgt, struct goacc_asyncqueue *aq,
     {
       if (allow_zero_length_array_sections)
 	cur_node.tgt_offset = 0;
+      else if (devicep->is_usm_ptr_func
+	       && devicep->is_usm_ptr_func ((void*)cur_node.host_start))
+	cur_node.tgt_offset = cur_node.host_start;
       else
 	{
 	  gomp_mutex_unlock (&devicep->lock);
@@ -928,6 +931,7 @@ gomp_map_val (struct target_mem_desc *tgt, void **hostaddrs, size_t i)
   switch (tgt->list[i].offset)
     {
     case OFFSET_INLINED:
+    case OFFSET_USM:
       return (uintptr_t) hostaddrs[i];
 
     case OFFSET_POINTER:
@@ -1013,6 +1017,7 @@ gomp_map_vars_internal (struct gomp_device_descr *devicep,
     {
       int kind = get_kind (short_mapkind, kinds, i);
       bool implicit = get_implicit (short_mapkind, kinds, i);
+      tgt->list[i].offset = 0;
       if (hostaddrs[i] == NULL
 	  || (kind & typemask) == GOMP_MAP_FIRSTPRIVATE_INT)
 	{
@@ -1020,6 +1025,15 @@ gomp_map_vars_internal (struct gomp_device_descr *devicep,
 	  tgt->list[i].offset = OFFSET_INLINED;
 	  continue;
 	}
+      else if (devicep->is_usm_ptr_func
+	       && devicep->is_usm_ptr_func (hostaddrs[i]))
+	{
+	  /* The memory is visible from both host and target
+	     so nothing needs to be moved.  */
+	  tgt->list[i].key = NULL;
+	  tgt->list[i].offset = OFFSET_USM;
+	  continue;
+	}
       else if ((kind & typemask) == GOMP_MAP_USE_DEVICE_PTR
 	       || (kind & typemask) == GOMP_MAP_USE_DEVICE_PTR_IF_PRESENT)
 	{
@@ -1063,15 +1077,6 @@ gomp_map_vars_internal (struct gomp_device_descr *devicep,
 	    tgt->list[i].offset = 0;
 	  continue;
 	}
-      else if (devicep->is_usm_ptr_func
-	       && devicep->is_usm_ptr_func (hostaddrs[i]))
-	{
-	  /* The memory is visible from both host and target
-	     so nothing needs to be moved.  */
-	  tgt->list[i].key = NULL;
-	  tgt->list[i].offset = OFFSET_INLINED;
-	  continue;
-	}
       else if ((kind & typemask) == GOMP_MAP_STRUCT)
 	{
 	  size_t first = i + 1;
@@ -1441,6 +1446,8 @@ gomp_map_vars_internal (struct gomp_device_descr *devicep,
 	    bool implicit = get_implicit (short_mapkind, kinds, i);
 	    if (hostaddrs[i] == NULL)
 	      continue;
+	    if (tgt->list[i].offset == OFFSET_USM)
+	      continue;
 	    switch (kind & typemask)
 	      {
 		size_t align, len, first, last;
diff --git a/libgomp/testsuite/libgomp.fortran/usm-1.f90 b/libgomp/testsuite/libgomp.fortran/usm-1.f90
new file mode 100644
index 00000000000..7147e9925a2
--- /dev/null
+++ b/libgomp/testsuite/libgomp.fortran/usm-1.f90
@@ -0,0 +1,28 @@
+! { dg-do run }
+! { dg-require-effective-target omp_usm }
+
+! Ensure that USM works for implicit mappings.
+! This needs to cover both the initial mapping scan and the rescan that
+! happens when some of the mappings aren't no-ops (in this cases there are
+! some hidden pointers).
+
+program usm
+  use iso_fortran_env
+  use omp_lib
+  implicit none
+
+  !$omp requires unified_shared_memory
+
+  integer, parameter :: N = 1024
+  real(real64), allocatable :: x(:), y(:)
+  integer :: i
+
+  allocate(x(N), y(N))
+  !$omp target teams distribute parallel do simd
+  do i=1,N
+    y(i) = x(i)
+  enddo
+
+  deallocate(x,y)
+
+end program usm
diff --git a/libgomp/testsuite/libgomp.fortran/usm-2.f90 b/libgomp/testsuite/libgomp.fortran/usm-2.f90
new file mode 100644
index 00000000000..94e8284c475
--- /dev/null
+++ b/libgomp/testsuite/libgomp.fortran/usm-2.f90
@@ -0,0 +1,33 @@
+! { dg-do run }
+! { dg-require-effective-target omp_usm }
+
+! Ensure that USM doesn't break the use_device_ptr clause (host pointers and
+! target pointers being "unified").
+
+program usm
+  use iso_fortran_env
+  use omp_lib
+  implicit none
+
+  !$omp requires unified_shared_memory
+
+  integer, parameter :: N = 1024
+  real(real64), allocatable :: x(:), y(:)
+  integer :: i
+
+  allocate(x(N),y(N))
+
+  !$omp target data map(x)
+  ! The "i" variable is not explictly mapped yet, so ensures that both
+  ! mapping scan passes are tested.
+  !$omp target data map(i) use_device_ptr(x)
+  !$omp target teams distribute parallel do simd
+  do i=1,N
+    y(i) = x(i)
+  enddo
+  !$omp end target data 
+  !$omp end target data 
+
+  deallocate(x,y)
+
+end program usm

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2022-12-16 11:28 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-12-16 11:28 [gcc/devel/omp/gcc-12] libgomp: Fix USM bugs Andrew Stubbs

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).