This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Fwd: [RFC][gomp4] Offloading patches (2/3): Add tables generation


On 28 Feb 17:21, Bernd Schmidt wrote:
> It would help to see the code you have on the libgomp side, I don't
> believe that's been posted yet?

It was posted here: http://gcc.gnu.org/ml/gcc-patches/2013-12/msg01777.html
And below is the updated version.

---
 libgomp/libgomp.map |    1 +
 libgomp/target.c    |  138 ++++++++++++++++++++++++++++++++++++++++++++++++---
 2 files changed, 132 insertions(+), 7 deletions(-)

diff --git a/libgomp/libgomp.map b/libgomp/libgomp.map
index cb52e45..d33673d 100644
--- a/libgomp/libgomp.map
+++ b/libgomp/libgomp.map
@@ -208,6 +208,7 @@ GOMP_3.0 {
 
 GOMP_4.0 {
   global:
+	GOMP_register_lib;
 	GOMP_barrier_cancel;
 	GOMP_cancel;
 	GOMP_cancellation_point;
diff --git a/libgomp/target.c b/libgomp/target.c
index a6a5505..7fafa9a 100644
--- a/libgomp/target.c
+++ b/libgomp/target.c
@@ -84,6 +84,19 @@ struct splay_tree_key_s {
   bool copy_from;
 };
 
+enum library_descr {
+  DESCR_TABLE_START,
+  DESCR_TABLE_END,
+  DESCR_IMAGE_START,
+  DESCR_IMAGE_END
+};
+
+/* Array of pointers to target shared library descriptors.  */
+static void **libraries;
+
+/* Total number of target shared libraries.  */
+static int num_libraries;
+
 /* Array of descriptors of all available devices.  */
 static struct gomp_device_descr *devices;
 
@@ -107,6 +120,12 @@ splay_compare (splay_tree_key x, splay_tree_key y)
 
 #include "splay-tree.h"
 
+struct target_table_s
+{
+  void **entries;
+  int num_entries;
+};
+
 /* This structure describes accelerator device.
    It contains name of the corresponding libgomp plugin, function handlers for
    interaction with the device, ID-number of the device, and information about
@@ -117,15 +136,21 @@ struct gomp_device_descr
      TARGET construct.  */
   int id;
 
+  /* Set to true when device is initialized.  */
+  bool is_initialized;
+
   /* Plugin file handler.  */
   void *plugin_handle;
 
   /* Function handlers.  */
-  bool (*device_available_func) (void);
+  bool (*device_available_func) (int);
+  void (*device_init_func) (int);
+  struct target_table_s (*device_load_image_func) (void *, int);
   void *(*device_alloc_func) (size_t);
   void (*device_free_func) (void *);
   void *(*device_dev2host_func)(void *, const void *, size_t);
   void *(*device_host2dev_func)(void *, const void *, size_t);
+  void (*device_run_func) (void *, void *);
 
   /* Splay tree containing information about mapped memory regions.  */
   struct splay_tree_s dev_splay_tree;
@@ -471,6 +496,80 @@ gomp_update (struct gomp_device_descr *devicep, size_t mapnum,
   gomp_mutex_unlock (&devicep->dev_env_lock);
 }
 
+void
+GOMP_register_lib (const void *openmp_target)
+{
+  libraries = realloc (libraries, (num_libraries + 1) * sizeof (void *));
+
+  if (libraries == NULL)
+    return;
+
+  libraries[num_libraries] = (void *) openmp_target;
+
+  num_libraries++;
+}
+
+static void
+gomp_init_device (struct gomp_device_descr *devicep)
+{
+  /* Initialize the target device.  */
+  devicep->device_init_func (devicep->id);
+
+  /* Load shared libraries into target device and
+     perform host-target address mapping.  */
+  int i;
+  for (i = 0; i < num_libraries; i++)
+    {
+      /* Get the pointer to the target image from the library descriptor.  */
+      void **lib = libraries[i];
+
+      /* FIXME: Select the proper target image, if there are several.  */
+      void *target_image = lib[DESCR_IMAGE_START];
+      int target_img_size = lib[DESCR_IMAGE_END] - lib[DESCR_IMAGE_START];
+
+      /* Calculate the size of host address table.  */
+      void **host_table_start = lib[DESCR_TABLE_START];
+      void **host_table_end = lib[DESCR_TABLE_END];
+      int host_table_size = host_table_end - host_table_start;
+
+      /* Load library into target device and receive its address table.  */
+      struct target_table_s target_table
+	= devicep->device_load_image_func (target_image, target_img_size);
+
+      if (host_table_size != target_table.num_entries)
+	gomp_fatal ("Can't map target objects");
+
+      void **host_entry, **target_entry;
+      for (host_entry = host_table_start, target_entry = target_table.entries;
+	   host_entry < host_table_end; host_entry += 2, target_entry += 2)
+	{
+	  struct target_mem_desc *tgt = gomp_malloc (sizeof (*tgt));
+	  tgt->refcount = 1;
+	  tgt->array = gomp_malloc (sizeof (*tgt->array));
+	  tgt->tgt_start = (uintptr_t) *target_entry;
+	  tgt->tgt_end = tgt->tgt_start + *((uint64_t *) target_entry + 1);
+	  tgt->to_free = NULL;
+	  tgt->list_count = 0;
+	  tgt->device_descr = devicep;
+	  splay_tree_node node = tgt->array;
+	  splay_tree_key k = &node->key;
+	  k->host_start = (uintptr_t) *host_entry;
+	  k->host_end = k->host_start + *((uint64_t *) host_entry + 1);
+	  k->tgt_offset = 0;
+	  k->tgt = tgt;
+	  node->left = NULL;
+	  node->right = NULL;
+	  splay_tree_insert (&devicep->dev_splay_tree, node);
+	}
+
+      free (target_table.entries);
+    }
+
+  free (libraries);
+  num_libraries = 0;
+  devicep->is_initialized = true;
+}
+
 /* Called when encountering a target directive.  If DEVICE
    is -1, it means use device-var ICV.  If it is -2 (or any other value
    larger than last available hw device, use host fallback.
@@ -487,7 +586,8 @@ GOMP_target (int device, void (*fn) (void *), const void *openmp_target,
 	     unsigned char *kinds)
 {
   struct gomp_device_descr *devicep = resolve_device (device);
-  if (devicep == NULL)
+  if (openmp_target == NULL || devicep == NULL
+      || !devicep->device_available_func (devicep->id))
     {
       /* Host fallback.  */
       struct gomp_thread old_thr, *thr = gomp_thread ();
@@ -504,7 +604,18 @@ GOMP_target (int device, void (*fn) (void *), const void *openmp_target,
       return;
     }
 
-  struct target_mem_desc *tgt
+  if (!devicep->is_initialized)
+    gomp_init_device (devicep);
+
+  splay_tree_node node = gomp_malloc (sizeof (*node));
+  splay_tree_key k = &node->key;
+  k->host_start = (uintptr_t) fn;
+  k->host_end = k->host_start + 1;
+  splay_tree_key tgt_fn = splay_tree_lookup (&devicep->dev_splay_tree, k);
+  if (tgt_fn == NULL)
+    gomp_fatal ("Target function wasn't mapped");
+
+  struct target_mem_desc *tgt_vars
     = gomp_map_vars (devicep, mapnum, hostaddrs, sizes, kinds, true);
   struct gomp_thread old_thr, *thr = gomp_thread ();
   old_thr = *thr;
@@ -514,10 +625,11 @@ GOMP_target (int device, void (*fn) (void *), const void *openmp_target,
       thr->place = old_thr.place;
       thr->ts.place_partition_len = gomp_places_list_len;
     }
-  fn ((void *) tgt->tgt_start);
+  devicep->device_run_func ((void *) tgt_fn->tgt->tgt_start,
+			    (void *) tgt_vars->tgt_start);
   gomp_free_thread (thr);
   *thr = old_thr;
-  gomp_unmap_vars (tgt);
+  gomp_unmap_vars (tgt_vars);
 }
 
 void
@@ -525,7 +637,8 @@ GOMP_target_data (int device, const void *openmp_target, size_t mapnum,
 		  void **hostaddrs, size_t *sizes, unsigned char *kinds)
 {
   struct gomp_device_descr *devicep = resolve_device (device);
-  if (devicep == NULL)
+  if (openmp_target == NULL || devicep == NULL
+      || !devicep->device_available_func (devicep->id))
     {
       /* Host fallback.  */
       struct gomp_task_icv *icv = gomp_icv (false);
@@ -543,6 +656,9 @@ GOMP_target_data (int device, const void *openmp_target, size_t mapnum,
       return;
     }
 
+  if (!devicep->is_initialized)
+    gomp_init_device (devicep);
+
   struct target_mem_desc *tgt
     = gomp_map_vars (devicep, mapnum, hostaddrs, sizes, kinds, false);
   struct gomp_task_icv *icv = gomp_icv (true);
@@ -567,9 +683,13 @@ GOMP_target_update (int device, const void *openmp_target, size_t mapnum,
 		    void **hostaddrs, size_t *sizes, unsigned char *kinds)
 {
   struct gomp_device_descr *devicep = resolve_device (device);
-  if (devicep == NULL)
+  if (openmp_target == NULL || devicep == NULL
+      || !devicep->device_available_func (devicep->id))
     return;
 
+  if (!devicep->is_initialized)
+    gomp_init_device (devicep);
+
   gomp_update (devicep, mapnum, hostaddrs, sizes, kinds);
 }
 
@@ -637,10 +757,13 @@ gomp_load_plugin_for_device (struct gomp_device_descr *device,
     }									\
   while (0)
   DLSYM (device_available);
+  DLSYM (device_init);
+  DLSYM (device_load_image);
   DLSYM (device_alloc);
   DLSYM (device_free);
   DLSYM (device_dev2host);
   DLSYM (device_host2dev);
+  DLSYM (device_run);
 #undef DLSYM
 
  out:
@@ -700,6 +823,7 @@ gomp_find_available_plugins (void)
 
       devices[num_devices] = current_device;
       devices[num_devices].id = num_devices + 1;
+      devices[num_devices].is_initialized = false;
       devices[num_devices].dev_splay_tree.root = NULL;
       gomp_mutex_init (&devices[num_devices].dev_env_lock);
       num_devices++;
-- 
1.7.1

  -- Ilya


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]