From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 26106 invoked by alias); 28 Feb 2014 22:10:29 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Received: (qmail 23715 invoked by uid 89); 28 Feb 2014 22:06:51 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.4 required=5.0 tests=AWL,BAYES_00,FREEMAIL_FROM,RCVD_IN_DNSWL_LOW,SPF_PASS autolearn=ham version=3.3.2 X-HELO: mail-pb0-f52.google.com Received: from mail-pb0-f52.google.com (HELO mail-pb0-f52.google.com) (209.85.160.52) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-SHA encrypted) ESMTPS; Fri, 28 Feb 2014 22:06:49 +0000 Received: by mail-pb0-f52.google.com with SMTP id rr13so1322323pbb.11 for ; Fri, 28 Feb 2014 14:06:47 -0800 (PST) X-Received: by 10.66.158.132 with SMTP id wu4mr6202876pab.66.1393625207343; Fri, 28 Feb 2014 14:06:47 -0800 (PST) Received: from msticlxl57.ims.intel.com (fmdmzpr04-ext.fm.intel.com. [192.55.55.39]) by mx.google.com with ESMTPSA id os1sm22295235pac.20.2014.02.28.14.06.39 for (version=TLSv1 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Fri, 28 Feb 2014 14:06:46 -0800 (PST) Date: Fri, 28 Feb 2014 22:10:00 -0000 From: Ilya Verbin To: Bernd Schmidt Cc: Thomas Schwinge , "Michael V. Zolotukhin" , Jakub Jelinek , Richard Biener , Kirill Yukhin , Andrey Turetskiy , Ilya Tocar , gcc-patches , Nathan Sidwell Subject: Re: Fwd: [RFC][gomp4] Offloading patches (2/3): Add tables generation Message-ID: <20140228220624.GA18462@msticlxl57.ims.intel.com> References: <20131217113957.GA39975@msticlxl57.ims.intel.com> <52E7927B.8030509@codesourcery.com> <52E9137C.4020706@codesourcery.com> <530648F8.2010409@codesourcery.com> <5310B791.1000703@codesourcery.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <5310B791.1000703@codesourcery.com> User-Agent: Mutt/1.5.21 (2010-09-15) X-IsSubscribed: yes X-SW-Source: 2014-02/txt/msg01690.txt.bz2 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