diff mbox

[gomp4] Generalize mapping functions for future OpenACC runtime library usage.

Message ID 52D990FD.3010502@codesourcery.com
State New
Headers show

Commit Message

James Norris Jan. 17, 2014, 8:22 p.m. UTC
Hi!

Here is a patch that changes the mapping functions to use functions defined
with the device descriptor. These changes generalize the mapping functions
so that they can be used by the soon to be added OpenACC Runtime functions.

These changes assume that the previous set of changes described in:
http://gcc.gnu.org/ml/gcc-patches/2013-12/msg00527.html, have been
applied.

Would appreciate a review of the changes.

Thanks!
Change mapping functionality to use handlers defined by device
    descriptor. These changes are required for the addition of the
    OpenACC Runtime Library.

    * ialias.h: New file
    * libgomp.h: Remove definitions and include file from where definitions
      now reside.
    * splay-tree.c: Add forward reference to splay_compare, replace call to
      abort with call to gomp_fatal, and fix comment formatting.
    * splay-tree.h: Remove inclusion of header file, add definition for
      splay_tree_key_s, remove splay_compare definition, and fix a typo.
    * target.c: Remove inclusion of unused header files, add inclusion of
      header file target.h, remove definition of structures: target_mem_desc
      and gomp_device_desc, and fix comment formatting.
      (gomp_map_vars, gomp_unmap_tgt, gomp_update): Replace calls with
      corresponding calls defined by device descriptor (gomp_device_descr).
      (gomp_find_available_plugins): Replace call to realloc with call to
      gomp_realloc and add assignments for new device descriptor operations.
    * target.h: Remove structure definiton splay_tree_key_s, add structure
      definition target_mem_desc and gomp_device_desc, add new function
      handlers to gomp_device_descr.
diff mbox

Patch

