libgomp.h (gomp_device_state): New enum.
authorIlya Verbin <ilya.verbin@intel.com>
Mon, 14 Dec 2015 16:46:54 +0000 (16:46 +0000)
committerIlya Verbin <iverbin@gcc.gnu.org>
Mon, 14 Dec 2015 16:46:54 +0000 (16:46 +0000)
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.

From-SVN: r231623

libgomp/ChangeLog
libgomp/libgomp.h
libgomp/oacc-host.c
libgomp/oacc-init.c
libgomp/target.c
liboffloadmic/ChangeLog
liboffloadmic/plugin/libgomp-plugin-intelmic.cpp

index 1b12354a075c61b89c6ae8de10a1688d1f58a10e..87459270a5e159f598099692e0ad4052b64903f2 100644 (file)
@@ -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
index c467f97788bd3d38f11bef6e4c41b32c9e2f75e5..9d9949ff16a1f58479da3ad2333ca0c8e1c6cdcd 100644 (file)
@@ -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 */
index 98748041bfcfca2407b4a6f0c9da99d7215e58a0..d289b38941d3e2de736d45575bb45f2140b38a02 100644 (file)
@@ -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,
index 9a9a0b0333f71a634bbcb770b0a213a258fc9ba0..c4f7b6742fdb7f1b3043e299facc10cb1c178cbd 100644 (file)
@@ -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);
 
index cf9d0e64c7c241d9870642ee9954da3d74fb6827..932b1761f4e4feeb91797fe16ab34e8ed1066c2b 100644 (file)
@@ -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 */
index fb9fa8515128c6bc2deb98d66329b1645b177f0f..c6fd49fbf70e3d957a584fe524d2eb24fb2f14c2 100644 (file)
@@ -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.
index f8c172562ae9f89d566aac1d32dbda8866694650..68f7b2c898b1522b4c1affb11d2647d0ecb86004 100644 (file)
@@ -230,12 +230,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 ()
 {
@@ -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