OpenACC device-pointer lookup with globally-mapped variables (PR92888)

Message ID 20191212120741.08be278b@squid.athome
State New
Headers show
Series
  • OpenACC device-pointer lookup with globally-mapped variables (PR92888)
Related show

Commit Message

Julian Brown Dec. 12, 2019, 12:07 p.m.
Hi,

This patch provides a fix for PR92888, wherein global variables mapped
using an OpenACC 'declare' directive would not be visible to
device-pointer lookups.

Tested with offloading to nvptx. OK?

Thanks,

Julian

ChangeLog

2019-12-12  Julian Brown  <julian@codesourcery.com>

    PR libgomp/92888

    libgomp/
    * oacc-parallel.c (GOACC_parallel_keyed): Add tgt_start in target
    function address calculation.
    * target.c (gomp_load_image_to_device): Record address range for
    target_mem_desc for mapped functions and global variables, and adjust
    tgt_offsets to be within that range.
    (gomp_get_target_fn_addr): Add tgt_start in target function address
    calculation.
    * testsuite/libgomp.oacc-c-c++-common/acc_map_data-device_already-3.c:
    Remove XFAIL.

Patch

commit 16e774d2ce86af90ff282b9126cf615e66e7efae
Author: Julian Brown <julian@codesourcery.com>
Date:   Mon Dec 9 11:04:58 2019 -0800

    Find address range for offloaded functions and global variables (PR92888)
    
            PR libgomp/92888
    
            libgomp/
            * oacc-parallel.c (GOACC_parallel_keyed): Add tgt_start in target
            function address calculation.
            * target.c (gomp_load_image_to_device): Record address range for
            target_mem_desc for mapped functions and global variables, and adjust
            offsets to be within that range.
            (gomp_get_target_fn_addr): Add tgt_start in target function address
            calculation.
            * testsuite/libgomp.oacc-c-c++-common/acc_map_data-device_already-3.c:
            Remove XFAIL.

diff --git a/libgomp/oacc-parallel.c b/libgomp/oacc-parallel.c
index f5ef5050bbd..5a5697cf6e6 100644
--- a/libgomp/oacc-parallel.c
+++ b/libgomp/oacc-parallel.c
@@ -377,7 +377,7 @@  GOACC_parallel_keyed (int flags_m, void (*fn) (void *),
       if (tgt_fn_key == NULL)
 	gomp_fatal ("target function wasn't mapped");
 
-      tgt_fn = (void (*)) tgt_fn_key->tgt_offset;
+      tgt_fn = (void (*)) (tgt_fn_key->tgt->tgt_start + tgt_fn_key->tgt_offset);
     }
   else
     tgt_fn = (void (*)) fn;
diff --git a/libgomp/target.c b/libgomp/target.c
index bb392dd1c8f..b023e3daf1a 100644
--- a/libgomp/target.c
+++ b/libgomp/target.c
@@ -1759,6 +1759,8 @@  gomp_load_image_to_device (struct gomp_device_descr *devicep, unsigned version,
   tgt->device_descr = devicep;
   splay_tree_node array = tgt->array;
 
+  uintptr_t max_addr = 0, min_addr = ~(uintptr_t) 0;
+
   for (i = 0; i < num_funcs; i++)
     {
       splay_tree_key k = &array->key;
@@ -1766,6 +1768,10 @@  gomp_load_image_to_device (struct gomp_device_descr *devicep, unsigned version,
       k->host_end = k->host_start + 1;
       k->tgt = tgt;
       k->tgt_offset = target_table[i].start;
+      if (target_table[i].start < min_addr)
+	min_addr = target_table[i].start;
+      if (target_table[i].end > max_addr)
+	max_addr = target_table[i].end;
       k->refcount = REFCOUNT_INFINITY;
       k->virtual_refcount = 0;
       k->aux = NULL;
@@ -1799,6 +1805,10 @@  gomp_load_image_to_device (struct gomp_device_descr *devicep, unsigned version,
 	= k->host_start + (size_mask & (uintptr_t) host_var_table[i * 2 + 1]);
       k->tgt = tgt;
       k->tgt_offset = target_var->start;
+      if (target_var->start < min_addr)
+	min_addr = target_var->start;
+      if (target_var->end > max_addr)
+	max_addr = target_var->end;
       k->refcount = target_size & link_bit ? REFCOUNT_LINK : REFCOUNT_INFINITY;
       k->virtual_refcount = 0;
       k->aux = NULL;
@@ -1808,6 +1818,17 @@  gomp_load_image_to_device (struct gomp_device_descr *devicep, unsigned version,
       array++;
     }
 
+  /* Make the tgt_mem_desc cover all of the functions and variables so that
+     oacc-mem.c:lookup_dev can find mapped global variables properly.  */
+  tgt->tgt_start = min_addr;
+  tgt->tgt_end = max_addr;
+
+  for (array = tgt->array, i = 0; i < num_vars + num_funcs; i++, array++)
+    {
+      splay_tree_key k = &array->key;
+      k->tgt_offset -= min_addr;
+    }
+
   free (target_table);
 }
 
@@ -2170,7 +2191,7 @@  gomp_get_target_fn_addr (struct gomp_device_descr *devicep,
       if (tgt_fn == NULL)
 	return NULL;
 
-      return (void *) tgt_fn->tgt_offset;
+      return (void *) (tgt_fn->tgt->tgt_start + tgt_fn->tgt_offset);
     }
 }
 
diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/acc_map_data-device_already-3.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/acc_map_data-device_already-3.c
index 7cd2936219a..0807bc9d694 100644
--- a/libgomp/testsuite/libgomp.oacc-c-c++-common/acc_map_data-device_already-3.c
+++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/acc_map_data-device_already-3.c
@@ -24,5 +24,5 @@  main ()
 
 
 /* { dg-output "CheCKpOInT(\n|\r\n|\r).*" } */
-/* { dg-output "device address \\\[\[0-9a-fA-FxX\]+, \\\+8\\\] is already mapped" { xfail *-*-* } } TODO */
-/* { dg-shouldfail "TODO" { INV-AL-ID } } */
+/* { dg-output "device address \\\[\[0-9a-fA-FxX\]+, \\\+8\\\] is already mapped" } */
+/* { dg-shouldfail "" } */
diff --git a/libgomp/testsuite/libgomp.oacc-c-c++-common/pr92888-1.c b/libgomp/testsuite/libgomp.oacc-c-c++-common/pr92888-1.c
new file mode 100644
index 00000000000..0cd7f13656c
--- /dev/null
+++ b/libgomp/testsuite/libgomp.oacc-c-c++-common/pr92888-1.c
@@ -0,0 +1,19 @@ 
+/* Make sure that we can resolve back via 'acc_hostptr' an 'acc_deviceptr'
+   retrieved for a '#pragma acc declare'd variable.  */
+
+#include <assert.h>
+#include <openacc.h>
+
+double global_var;
+#pragma acc declare create (global_var)
+
+int
+main ()
+{
+  void *global_var_p_d = acc_deviceptr (&global_var);
+  assert (acc_hostptr (global_var_p_d) == &global_var);
+
+  return 0;
+}
+
+/* { dg-xfail-run-if "PR92888" { ! openacc_host_selected } } */