diff --git a/libgomp/ialias.h b/libgomp/ialias.h
new file mode 100644
index 0000000..167907b
--- /dev/null
+++ b/libgomp/ialias.h
@@ -0,0 +1,52 @@ 
+/* Copyright (C) 2013 Free Software Foundation, Inc.
+   Contributed by Jakub Jelinek <jakub@redhat.com>.
+
+   This file is part of the GNU OpenMP Library (libgomp).
+
+   Libgomp is free software; you can redistribute it and/or modify it
+   under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3, or (at your option)
+   any later version.
+
+   Libgomp is distributed in the hope that it will be useful, but WITHOUT ANY
+   WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+   FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+   more details.
+
+   Under Section 7 of GPL version 3, you are granted additional
+   permissions described in the GCC Runtime Library Exception, version
+   3.1, as published by the Free Software Foundation.
+
+   You should have received a copy of the GNU General Public License and
+   a copy of the GCC Runtime Library Exception along with this program;
+   see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+/* Defines shared between OpenACC and OpenMP  */
+
+#ifndef IALIAS_H
+#define IALIAS_H 1
+
+#ifdef HAVE_ATTRIBUTE_VISIBILITY
+# define attribute_hidden __attribute__ ((visibility ("hidden")))
+#else
+# define attribute_hidden
+#endif
+
+#ifdef HAVE_ATTRIBUTE_ALIAS
+# define ialias_ulp	ialias_str1(__USER_LABEL_PREFIX__)
+# define ialias_str1(x)	ialias_str2(x)
+# define ialias_str2(x)	#x
+# define ialias(fn) \
+  extern __typeof (fn) goacc_ialias_##fn \
+    __attribute__ ((alias (#fn))) attribute_hidden;
+# define ialias_redirect(fn) \
+  extern __typeof (fn) fn __asm__ (ialias_ulp "goacc_ialias_" #fn) attribute_hidden;
+# define ialias_call(fn) goacc_ialias_ ## fn
+#else
+# define ialias(fn)
+# define ialias_redirect(fn)
+# define ialias_call(fn) fn
+#endif
+
+#endif /* IALIAS_H */
diff --git a/libgomp/libgomp.h b/libgomp/libgomp.h
index bdc0486..933ed23 100644
--- a/libgomp/libgomp.h
+++ b/libgomp/libgomp.h
@@ -675,26 +675,6 @@  extern int gomp_test_nest_lock_25 (omp_nest_lock_25_t *) __GOMP_NOTHROW;
 # define gomp_test_nest_lock_30 omp_test_nest_lock
 #endif
 
-#ifdef HAVE_ATTRIBUTE_VISIBILITY
-# define attribute_hidden __attribute__ ((visibility ("hidden")))
-#else
-# define attribute_hidden
-#endif
-
-#ifdef HAVE_ATTRIBUTE_ALIAS
-# define ialias_ulp	ialias_str1(__USER_LABEL_PREFIX__)
-# define ialias_str1(x)	ialias_str2(x)
-# define ialias_str2(x)	#x
-# define ialias(fn) \
-  extern __typeof (fn) gomp_ialias_##fn \
-    __attribute__ ((alias (#fn))) attribute_hidden;
-# define ialias_redirect(fn) \
-  extern __typeof (fn) fn __asm__ (ialias_ulp "gomp_ialias_" #fn) attribute_hidden;
-# define ialias_call(fn) gomp_ialias_ ## fn
-#else
-# define ialias(fn)
-# define ialias_redirect(fn)
-# define ialias_call(fn) fn
-#endif
+#include "ialias.h"
 
 #endif /* LIBGOMP_H */
diff --git a/libgomp/splay-tree.c b/libgomp/splay-tree.c
index fc929f9..fe5596d 100644
--- a/libgomp/splay-tree.c
+++ b/libgomp/splay-tree.c
@@ -43,11 +43,12 @@  typedef struct splay_tree_key_s *splay_tree_key;
    The major feature of splay trees is that all basic tree operations
    are amortized O(log n) time for a tree with n nodes.  */
 
-/* Forward declaration for a node in the tree.  */
 typedef struct splay_tree_node_s *splay_tree_node;
 typedef struct splay_tree_s *splay_tree;
 typedef struct splay_tree_key_s *splay_tree_key;
 
+extern int splay_compare (splay_tree_key, splay_tree_key);
+
 #include "libgomp.h"
 #include "splay-tree.h"
 
@@ -155,7 +156,7 @@  splay_tree_insert (splay_tree sp, splay_tree_node node)
     comparison = splay_compare (&sp->root->key, &node->key);
 
   if (sp->root && comparison == 0)
-    abort ();
+    gomp_fatal ("Duplicate node");
   else
     {
       /* Insert it at the root.  */
diff --git a/libgomp/splay-tree.h b/libgomp/splay-tree.h
index 3a5d23e..db36419 100644
--- a/libgomp/splay-tree.h
+++ b/libgomp/splay-tree.h
@@ -43,10 +43,23 @@  typedef struct splay_tree_key_s *splay_tree_key;
    The major feature of splay trees is that all basic tree operations
    are amortized O(log n) time for a tree with n nodes.  */
 
-#include "target.h"
-
 #ifndef _SPLAY_TREE_H
-#define _SPLAY_TREE_H
+#define _SPLAY_TREE_H 1
+
+struct splay_tree_key_s {
+  /* Address of the host object.  */
+  uintptr_t host_start;
+  /* Address immediately after the host object.  */
+  uintptr_t host_end;
+  /* Descriptor of the target memory.  */
+  struct target_mem_desc *tgt;
+  /* Offset from tgt->tgt_start to the start of the target object.  */
+  uintptr_t tgt_offset;
+  /* Reference count.  */
+  uintptr_t refcount;
+  /* True if data should be copied from device to host at the end.  */
+  bool copy_from;
+};
 
 /* The nodes in the splay tree.  */
 struct splay_tree_node_s {
@@ -64,6 +77,5 @@  struct splay_tree_s {
 attribute_hidden splay_tree_key splay_tree_lookup (splay_tree, splay_tree_key);
 attribute_hidden void splay_tree_insert (splay_tree, splay_tree_node);
 attribute_hidden void splay_tree_remove (splay_tree, splay_tree_key);
-attribute_hidden int splay_compare (splay_tree_key, splay_tree_key);
 
 #endif /* _SPLAY_TREE_H */
diff --git a/libgomp/target.c b/libgomp/target.c
index 14ec3d0..37929b8 100644
--- a/libgomp/target.c
+++ b/libgomp/target.c
@@ -26,9 +26,6 @@ 
    creation and termination.  */
 
 #include "libgomp.h"
-#include <limits.h>
-#include <stdbool.h>
-#include <stdlib.h>
 #include <string.h>
 
 #ifdef PLUGIN_SUPPORT
@@ -40,41 +37,16 @@  static void gomp_target_init (void);
 
 static pthread_once_t gomp_is_initialized = PTHREAD_ONCE_INIT;
 
-/* Forward declaration for a node in the tree.  */
 typedef struct splay_tree_node_s *splay_tree_node;
 typedef struct splay_tree_s *splay_tree;
 typedef struct splay_tree_key_s *splay_tree_key;
 
-struct target_mem_desc {
-  /* Reference count.  */
-  uintptr_t refcount;
-  /* All the splay nodes allocated together.  */
-  splay_tree_node array;
-  /* Start of the target region.  */
-  uintptr_t tgt_start;
-  /* End of the targer region.  */
-  uintptr_t tgt_end;
-  /* Handle to free.  */
-  void *to_free;
-  /* Previous target_mem_desc.  */
-  struct target_mem_desc *prev;
-  /* Number of items in following list.  */
-  size_t list_count;
-
-  /* Corresponding target device descriptor.  */
-  struct gomp_device_descr *device_descr;
-
-  /* List of splay keys to remove (or decrease refcount)
-     at the end of region.  */
-  splay_tree_key list[];
-};
-
-#include "target.h"
+#include "splay-tree.h"
 
-/* Array of descriptors of all available devices.  */
+/* Array of descriptors of all available devices. */
 static struct gomp_device_descr *devices;
 
-/* Total number of available devices.  */
+/* Total number of available devices. */
 static int num_devices;
 
 /* The comparison function.  */
@@ -92,30 +64,7 @@  splay_compare (splay_tree_key x, splay_tree_key y)
   return 0;
 }
 
-#include "splay-tree.h"
-
-/* 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
-   mapped memory.  */
-struct gomp_device_descr
-{
-  /* This is the ID number of device.  It could be specified in DEVICE-clause of
-     TARGET construct.  */
-  int id;
-
-  /* Plugin file handler.  */
-  void *plugin_handle;
-
-  /* Function handlers.  */
-  bool (*device_available_func) (void);
-
-  /* Splay tree containing information about mapped memory regions.  */
-  struct splay_tree_s dev_splay_tree;
-
-  /* Mutex for operating with the splay tree and other shared structures.  */
-  gomp_mutex_t dev_env_lock;
-};
+#include "target.h"
 
 attribute_hidden int
 gomp_get_num_devices (void)
@@ -223,7 +172,7 @@  gomp_map_vars (struct gomp_device_descr *devicep, size_t mapnum,
       /* FIXME: This would be accelerator memory allocation, not
 	 host, and should allocate tgt_align aligned tgt_size block
 	 of memory.  */
-      tgt->to_free = gomp_malloc (tgt_size + tgt_align - 1);
+      tgt->to_free = devicep->device_alloc_func (tgt_size + tgt_align - 1);
       tgt->tgt_start = (uintptr_t) tgt->to_free;
       tgt->tgt_start = (tgt->tgt_start + tgt_align - 1) & ~(tgt_align - 1);
       tgt->tgt_end = tgt->tgt_start + tgt_size;
@@ -288,7 +237,8 @@  gomp_map_vars (struct gomp_device_descr *devicep, size_t mapnum,
 		       memory.  Perhaps add some smarts, like if copying
 		       several adjacent fields from host to target, use some
 		       host buffer to avoid sending each var individually.  */
-		    memcpy ((void *) (tgt->tgt_start + k->tgt_offset),
+		    devicep->device_host2dev_func(
+			    (void *) (tgt->tgt_start + k->tgt_offset),
 			    (void *) k->host_start,
 			    k->host_end - k->host_start);
 		    break;
@@ -325,7 +275,8 @@  gomp_map_vars (struct gomp_device_descr *devicep, size_t mapnum,
 		       to initialize the pointer with.  */
 		    cur_node.tgt_offset -= sizes[i];
 		    /* FIXME: host to device copy, see above FIXME comment.  */
-		    memcpy ((void *) (tgt->tgt_start + k->tgt_offset),
+		    devicep->device_host2dev_func (
+			    (void *) (tgt->tgt_start + k->tgt_offset),
 			    (void *) &cur_node.tgt_offset,
 			    sizeof (void *));
 		    break;
@@ -341,7 +292,8 @@  gomp_map_vars (struct gomp_device_descr *devicep, size_t mapnum,
 	  cur_node.tgt_offset = tgt->list[i]->tgt->tgt_start
 				+ tgt->list[i]->tgt_offset;
 	  /* FIXME: host to device copy, see above FIXME comment.  */
-	  memcpy ((void *) (tgt->tgt_start + i * sizeof (void *)),
+	  devicep->device_host2dev_func (
+		  (void *) (tgt->tgt_start + i * sizeof (void *)),
 		  (void *) &cur_node.tgt_offset,
 		  sizeof (void *));
 	}
@@ -357,7 +309,7 @@  gomp_unmap_tgt (struct target_mem_desc *tgt)
   /* FIXME: Deallocate on target the tgt->tgt_start .. tgt->tgt_end
      region.  */
   if (tgt->tgt_end)
-    free (tgt->to_free);
+    tgt->device_descr->device_free_func(tgt->to_free);
 
   free (tgt->array);
   free (tgt);
@@ -384,7 +336,7 @@  gomp_unmap_vars (struct target_mem_desc *tgt)
 	splay_tree_key k = tgt->list[i];
 	if (k->copy_from)
 	  /* FIXME: device to host copy.  */
-	  memcpy ((void *) k->host_start,
+	  devicep->device_dev2host_func ((void *) k->host_start,
 		  (void *) (k->tgt->tgt_start + k->tgt_offset),
 		  k->host_end - k->host_start);
 	splay_tree_remove (&devicep->dev_splay_tree, k);
@@ -434,13 +386,14 @@  gomp_update (struct gomp_device_descr *devicep, size_t mapnum,
 			  (void *) n->host_end);
 	    if ((kinds[i] & 7) == 1)
 	      /* FIXME: host to device copy.  */
-	      memcpy ((void *) (n->tgt->tgt_start + n->tgt_offset
+	      devicep->device_host2dev_func (
+		      (void *) (n->tgt->tgt_start + n->tgt_offset
 				+ cur_node.host_start - n->host_start),
 		      (void *) cur_node.host_start,
 		      cur_node.host_end - cur_node.host_start);
 	    else if ((kinds[i] & 7) == 2)
 	      /* FIXME: device to host copy.  */
-	      memcpy ((void *) cur_node.host_start,
+	      devicep->device_dev2host_func ((void *) cur_node.host_start,
 		      (void *) (n->tgt->tgt_start + n->tgt_offset
 				+ cur_node.host_start - n->host_start),
 		      cur_node.host_end - cur_node.host_start);
@@ -656,7 +609,7 @@  gomp_find_available_plugins (void)
       strcat (plugin_name, ent->d_name);
       if (!gomp_load_plugin_for_device (&current_device, plugin_name))
 	continue;
-      devices = realloc (devices, (num_devices + 1)
+      devices = gomp_realloc (devices, (num_devices + 1)
 				  * sizeof (struct gomp_device_descr));
       if (devices == NULL)
 	{
@@ -687,6 +640,10 @@  gomp_find_available_plugins (void)
 	}
       devices[0].plugin_handle = NULL;
       devices[0].device_available_func = NULL;
+      devices[0].device_alloc_func = malloc;
+      devices[0].device_free_func = free;
+      devices[0].device_dev2host_func = memcpy;
+      devices[0].device_host2dev_func = memcpy;
       devices[0].dev_splay_tree.root = NULL;
       gomp_mutex_init (&devices[0].dev_env_lock);
     }
diff --git a/libgomp/target.h b/libgomp/target.h
index cac951f..1fa7ec5 100644
--- a/libgomp/target.h
+++ b/libgomp/target.h
@@ -26,21 +26,57 @@ 
    creation and termination.  */
 
 #ifndef _TARGET_H
-#define _TARGET_H
-
-struct splay_tree_key_s {
-  /* Address of the host object.  */
-  uintptr_t host_start;
-  /* Address immediately after the host object.  */
-  uintptr_t host_end;
-  /* Descriptor of the target memory.  */
-  struct target_mem_desc *tgt;
-  /* Offset from tgt->tgt_start to the start of the target object.  */
-  uintptr_t tgt_offset;
+#define _TARGET_H 1
+
+struct target_mem_desc {
   /* Reference count.  */
   uintptr_t refcount;
-  /* True if data should be copied from device to host at the end.  */
-  bool copy_from;
+  /* All the splay nodes allocated together.  */
+  splay_tree_node array;
+  /* Start of the target region.  */
+  uintptr_t tgt_start;
+  /* End of the targer region.  */
+  uintptr_t tgt_end;
+  /* Handle to free.  */
+  void *to_free;
+  /* Previous target_mem_desc.  */
+  struct target_mem_desc *prev;
+  /* Number of items in following list.  */
+  size_t list_count;
+
+  /* Corresponding target device descriptor.  */
+  struct gomp_device_descr *device_descr;
+
+  /* List of splay keys to remove (or decrease refcount)
+     at the end of region.  */
+  splay_tree_key list[];
+};
+
+/* 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
+   mapped memory.  */
+struct gomp_device_descr
+{
+  /* This is the ID number of device.  It could be specified in DEVICE-clause of
+     TARGET construct.  */
+  int id;
+
+  /* Plugin file handler.  */
+  void *plugin_handle;
+
+  /* Function handlers.  */
+  bool (*device_available_func) (void);
+  void *(*device_alloc_func) (size_t s);
+  void (*device_free_func) (void *);
+  void *(*device_dev2host_func)(void *, const void *, size_t);
+  void *(*device_host2dev_func)(void *, const void *, size_t);
+
+  /* Splay tree containing information about mapped memory regions.  */
+  struct splay_tree_s dev_splay_tree;
+
+  /* Mutex for operating with the splay tree and other shared structures.  */
+  gomp_mutex_t dev_env_lock;
 };
 
 #endif /* _TARGET_H */