aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoriverbin <iverbin@138bc75d-0d04-0410-961f-82ee72b054a4>2015-12-14 16:46:54 +0000
committeriverbin <iverbin@138bc75d-0d04-0410-961f-82ee72b054a4>2015-12-14 16:46:54 +0000
commitf87b2900a166626a523c77dbb6456ca9b8f71d24 (patch)
tree942a44d60d4c5cc795b051eb83959cabdbc8fe20
parent89b07b7d2e00f7024e9b0ea17d60c62a17f7abf5 (diff)
libgomp/
* libgomp.h (gomp_device_state): New enum. (struct gomp_device_descr): Replace is_initialized with state. (gomp_fini_device): Remove declaration. * oacc-host.c (host_dispatch): Use state instead of is_initialized. * oacc-init.c (acc_init_1): Use state instead of is_initialized. (acc_shutdown_1): Likewise. Inline gomp_fini_device. (acc_set_device_type): Use state instead of is_initialized. (acc_set_device_num): Likewise. * target.c (resolve_device): Use state instead of is_initialized. Do not initialize finalized device. (gomp_map_vars): Do nothing if device is finalized. (gomp_unmap_vars): Likewise. (gomp_update): Likewise. (GOMP_offload_register_ver): Use state instead of is_initialized. (GOMP_offload_unregister_ver): Likewise. (gomp_init_device): Likewise. (gomp_unload_device): Likewise. (gomp_fini_device): Remove. (gomp_get_target_fn_addr): Do nothing if device is finalized. (GOMP_target): Go to host fallback if device is finalized. (GOMP_target_ext): Likewise. (gomp_exit_data): Do nothing if device is finalized. (gomp_target_task_fn): Go to host fallback if device is finalized. (gomp_target_fini): New static function. (gomp_target_init): Use state instead of is_initialized. Call gomp_target_fini at exit. liboffloadmic/ * plugin/libgomp-plugin-intelmic.cpp (unregister_main_image): Remove. (register_main_image): Do not call unregister_main_image at exit. (GOMP_OFFLOAD_fini_device): Allow for OpenMP. Unregister main image. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@231623 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--libgomp/ChangeLog29
-rw-r--r--libgomp/libgomp.h15
-rw-r--r--libgomp/oacc-host.c2
-rw-r--r--libgomp/oacc-init.c11
-rw-r--r--libgomp/target.c101
-rw-r--r--liboffloadmic/ChangeLog6
-rw-r--r--liboffloadmic/plugin/libgomp-plugin-intelmic.cpp17
7 files changed, 132 insertions, 49 deletions
diff --git a/libgomp/ChangeLog b/libgomp/ChangeLog
index 1b12354a075..87459270a5e 100644
--- a/libgomp/ChangeLog
+++ b/libgomp/ChangeLog
@@ -1,3 +1,32 @@
+2015-12-14 Ilya Verbin <ilya.verbin@intel.com>
+
+ * libgomp.h (gomp_device_state): New enum.
+ (struct gomp_device_descr): Replace is_initialized with state.
+ (gomp_fini_device): Remove declaration.
+ * oacc-host.c (host_dispatch): Use state instead of is_initialized.
+ * oacc-init.c (acc_init_1): Use state instead of is_initialized.
+ (acc_shutdown_1): Likewise. Inline gomp_fini_device.
+ (acc_set_device_type): Use state instead of is_initialized.
+ (acc_set_device_num): Likewise.
+ * target.c (resolve_device): Use state instead of is_initialized.
+ Do not initialize finalized device.
+ (gomp_map_vars): Do nothing if device is finalized.
+ (gomp_unmap_vars): Likewise.
+ (gomp_update): Likewise.
+ (GOMP_offload_register_ver): Use state instead of is_initialized.
+ (GOMP_offload_unregister_ver): Likewise.
+ (gomp_init_device): Likewise.
+ (gomp_unload_device): Likewise.
+ (gomp_fini_device): Remove.
+ (gomp_get_target_fn_addr): Do nothing if device is finalized.
+ (GOMP_target): Go to host fallback if device is finalized.
+ (GOMP_target_ext): Likewise.
+ (gomp_exit_data): Do nothing if device is finalized.
+ (gomp_target_task_fn): Go to host fallback if device is finalized.
+ (gomp_target_fini): New static function.
+ (gomp_target_init): Use state instead of is_initialized.
+ Call gomp_target_fini at exit.
+
2015-12-09 Tom de Vries <tom@codesourcery.com>
PR tree-optimization/68716
diff --git a/libgomp/libgomp.h b/libgomp/libgomp.h
index c467f97788b..9d9949ff16a 100644
--- a/libgomp/libgomp.h
+++ b/libgomp/libgomp.h
@@ -888,6 +888,14 @@ typedef struct acc_dispatch_t
} cuda;
} acc_dispatch_t;
+/* Various state of the accelerator device. */
+enum gomp_device_state
+{
+ GOMP_DEVICE_UNINITIALIZED,
+ GOMP_DEVICE_INITIALIZED,
+ GOMP_DEVICE_FINALIZED
+};
+
/* 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
@@ -933,8 +941,10 @@ struct gomp_device_descr
/* Mutex for the mutable data. */
gomp_mutex_t lock;
- /* Set to true when device is initialized. */
- bool is_initialized;
+ /* Current state of the device. OpenACC allows to move from INITIALIZED state
+ back to UNINITIALIZED state. OpenMP allows only to move from INITIALIZED
+ to FINALIZED state (at program shutdown). */
+ enum gomp_device_state state;
/* OpenACC-specific data and functions. */
/* This is mutable because of its mutable data_environ and target_data
@@ -962,7 +972,6 @@ extern void gomp_copy_from_async (struct target_mem_desc *);
extern void gomp_unmap_vars (struct target_mem_desc *, bool);
extern void gomp_init_device (struct gomp_device_descr *);
extern void gomp_free_memmap (struct splay_tree_s *);
-extern void gomp_fini_device (struct gomp_device_descr *);
extern void gomp_unload_device (struct gomp_device_descr *);
/* work.c */
diff --git a/libgomp/oacc-host.c b/libgomp/oacc-host.c
index 98748041bfc..d289b38941d 100644
--- a/libgomp/oacc-host.c
+++ b/libgomp/oacc-host.c
@@ -222,7 +222,7 @@ static struct gomp_device_descr host_dispatch =
.mem_map = { NULL },
/* .lock initilized in goacc_host_init. */
- .is_initialized = false,
+ .state = GOMP_DEVICE_UNINITIALIZED,
.openacc = {
.data_environ = NULL,
diff --git a/libgomp/oacc-init.c b/libgomp/oacc-init.c
index 9a9a0b0333f..c4f7b6742fd 100644
--- a/libgomp/oacc-init.c
+++ b/libgomp/oacc-init.c
@@ -225,7 +225,7 @@ acc_init_1 (acc_device_t d)
acc_dev = &base_dev[goacc_device_num];
gomp_mutex_lock (&acc_dev->lock);
- if (acc_dev->is_initialized)
+ if (acc_dev->state == GOMP_DEVICE_INITIALIZED)
{
gomp_mutex_unlock (&acc_dev->lock);
gomp_fatal ("device already active");
@@ -306,10 +306,11 @@ acc_shutdown_1 (acc_device_t d)
{
struct gomp_device_descr *acc_dev = &base_dev[i];
gomp_mutex_lock (&acc_dev->lock);
- if (acc_dev->is_initialized)
+ if (acc_dev->state == GOMP_DEVICE_INITIALIZED)
{
devices_active = true;
- gomp_fini_device (acc_dev);
+ acc_dev->fini_device_func (acc_dev->target_id);
+ acc_dev->state = GOMP_DEVICE_UNINITIALIZED;
}
gomp_mutex_unlock (&acc_dev->lock);
}
@@ -506,7 +507,7 @@ acc_set_device_type (acc_device_t d)
acc_dev = &base_dev[goacc_device_num];
gomp_mutex_lock (&acc_dev->lock);
- if (!acc_dev->is_initialized)
+ if (acc_dev->state == GOMP_DEVICE_UNINITIALIZED)
gomp_init_device (acc_dev);
gomp_mutex_unlock (&acc_dev->lock);
@@ -608,7 +609,7 @@ acc_set_device_num (int ord, acc_device_t d)
acc_dev = &base_dev[ord];
gomp_mutex_lock (&acc_dev->lock);
- if (!acc_dev->is_initialized)
+ if (acc_dev->state == GOMP_DEVICE_UNINITIALIZED)
gomp_init_device (acc_dev);
gomp_mutex_unlock (&acc_dev->lock);
diff --git a/libgomp/target.c b/libgomp/target.c
index cf9d0e64c7c..932b1761f4e 100644
--- a/libgomp/target.c
+++ b/libgomp/target.c
@@ -118,8 +118,13 @@ resolve_device (int device_id)
return NULL;
gomp_mutex_lock (&devices[device_id].lock);
- if (!devices[device_id].is_initialized)
+ if (devices[device_id].state == GOMP_DEVICE_UNINITIALIZED)
gomp_init_device (&devices[device_id]);
+ else if (devices[device_id].state == GOMP_DEVICE_FINALIZED)
+ {
+ gomp_mutex_unlock (&devices[device_id].lock);
+ return NULL;
+ }
gomp_mutex_unlock (&devices[device_id].lock);
return &devices[device_id];
@@ -356,6 +361,12 @@ gomp_map_vars (struct gomp_device_descr *devicep, size_t mapnum,
}
gomp_mutex_lock (&devicep->lock);
+ if (devicep->state == GOMP_DEVICE_FINALIZED)
+ {
+ gomp_mutex_unlock (&devicep->lock);
+ free (tgt);
+ return NULL;
+ }
for (i = 0; i < mapnum; i++)
{
@@ -834,6 +845,13 @@ gomp_unmap_vars (struct target_mem_desc *tgt, bool do_copyfrom)
}
gomp_mutex_lock (&devicep->lock);
+ if (devicep->state == GOMP_DEVICE_FINALIZED)
+ {
+ gomp_mutex_unlock (&devicep->lock);
+ free (tgt->array);
+ free (tgt);
+ return;
+ }
size_t i;
for (i = 0; i < tgt->list_count; i++)
@@ -896,6 +914,12 @@ gomp_update (struct gomp_device_descr *devicep, size_t mapnum, void **hostaddrs,
return;
gomp_mutex_lock (&devicep->lock);
+ if (devicep->state == GOMP_DEVICE_FINALIZED)
+ {
+ gomp_mutex_unlock (&devicep->lock);
+ return;
+ }
+
for (i = 0; i < mapnum; i++)
if (sizes[i])
{
@@ -1106,7 +1130,8 @@ GOMP_offload_register_ver (unsigned version, const void *host_table,
{
struct gomp_device_descr *devicep = &devices[i];
gomp_mutex_lock (&devicep->lock);
- if (devicep->type == target_type && devicep->is_initialized)
+ if (devicep->type == target_type
+ && devicep->state == GOMP_DEVICE_INITIALIZED)
gomp_load_image_to_device (devicep, version,
host_table, target_data, true);
gomp_mutex_unlock (&devicep->lock);
@@ -1150,7 +1175,8 @@ GOMP_offload_unregister_ver (unsigned version, const void *host_table,
{
struct gomp_device_descr *devicep = &devices[i];
gomp_mutex_lock (&devicep->lock);
- if (devicep->type == target_type && devicep->is_initialized)
+ if (devicep->type == target_type
+ && devicep->state == GOMP_DEVICE_INITIALIZED)
gomp_unload_image_from_device (devicep, version,
host_table, target_data);
gomp_mutex_unlock (&devicep->lock);
@@ -1193,13 +1219,13 @@ gomp_init_device (struct gomp_device_descr *devicep)
false);
}
- devicep->is_initialized = true;
+ devicep->state = GOMP_DEVICE_INITIALIZED;
}
attribute_hidden void
gomp_unload_device (struct gomp_device_descr *devicep)
{
- if (devicep->is_initialized)
+ if (devicep->state == GOMP_DEVICE_INITIALIZED)
{
unsigned i;
@@ -1231,18 +1257,6 @@ gomp_free_memmap (struct splay_tree_s *mem_map)
}
}
-/* This function de-initializes the target device, specified by DEVICEP.
- DEVICEP must be locked on entry, and remains locked on return. */
-
-attribute_hidden void
-gomp_fini_device (struct gomp_device_descr *devicep)
-{
- if (devicep->is_initialized)
- devicep->fini_device_func (devicep->target_id);
-
- devicep->is_initialized = false;
-}
-
/* Host fallback for GOMP_target{,_ext} routines. */
static void
@@ -1310,6 +1324,12 @@ gomp_get_target_fn_addr (struct gomp_device_descr *devicep,
else
{
gomp_mutex_lock (&devicep->lock);
+ if (devicep->state == GOMP_DEVICE_FINALIZED)
+ {
+ gomp_mutex_unlock (&devicep->lock);
+ return NULL;
+ }
+
struct splay_tree_key_s k;
k.host_start = (uintptr_t) host_fn;
k.host_end = k.host_start + 1;
@@ -1339,12 +1359,12 @@ GOMP_target (int device, void (*fn) (void *), const void *unused,
{
struct gomp_device_descr *devicep = resolve_device (device);
+ void *fn_addr;
if (devicep == NULL
- || !(devicep->capabilities & GOMP_OFFLOAD_CAP_OPENMP_400))
+ || !(devicep->capabilities & GOMP_OFFLOAD_CAP_OPENMP_400)
+ || !(fn_addr = gomp_get_target_fn_addr (devicep, fn)))
return gomp_target_fallback (fn, hostaddrs);
- void *fn_addr = gomp_get_target_fn_addr (devicep, fn);
-
struct target_mem_desc *tgt_vars
= gomp_map_vars (devicep, mapnum, hostaddrs, NULL, sizes, kinds, false,
GOMP_MAP_VARS_TARGET);
@@ -1430,15 +1450,15 @@ GOMP_target_ext (int device, void (*fn) (void *), size_t mapnum,
gomp_task_maybe_wait_for_dependencies (depend);
}
+ void *fn_addr;
if (devicep == NULL
- || !(devicep->capabilities & GOMP_OFFLOAD_CAP_OPENMP_400))
+ || !(devicep->capabilities & GOMP_OFFLOAD_CAP_OPENMP_400)
+ || !(fn_addr = gomp_get_target_fn_addr (devicep, fn)))
{
gomp_target_fallback_firstprivate (fn, mapnum, hostaddrs, sizes, kinds);
return;
}
- void *fn_addr = gomp_get_target_fn_addr (devicep, fn);
-
struct target_mem_desc *tgt_vars
= gomp_map_vars (devicep, mapnum, hostaddrs, NULL, sizes, kinds, true,
GOMP_MAP_VARS_TARGET);
@@ -1593,6 +1613,12 @@ gomp_exit_data (struct gomp_device_descr *devicep, size_t mapnum,
const int typemask = 0xff;
size_t i;
gomp_mutex_lock (&devicep->lock);
+ if (devicep->state == GOMP_DEVICE_FINALIZED)
+ {
+ gomp_mutex_unlock (&devicep->lock);
+ return;
+ }
+
for (i = 0; i < mapnum; i++)
{
struct splay_tree_key_s cur_node;
@@ -1729,8 +1755,10 @@ gomp_target_task_fn (void *data)
if (ttask->fn != NULL)
{
+ void *fn_addr;
if (devicep == NULL
- || !(devicep->capabilities & GOMP_OFFLOAD_CAP_OPENMP_400))
+ || !(devicep->capabilities & GOMP_OFFLOAD_CAP_OPENMP_400)
+ || !(fn_addr = gomp_get_target_fn_addr (devicep, ttask->fn)))
{
ttask->state = GOMP_TARGET_TASK_FALLBACK;
gomp_target_fallback_firstprivate (ttask->fn, ttask->mapnum,
@@ -1745,7 +1773,6 @@ gomp_target_task_fn (void *data)
return false;
}
- void *fn_addr = gomp_get_target_fn_addr (devicep, ttask->fn);
ttask->tgt
= gomp_map_vars (devicep, ttask->mapnum, ttask->hostaddrs, NULL,
ttask->sizes, ttask->kinds, true,
@@ -2282,6 +2309,25 @@ gomp_load_plugin_for_device (struct gomp_device_descr *device,
return 0;
}
+/* This function finalizes all initialized devices. */
+
+static void
+gomp_target_fini (void)
+{
+ int i;
+ for (i = 0; i < num_devices; i++)
+ {
+ struct gomp_device_descr *devicep = &devices[i];
+ gomp_mutex_lock (&devicep->lock);
+ if (devicep->state == GOMP_DEVICE_INITIALIZED)
+ {
+ devicep->fini_device_func (devicep->target_id);
+ devicep->state = GOMP_DEVICE_FINALIZED;
+ }
+ gomp_mutex_unlock (&devicep->lock);
+ }
+}
+
/* This function initializes the runtime needed for offloading.
It parses the list of offload targets and tries to load the plugins for
these targets. On return, the variables NUM_DEVICES and NUM_DEVICES_OPENMP
@@ -2341,7 +2387,7 @@ gomp_target_init (void)
/* current_device.capabilities has already been set. */
current_device.type = current_device.get_type_func ();
current_device.mem_map.root = NULL;
- current_device.is_initialized = false;
+ current_device.state = GOMP_DEVICE_UNINITIALIZED;
current_device.openacc.data_environ = NULL;
for (i = 0; i < new_num_devices; i++)
{
@@ -2387,6 +2433,9 @@ gomp_target_init (void)
if (devices[i].capabilities & GOMP_OFFLOAD_CAP_OPENACC_200)
goacc_register (&devices[i]);
}
+
+ if (atexit (gomp_target_fini) != 0)
+ gomp_fatal ("atexit failed");
}
#else /* PLUGIN_SUPPORT */
diff --git a/liboffloadmic/ChangeLog b/liboffloadmic/ChangeLog
index fb9fa851512..c6fd49fbf70 100644
--- a/liboffloadmic/ChangeLog
+++ b/liboffloadmic/ChangeLog
@@ -1,3 +1,9 @@
+2015-12-14 Ilya Verbin <ilya.verbin@intel.com>
+
+ * plugin/libgomp-plugin-intelmic.cpp (unregister_main_image): Remove.
+ (register_main_image): Do not call unregister_main_image at exit.
+ (GOMP_OFFLOAD_fini_device): Allow for OpenMP. Unregister main image.
+
2015-11-19 Ilya Verbin <ilya.verbin@intel.com>
* plugin/libgomp-plugin-intelmic.cpp (struct TargetImageDesc): New.
diff --git a/liboffloadmic/plugin/libgomp-plugin-intelmic.cpp b/liboffloadmic/plugin/libgomp-plugin-intelmic.cpp
index f8c172562ae..68f7b2c898b 100644
--- a/liboffloadmic/plugin/libgomp-plugin-intelmic.cpp
+++ b/liboffloadmic/plugin/libgomp-plugin-intelmic.cpp
@@ -231,12 +231,6 @@ offload (const char *file, uint64_t line, int device, const char *name,
}
static void
-unregister_main_image ()
-{
- __offload_unregister_image (&main_target_image);
-}
-
-static void
register_main_image ()
{
/* Do not check the return value, because old versions of liboffloadmic did
@@ -246,12 +240,6 @@ register_main_image ()
/* liboffloadmic will call GOMP_PLUGIN_target_task_completion when
asynchronous task on target is completed. */
__offload_register_task_callback (GOMP_PLUGIN_target_task_completion);
-
- if (atexit (unregister_main_image) != 0)
- {
- fprintf (stderr, "%s: atexit failed\n", __FILE__);
- exit (1);
- }
}
/* liboffloadmic loads and runs offload_target_main on all available devices
@@ -269,8 +257,9 @@ extern "C" void
GOMP_OFFLOAD_fini_device (int device)
{
TRACE ("(device = %d)", device);
- /* Unreachable for GOMP_OFFLOAD_CAP_OPENMP_400. */
- abort ();
+
+ /* liboffloadmic will finalize target processes on all available devices. */
+ __offload_unregister_image (&main_target_image);
}
static void