summaryrefslogtreecommitdiff
path: root/liboffloadmic
diff options
context:
space:
mode:
authorIlya Verbin <ilya.verbin@intel.com>2015-04-06 12:40:28 +0000
committerIlya Verbin <iverbin@gcc.gnu.org>2015-04-06 12:40:28 +0000
commita51df54e487cf1e03b6d01ffa2446a69e2b25c79 (patch)
treee7d774fabd484c0dd0c0c0e4c3452c47b0ee8b26 /liboffloadmic
parent71671f5d5259f40720b0636625b1edd11fb11f18 (diff)
libgomp: rework initialization of offloading
gcc/ * config/i386/intelmic-mkoffload.c (generate_host_descr_file): Call GOMP_offload_unregister from the destructor. libgomp/ * libgomp-plugin.h (struct mapping_table): Replace with addr_pair. * libgomp.h (struct gomp_memory_mapping): Remove. (struct target_mem_desc): Change type of mem_map from gomp_memory_mapping * to splay_tree_s *. (struct gomp_device_descr): Remove register_image_func, get_table_func. Add load_image_func, unload_image_func. Change type of mem_map from gomp_memory_mapping to splay_tree_s. Remove offload_regions_registered. (gomp_init_tables): Remove. (gomp_free_memmap): Change type of argument from gomp_memory_mapping * to splay_tree_s *. * libgomp.map (GOMP_4.0.1): Add GOMP_offload_unregister. * oacc-host.c (host_dispatch): Do not initialize register_image_func, get_table_func, mem_map.is_initialized, mem_map.splay_tree.root, offload_regions_registered. Initialize load_image_func, unload_image_func, mem_map.root. (goacc_host_init): Do not initialize host_dispatch.mem_map.lock. * oacc-init.c (lazy_open): Don't call gomp_init_tables. (acc_shutdown_1): Use dev's lock and splay_tree instead of mem_map's. * oacc-mem.c (lookup_host): Get gomp_device_descr *dev instead of gomp_memory_mapping *. Use dev's lock and splay_tree. (lookup_dev): Use dev's lock. (acc_deviceptr): Pass dev to lookup_host instead of mem_map. (acc_is_present): Likewise. (acc_map_data): Likewise. (acc_unmap_data): Likewise. Use dev's lock. (present_create_copy): Likewise. (delete_copyout): Pass dev to lookup_host instead of mem_map. (update_dev_host): Likewise. (gomp_acc_remove_pointer): Likewise. Use dev's lock. * oacc-parallel.c (GOACC_parallel): Use dev's lock and splay_tree. * plugin/plugin-host.c (GOMP_OFFLOAD_register_image): Remove. (GOMP_OFFLOAD_get_table): Remove (GOMP_OFFLOAD_load_image): New function. (GOMP_OFFLOAD_unload_image): New function. * target.c (register_lock): New mutex for offload image registration. (num_devices): Do not guard with PLUGIN_SUPPORT. (gomp_realloc_unlock): New static function. (gomp_map_vars_existing): Add device descriptor argument. Unlock mutex before gomp_fatal. (gomp_map_vars): Use dev's lock and splay_tree instead of mem_map's. Pass devicep to gomp_map_vars_existing. Unlock mutex before gomp_fatal. (gomp_copy_from_async): Use dev's lock and splay_tree instead of mem_map's. (gomp_unmap_vars): Likewise. (gomp_update): Remove gomp_memory_mapping argument. Use dev's lock and splay_tree instead of mm's. Unlock mutex before gomp_fatal. (gomp_offload_image_to_device): New static function. (GOMP_offload_register): Add mutex lock. Call gomp_offload_image_to_device for all initialized devices. Replace gomp_realloc with gomp_realloc_unlock. (GOMP_offload_unregister): New function. (gomp_init_tables): Replace with gomp_init_device. Replace a call to get_table_func from the plugin with calls to init_device_func and gomp_offload_image_to_device. (gomp_free_memmap): Change type of argument from gomp_memory_mapping * to splay_tree_s *. (GOMP_target): Do not call gomp_init_tables. Use dev's lock and splay_tree instead of mem_map's. Unlock mutex before gomp_fatal. (GOMP_target_data): Do not call gomp_init_tables. (GOMP_target_update): Likewise. Remove argument from gomp_update. (gomp_load_plugin_for_device): Replace register_image and get_table with load_image and unload_image in DLSYM (). (gomp_register_images_for_device): Remove function. (gomp_target_init): Do not initialize current_device.mem_map.*, current_device.offload_regions_registered. Remove call to gomp_register_images_for_device. Do not free offload_images and num_offload_images. liboffloadmic/ * plugin/libgomp-plugin-intelmic.cpp: Include map. (AddrVect, DevAddrVect, ImgDevAddrMap): New typedefs. (num_devices, num_images, address_table): New static vars. (num_libraries, lib_descrs): Remove static vars. (set_mic_lib_path): Rename to ... (init): ... this. Allocate address_table and get num_devices. (GOMP_OFFLOAD_get_num_devices): return num_devices. (load_lib_and_get_table): Remove static function. (offload_image): New static function. (GOMP_OFFLOAD_get_table): Remove function. (GOMP_OFFLOAD_load_image, GOMP_OFFLOAD_unload_image): New functions. From-SVN: r221878
Diffstat (limited to 'liboffloadmic')
-rw-r--r--liboffloadmic/ChangeLog14
-rw-r--r--liboffloadmic/plugin/libgomp-plugin-intelmic.cpp203
2 files changed, 113 insertions, 104 deletions
diff --git a/liboffloadmic/ChangeLog b/liboffloadmic/ChangeLog
index 074926e3595..c43e9fcda55 100644
--- a/liboffloadmic/ChangeLog
+++ b/liboffloadmic/ChangeLog
@@ -1,3 +1,17 @@
+2015-04-06 Ilya Verbin <ilya.verbin@intel.com>
+
+ * plugin/libgomp-plugin-intelmic.cpp: Include map.
+ (AddrVect, DevAddrVect, ImgDevAddrMap): New typedefs.
+ (num_devices, num_images, address_table): New static vars.
+ (num_libraries, lib_descrs): Remove static vars.
+ (set_mic_lib_path): Rename to ...
+ (init): ... this. Allocate address_table and get num_devices.
+ (GOMP_OFFLOAD_get_num_devices): return num_devices.
+ (load_lib_and_get_table): Remove static function.
+ (offload_image): New static function.
+ (GOMP_OFFLOAD_get_table): Remove function.
+ (GOMP_OFFLOAD_load_image, GOMP_OFFLOAD_unload_image): New functions.
+
2015-01-15 Thomas Schwinge <thomas@codesourcery.com>
* plugin/libgomp-plugin-intelmic.cpp (GOMP_OFFLOAD_get_name)
diff --git a/liboffloadmic/plugin/libgomp-plugin-intelmic.cpp b/liboffloadmic/plugin/libgomp-plugin-intelmic.cpp
index 3e7a95860b6..a2d61b15783 100644
--- a/liboffloadmic/plugin/libgomp-plugin-intelmic.cpp
+++ b/liboffloadmic/plugin/libgomp-plugin-intelmic.cpp
@@ -34,6 +34,7 @@
#include <string.h>
#include <utility>
#include <vector>
+#include <map>
#include "libgomp-plugin.h"
#include "compiler_if_host.h"
#include "main_target_image.h"
@@ -53,6 +54,29 @@ fprintf (stderr, "\n"); \
#endif
+/* Start/end addresses of functions and global variables on a device. */
+typedef std::vector<addr_pair> AddrVect;
+
+/* Addresses for one image and all devices. */
+typedef std::vector<AddrVect> DevAddrVect;
+
+/* Addresses for all images and all devices. */
+typedef std::map<void *, DevAddrVect> ImgDevAddrMap;
+
+
+/* Total number of available devices. */
+static int num_devices;
+
+/* Total number of shared libraries with offloading to Intel MIC. */
+static int num_images;
+
+/* Two dimensional array: one key is a pointer to image,
+ second key is number of device. Contains a vector of pointer pairs. */
+static ImgDevAddrMap *address_table;
+
+/* Thread-safe registration of the main image. */
+static pthread_once_t main_image_is_registered = PTHREAD_ONCE_INIT;
+
static VarDesc vd_host2tgt = {
{ 1, 1 }, /* dst, src */
{ 1, 0 }, /* in, out */
@@ -90,28 +114,17 @@ static VarDesc vd_tgt2host = {
};
-/* Total number of shared libraries with offloading to Intel MIC. */
-static int num_libraries;
-
-/* Pointers to the descriptors, containing pointers to host-side tables and to
- target images. */
-static std::vector< std::pair<void *, void *> > lib_descrs;
-
-/* Thread-safe registration of the main image. */
-static pthread_once_t main_image_is_registered = PTHREAD_ONCE_INIT;
-
-
/* Add path specified in LD_LIBRARY_PATH to MIC_LD_LIBRARY_PATH, which is
required by liboffloadmic. */
__attribute__((constructor))
static void
-set_mic_lib_path (void)
+init (void)
{
const char *ld_lib_path = getenv (LD_LIBRARY_PATH_ENV);
const char *mic_lib_path = getenv (MIC_LD_LIBRARY_PATH_ENV);
if (!ld_lib_path)
- return;
+ goto out;
if (!mic_lib_path)
setenv (MIC_LD_LIBRARY_PATH_ENV, ld_lib_path, 1);
@@ -133,6 +146,10 @@ set_mic_lib_path (void)
if (!use_alloca)
free (mic_lib_path_new);
}
+
+out:
+ address_table = new ImgDevAddrMap;
+ num_devices = _Offload_number_of_devices ();
}
extern "C" const char *
@@ -162,18 +179,8 @@ GOMP_OFFLOAD_get_type (void)
extern "C" int
GOMP_OFFLOAD_get_num_devices (void)
{
- int res = _Offload_number_of_devices ();
- TRACE ("(): return %d", res);
- return res;
-}
-
-/* This should be called from every shared library with offloading. */
-extern "C" void
-GOMP_OFFLOAD_register_image (void *host_table, void *target_image)
-{
- TRACE ("(host_table = %p, target_image = %p)", host_table, target_image);
- lib_descrs.push_back (std::make_pair (host_table, target_image));
- num_libraries++;
+ TRACE ("(): return %d", num_devices);
+ return num_devices;
}
static void
@@ -196,7 +203,8 @@ register_main_image ()
__offload_register_image (&main_target_image);
}
-/* Load offload_target_main on target. */
+/* liboffloadmic loads and runs offload_target_main on all available devices
+ during a first call to offload (). */
extern "C" void
GOMP_OFFLOAD_init_device (int device)
{
@@ -243,9 +251,11 @@ get_target_table (int device, int &num_funcs, int &num_vars, void **&table)
}
}
+/* Offload TARGET_IMAGE to all available devices and fill address_table with
+ corresponding target addresses. */
+
static void
-load_lib_and_get_table (int device, int lib_num, mapping_table *&table,
- int &table_size)
+offload_image (void *target_image)
{
struct TargetImage {
int64_t size;
@@ -254,19 +264,11 @@ load_lib_and_get_table (int device, int lib_num, mapping_table *&table,
char data[];
} __attribute__ ((packed));
- void ***host_table_descr = (void ***) lib_descrs[lib_num].first;
- void **host_func_start = host_table_descr[0];
- void **host_func_end = host_table_descr[1];
- void **host_var_start = host_table_descr[2];
- void **host_var_end = host_table_descr[3];
+ void *image_start = ((void **) target_image)[0];
+ void *image_end = ((void **) target_image)[1];
- void **target_image_descr = (void **) lib_descrs[lib_num].second;
- void *image_start = target_image_descr[0];
- void *image_end = target_image_descr[1];
-
- TRACE ("() host_table_descr { %p, %p, %p, %p }", host_func_start,
- host_func_end, host_var_start, host_var_end);
- TRACE ("() target_image_descr { %p, %p }", image_start, image_end);
+ TRACE ("(target_image = %p { %p, %p })",
+ target_image, image_start, image_end);
int64_t image_size = (uintptr_t) image_end - (uintptr_t) image_start;
TargetImage *image
@@ -279,94 +281,87 @@ load_lib_and_get_table (int device, int lib_num, mapping_table *&table,
}
image->size = image_size;
- sprintf (image->name, "lib%010d.so", lib_num);
+ sprintf (image->name, "lib%010d.so", num_images++);
memcpy (image->data, image_start, image->size);
TRACE ("() __offload_register_image %s { %p, %d }",
image->name, image_start, image->size);
__offload_register_image (image);
- int tgt_num_funcs = 0;
- int tgt_num_vars = 0;
- void **tgt_table = NULL;
- get_target_table (device, tgt_num_funcs, tgt_num_vars, tgt_table);
- free (image);
-
- /* The func table contains only addresses, the var table contains addresses
- and corresponding sizes. */
- int host_num_funcs = host_func_end - host_func_start;
- int host_num_vars = (host_var_end - host_var_start) / 2;
- TRACE ("() host_num_funcs = %d, tgt_num_funcs = %d",
- host_num_funcs, tgt_num_funcs);
- TRACE ("() host_num_vars = %d, tgt_num_vars = %d",
- host_num_vars, tgt_num_vars);
- if (host_num_funcs != tgt_num_funcs)
+ /* Receive tables for target_image from all devices. */
+ DevAddrVect dev_table;
+ for (int dev = 0; dev < num_devices; dev++)
{
- fprintf (stderr, "%s: Can't map target functions\n", __FILE__);
- exit (1);
- }
- if (host_num_vars != tgt_num_vars)
- {
- fprintf (stderr, "%s: Can't map target variables\n", __FILE__);
- exit (1);
- }
+ int num_funcs = 0;
+ int num_vars = 0;
+ void **table = NULL;
- table = (mapping_table *) realloc (table, (table_size + host_num_funcs
- + host_num_vars)
- * sizeof (mapping_table));
- if (table == NULL)
- {
- fprintf (stderr, "%s: Can't allocate memory\n", __FILE__);
- exit (1);
- }
+ get_target_table (dev, num_funcs, num_vars, table);
- for (int i = 0; i < host_num_funcs; i++)
- {
- mapping_table t;
- t.host_start = (uintptr_t) host_func_start[i];
- t.host_end = t.host_start + 1;
- t.tgt_start = (uintptr_t) tgt_table[i];
- t.tgt_end = t.tgt_start + 1;
-
- TRACE ("() lib %d, func %d:\t0x%llx -- 0x%llx",
- lib_num, i, t.host_start, t.tgt_start);
-
- table[table_size++] = t;
- }
+ AddrVect curr_dev_table;
- for (int i = 0; i < host_num_vars * 2; i += 2)
- {
- mapping_table t;
- t.host_start = (uintptr_t) host_var_start[i];
- t.host_end = t.host_start + (uintptr_t) host_var_start[i+1];
- t.tgt_start = (uintptr_t) tgt_table[tgt_num_funcs+i];
- t.tgt_end = t.tgt_start + (uintptr_t) tgt_table[tgt_num_funcs+i+1];
+ for (int i = 0; i < num_funcs; i++)
+ {
+ addr_pair tgt_addr;
+ tgt_addr.start = (uintptr_t) table[i];
+ tgt_addr.end = tgt_addr.start + 1;
+ TRACE ("() func %d:\t0x%llx..0x%llx", i,
+ tgt_addr.start, tgt_addr.end);
+ curr_dev_table.push_back (tgt_addr);
+ }
- TRACE ("() lib %d, var %d:\t0x%llx (%d) -- 0x%llx (%d)", lib_num, i/2,
- t.host_start, t.host_end - t.host_start,
- t.tgt_start, t.tgt_end - t.tgt_start);
+ for (int i = 0; i < num_vars; i++)
+ {
+ addr_pair tgt_addr;
+ tgt_addr.start = (uintptr_t) table[num_funcs+i*2];
+ tgt_addr.end = tgt_addr.start + (uintptr_t) table[num_funcs+i*2+1];
+ TRACE ("() var %d:\t0x%llx..0x%llx", i, tgt_addr.start, tgt_addr.end);
+ curr_dev_table.push_back (tgt_addr);
+ }
- table[table_size++] = t;
+ dev_table.push_back (curr_dev_table);
}
- delete [] tgt_table;
+ address_table->insert (std::make_pair (target_image, dev_table));
+
+ free (image);
}
extern "C" int
-GOMP_OFFLOAD_get_table (int device, void *result)
+GOMP_OFFLOAD_load_image (int device, void *target_image, addr_pair **result)
{
- TRACE ("(num_libraries = %d)", num_libraries);
+ TRACE ("(device = %d, target_image = %p)", device, target_image);
- mapping_table *table = NULL;
- int table_size = 0;
+ /* If target_image is already present in address_table, then there is no need
+ to offload it. */
+ if (address_table->count (target_image) == 0)
+ offload_image (target_image);
- for (int i = 0; i < num_libraries; i++)
- load_lib_and_get_table (device, i, table, table_size);
+ AddrVect *curr_dev_table = &(*address_table)[target_image][device];
+ int table_size = curr_dev_table->size ();
+ addr_pair *table = (addr_pair *) malloc (table_size * sizeof (addr_pair));
+ if (table == NULL)
+ {
+ fprintf (stderr, "%s: Can't allocate memory\n", __FILE__);
+ exit (1);
+ }
- *(void **) result = table;
+ std::copy (curr_dev_table->begin (), curr_dev_table->end (), table);
+ *result = table;
return table_size;
}
+extern "C" void
+GOMP_OFFLOAD_unload_image (int device, void *target_image)
+{
+ TRACE ("(device = %d, target_image = %p)", device, target_image);
+
+ /* TODO: Currently liboffloadmic doesn't support __offload_unregister_image
+ for libraries. */
+
+ address_table->erase (target_image);
+}
+
extern "C" void *
GOMP_OFFLOAD_alloc (int device, size_t size)
{