diff options
author | Ilya Verbin <ilya.verbin@intel.com> | 2015-04-06 12:40:28 +0000 |
---|---|---|
committer | Ilya Verbin <iverbin@gcc.gnu.org> | 2015-04-06 12:40:28 +0000 |
commit | a51df54e487cf1e03b6d01ffa2446a69e2b25c79 (patch) | |
tree | e7d774fabd484c0dd0c0c0e4c3452c47b0ee8b26 /liboffloadmic | |
parent | 71671f5d5259f40720b0636625b1edd11fb11f18 (diff) | |
download | gcc-a51df54e487cf1e03b6d01ffa2446a69e2b25c79.tar.gz |
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/ChangeLog | 14 | ||||
-rw-r--r-- | liboffloadmic/plugin/libgomp-plugin-intelmic.cpp | 203 |
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) { |