On 3/31/20 5:35 PM, Jakub Jelinek via Gcc-patches wrote:

Doing the mappings separately is intentional, while for target data or
target region mappings it is very likely they will be all released together
as well, so it doesn't matter if they all go from the single same mapping,
for target enter data it is often not the case.
If everything is mapped together, then it can't be really freed until all
the mappings get refcount of 0.
So, instead of the change you've posted, there should be in
GOMP_target_enter_exit_data code to also handle GOMP_MAP_TO_PSET and put the
right number of mappings after it in one block and leave the rest separate.

Done in that way – including adding a rational comment :-)

OK for mainline?

Tobias

-----------------
Mentor Graphics (Deutschland) GmbH, Arnulfstraße 201, 80634 München / Germany
Registergericht München HRB 106955, Geschäftsführer: Thomas Heurung, Alexander 
Walter
libgomp – fix handling of 'target enter data'

	* target.c (GOMP_target_enter_exit_data): Handle PSET/MAP_POINTER.
	* testsuite/libgomp.fortran/target-enter-data-1.f90: New.

 libgomp/target.c                                   | 13 +++++++-
 .../libgomp.fortran/target-enter-data-1.f90        | 36 ++++++++++++++++++++++
 2 files changed, 48 insertions(+), 1 deletion(-)

diff --git a/libgomp/target.c b/libgomp/target.c
index c99dd5196fa..36425477dcb 100644
--- a/libgomp/target.c
+++ b/libgomp/target.c
@@ -2480,7 +2480,9 @@ GOMP_target_enter_exit_data (int device, size_t mapnum, void **hostaddrs,
 	}
     }
 
-  size_t i;
+  /* The variables are mapped separately such that they can be released
+     independently.  */
+  size_t i, j;
   if ((flags & GOMP_TARGET_FLAG_EXIT_DATA) == 0)
     for (i = 0; i < mapnum; i++)
       if ((kinds[i] & 0xff) == GOMP_MAP_STRUCT)
@@ -2489,6 +2491,15 @@ GOMP_target_enter_exit_data (int device, size_t mapnum, void **hostaddrs,
 			 &kinds[i], true, GOMP_MAP_VARS_ENTER_DATA);
 	  i += sizes[i];
 	}
+      else if ((kinds[i] & 0xff) == GOMP_MAP_TO_PSET)
+	{
+	  for (j = i + 1; j < mapnum; j++)
+	    if (!GOMP_MAP_POINTER_P (get_kind (true, kinds, j) & 0xff))
+	      break;
+	  gomp_map_vars (devicep, j-i, &hostaddrs[i], NULL, &sizes[i],
+			 &kinds[i], true, GOMP_MAP_VARS_ENTER_DATA);
+	  i += j - i - 1;
+	}
       else
 	gomp_map_vars (devicep, 1, &hostaddrs[i], NULL, &sizes[i], &kinds[i],
 		       true, GOMP_MAP_VARS_ENTER_DATA);
diff --git a/libgomp/testsuite/libgomp.fortran/target-enter-data-1.f90 b/libgomp/testsuite/libgomp.fortran/target-enter-data-1.f90
new file mode 100644
index 00000000000..91dedebf0a0
--- /dev/null
+++ b/libgomp/testsuite/libgomp.fortran/target-enter-data-1.f90
@@ -0,0 +1,36 @@
+program main
+  implicit none
+  integer, allocatable, dimension(:) :: AA, BB, CC, DD
+  integer :: i, N = 20
+
+  allocate(BB(N))
+  AA = [(i, i=1,N)]
+
+  !$omp target enter data map(alloc: BB)
+  !$omp target enter data map(to: AA)
+
+  !$omp target
+    BB = 3 * AA
+  !$omp end target
+
+  !$omp target exit data map(delete: AA)
+  !$omp target exit data map(from: BB)
+
+  if (any (BB /= [(3*i, i=1,N)])) stop 1
+  if (any (AA /= [(i, i=1,N)])) stop 2
+
+
+  CC = 31 * BB
+  DD = [(-i, i=1,N)]
+
+  !$omp target enter data map(to: CC) map(alloc: DD)
+
+  !$omp target
+    DD = 5 * CC
+  !$omp end target
+
+  !$omp target exit data map(delete: CC) map(from: DD)
+
+  if (any (CC /= [(31*3*i, i=1,N)])) stop 3
+  if (any (DD /= [(31*3*5*i, i=1,N)])) stop 4
+end

Reply via email to