This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: Fwd: [RFC][gomp4] Offloading patches (2/3): Add tables generation
- From: Ilya Verbin <iverbin at gmail dot com>
- To: Bernd Schmidt <bernds at codesourcery dot com>
- Cc: Thomas Schwinge <thomas at codesourcery dot com>, "Michael V. Zolotukhin" <michael dot v dot zolotukhin at gmail dot com>, Jakub Jelinek <jakub at redhat dot com>, Richard Biener <rguenther at suse dot de>, Kirill Yukhin <kirill dot yukhin at gmail dot com>, Andrey Turetskiy <andrey dot turetskiy at gmail dot com>, Ilya Tocar <tocarip dot intel at gmail dot com>, gcc-patches <gcc-patches at gcc dot gnu dot org>, Nathan Sidwell <nathan_sidwell at mentor dot com>
- Date: Sat, 1 Mar 2014 02:06:24 +0400
- Subject: Re: Fwd: [RFC][gomp4] Offloading patches (2/3): Add tables generation
- Authentication-results: sourceware.org; auth=none
- References: <20131217113957 dot GA39975 at msticlxl57 dot ims dot intel dot com> <52E7927B dot 8030509 at codesourcery dot com> <CADG=Z0GQ8ORLe1XRUU7VMYeLhwuWisMyCcGLQj-nY_bhkbD_1Q at mail dot gmail dot com> <CADG=Z0HRb1ojtTc4xEAG=hH_GcfAARDAmn70XGB5khF0mME4pQ at mail dot gmail dot com> <52E9137C dot 4020706 at codesourcery dot com> <CADG=Z0HkhefrBJ_tKyhEHv+p+AMTvpbxf=Md6JOCv6rAUu1u9g at mail dot gmail dot com> <CADG=Z0GW==Wax+3B5Z2JiieOWoz_gWpqtdhHA_L9-Nzb6u4bnA at mail dot gmail dot com> <530648F8 dot 2010409 at codesourcery dot com> <CADG=Z0HE6AudmZuQK2vWz+E4fh8PnqoJ-aq9GXjZXgn-ZRW0kw at mail dot gmail dot com> <5310B791 dot 1000703 at codesourcery dot com>
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