libgomp.map: Add 4.0.2 version.
authorNathan Sidwell <nathan@codesourcery.com>
Mon, 24 Aug 2015 17:10:06 +0000 (17:10 +0000)
committerNathan Sidwell <nathan@gcc.gnu.org>
Mon, 24 Aug 2015 17:10:06 +0000 (17:10 +0000)
libgomp/
* libgomp.map: Add 4.0.2 version.
* target.c (offload_image_descr): Add version field.
(gomp_load_image_to_device): Add version argument.  Adjust plugin
call.  Improve load mismatch diagnostic.
(gomp_unload_image_from_device): Add version argument.  Adjust plugin
call.
(GOMP_offload_regster): Make stub function, move bulk to ...
(GOMP_offload_register_ver): ... here.  Process version argument.
(GOMP_offload_unregister): Make stub function, move bulk to ...
(GOMP_offload_unregister_ver): ... here.  Process version argument.
(gomp_init_device): Process version field.
(gomp_unload_device): Process version field.
(gomp_load_plugin_for_device): Reimplement DLSYM & DLSYM_OPT
macros.  Check plugin version.
* libgomp.h (gomp_device_descr): Add version function field.  Adjust
loader and unloader types.
* oacc-host.c: Include gomp-constants.h.
(host_version): New.
(host_load_image, host_unload_image): Adjust.
(host_dispatch): Add host_version.
* plugin/plugin-nvptx.c: Include gomp-constants.h.
(GOMP_OFFLOAD_version): New.
(GOMP_OFFLOAD_load_image): Add version arg and check it.
(GOMP_OFFLOAD_unload_image): Likewise.
* plugin/plugin-host.c: Include gomp-constants.h.
(GOMP_OFFLOAD_version): New.
(GOMP_OFFLOAD_load_image): Add version arg.
(GOMP_OFFLOAD_unload_image): Likewise.

liboffloadmic/
* plugin/libgomp-plugin-intelmic.cpp (GOMP_OFFLOAD_version): New.
(GOMP_OFFLOAD_load_image): Add version arg and check it.
(GOMP_OFFLOAD_unload_image): Likewise.

include/
* gomp-constants.h (GOMP_VERSION, GOMP_VERSION_NVIDIA_PTX,
GOMP_VERSION_INTEL_MIC): New.
(GOMP_VERSION_PACK, GOMP_VERSION_LIB, GOMP_VERSION_DEV): New.

gcc/
* config/nvptx/mkoffload.c (process): Replace
GOMP_offload_{,un}register with GOMP_offload_{,un}register_ver.

From-SVN: r227137

12 files changed:
gcc/ChangeLog
gcc/config/nvptx/mkoffload.c
include/ChangeLog
include/gomp-constants.h
libgomp/ChangeLog
libgomp/libgomp.h
libgomp/libgomp.map
libgomp/oacc-host.c
libgomp/plugin/plugin-nvptx.c
libgomp/target.c
liboffloadmic/ChangeLog
liboffloadmic/plugin/libgomp-plugin-intelmic.cpp

index 1bac36655a970e88e5d14c3286bac8dabcb5fb2a..6ed8deacea28c2a6aa5303748a91d380021ff85c 100644 (file)
@@ -1,3 +1,8 @@
+2015-08-24  Nathan Sidwell  <nathan@codesourcery.com>
+
+       * config/nvptx/mkoffload.c (process): Replace
+       GOMP_offload_{,un}register with GOMP_offload_{,un}register_ver.
+
 2015-08-24  H.J. Lu  <hongjiu.lu@intel.com>
 
        PR target/67329
index 1e154c8412c6b7d416b17959ac69234244d7e028..ba0454e537a51eaa7a271c3a537ec1e70eb05658 100644 (file)
@@ -881,10 +881,10 @@ process (FILE *in, FILE *out)
           "extern \"C\" {\n"
           "#endif\n");
 
-  fprintf (out, "extern void GOMP_offload_register"
-          " (const void *, int, const void *);\n");
-  fprintf (out, "extern void GOMP_offload_unregister"
-          " (const void *, int, const void *);\n");
+  fprintf (out, "extern void GOMP_offload_register_ver"
+          " (unsigned, const void *, int, const void *);\n");
+  fprintf (out, "extern void GOMP_offload_unregister_ver"
+          " (unsigned, const void *, int, const void *);\n");
 
   fprintf (out, "#ifdef __cplusplus\n"
           "}\n"
@@ -894,15 +894,19 @@ process (FILE *in, FILE *out)
 
   fprintf (out, "static __attribute__((constructor)) void init (void)\n"
           "{\n"
-          "  GOMP_offload_register (__OFFLOAD_TABLE__, %d/*NVIDIA_PTX*/,\n"
-          "                         &target_data);\n"
-          "};\n", GOMP_DEVICE_NVIDIA_PTX);
+          "  GOMP_offload_register_ver (%#x, __OFFLOAD_TABLE__,"
+          "%d/*NVIDIA_PTX*/, &target_data);\n"
+          "};\n",
+          GOMP_VERSION_PACK (GOMP_VERSION, GOMP_VERSION_NVIDIA_PTX),
+          GOMP_DEVICE_NVIDIA_PTX);
 
   fprintf (out, "static __attribute__((destructor)) void fini (void)\n"
           "{\n"
-          "  GOMP_offload_unregister (__OFFLOAD_TABLE__, %d/*NVIDIA_PTX*/,\n"
-          "                           &target_data);\n"
-          "};\n", GOMP_DEVICE_NVIDIA_PTX);
+          "  GOMP_offload_unregister_ver (%#x, __OFFLOAD_TABLE__,"
+          "%d/*NVIDIA_PTX*/, &target_data);\n"
+          "};\n",
+          GOMP_VERSION_PACK (GOMP_VERSION, GOMP_VERSION_NVIDIA_PTX),
+          GOMP_DEVICE_NVIDIA_PTX);
 }
 
 static void
index 6962f8588443032c0333d7f4c5d128278c448cb6..c5dd5381a838442fc73176c11248cb28fb0deb45 100644 (file)
@@ -1,3 +1,9 @@
+2015-08-24  Nathan Sidwell  <nathan@codesourcery.com>
+
+       * gomp-constants.h (GOMP_VERSION, GOMP_VERSION_NVIDIA_PTX,
+       GOMP_VERSION_INTEL_MIC): New.
+       (GOMP_VERSION_PACK, GOMP_VERSION_LIB, GOMP_VERSION_DEV): New.
+
 2015-08-14  Pierre-Marie de Rodat  <derodat@adacore.com>
 
        * dwarf2.def (DW_AT_GNU_bias): New attribute.
index 807e672741ad5cdcdec81e4c0d29d564ea3bcaaf..6e6a8b127a53b190e2fd7d9e2164f1851f619366 100644 (file)
@@ -113,4 +113,13 @@ enum gomp_map_kind
 #define GOMP_DEVICE_ICV                        -1
 #define GOMP_DEVICE_HOST_FALLBACK      -2
 
+/* Versions of libgomp and device-specific plugins.  */
+#define GOMP_VERSION   0
+#define GOMP_VERSION_NVIDIA_PTX 0
+#define GOMP_VERSION_INTEL_MIC 0
+
+#define GOMP_VERSION_PACK(LIB, DEV) (((LIB) << 16) | (DEV))
+#define GOMP_VERSION_LIB(PACK) (((PACK) >> 16) & 0xffff)
+#define GOMP_VERSION_DEV(PACK) ((PACK) & 0xffff)
+
 #endif
index 7bb4fafb05fc89b2eaf644f9ece3fe4c8c11f736..39c67aff4238515a68e2b06710162ec73e9d7cf4 100644 (file)
@@ -1,3 +1,35 @@
+2015-08-24  Nathan Sidwell  <nathan@codesourcery.com>
+
+       libgomp/
+       * libgomp.map: Add 4.0.2 version.
+       * target.c (offload_image_descr): Add version field.
+       (gomp_load_image_to_device): Add version argument.  Adjust plugin
+       call.  Improve load mismatch diagnostic.
+       (gomp_unload_image_from_device): Add version argument.  Adjust plugin
+       call.
+       (GOMP_offload_regster): Make stub function, move bulk to ...
+       (GOMP_offload_register_ver): ... here.  Process version argument.
+       (GOMP_offload_unregister): Make stub function, move bulk to ...
+       (GOMP_offload_unregister_ver): ... here.  Process version argument.
+       (gomp_init_device): Process version field.
+       (gomp_unload_device): Process version field.
+       (gomp_load_plugin_for_device): Reimplement DLSYM & DLSYM_OPT
+       macros.  Check plugin version.
+       * libgomp.h (gomp_device_descr): Add version function field.  Adjust
+       loader and unloader types.
+       * oacc-host.c: Include gomp-constants.h.
+       (host_version): New.
+       (host_load_image, host_unload_image): Adjust.
+       (host_dispatch): Add host_version.
+       * plugin/plugin-nvptx.c: Include gomp-constants.h.
+       (GOMP_OFFLOAD_version): New.
+       (GOMP_OFFLOAD_load_image): Add version arg and check it.
+       (GOMP_OFFLOAD_unload_image): Likewise.
+       * plugin/plugin-host.c: Include gomp-constants.h.
+       (GOMP_OFFLOAD_version): New.
+       (GOMP_OFFLOAD_load_image): Add version arg.
+       (GOMP_OFFLOAD_unload_image): Likewise.
+
 2015-08-24  Tom de Vries  <tom@codesourcery.com>
 
        PR tree-optimization/65468
index ac40e2aa5100b89477ebe19bfd29221ab29c79d1..62454b8527af9fce45936e8d4fe106e6fae1f9fb 100644 (file)
@@ -748,8 +748,9 @@ struct gomp_device_descr
   int (*get_num_devices_func) (void);
   void (*init_device_func) (int);
   void (*fini_device_func) (int);
-  int (*load_image_func) (int, const void *, struct addr_pair **);
-  void (*unload_image_func) (int, const void *);
+  unsigned (*version_func) (void);
+  int (*load_image_func) (int, unsigned, const void *, struct addr_pair **);
+  void (*unload_image_func) (int, unsigned, const void *);
   void *(*alloc_func) (int, size_t);
   void (*free_func) (int, void *);
   void *(*dev2host_func) (int, void *, const void *, size_t);
index 2b2b953e489068c1dcb3d89c79b4915c931d564a..ec3c3c1c63797dc8d2a830df0b87fe2bae974c89 100644 (file)
@@ -234,6 +234,12 @@ GOMP_4.0.1 {
        GOMP_offload_unregister;
 } GOMP_4.0;
 
+GOMP_4.0.2 {
+  global:
+       GOMP_offload_register_ver;
+       GOMP_offload_unregister_ver;
+} GOMP_4.0.1;
+
 OACC_2.0 {
   global:
        acc_get_num_devices;
index 17a5102042b1381b6b87210d5ff735ad68dc4fef..55bb16b278a5a53b2554f513216eaee39398144d 100644 (file)
@@ -28,6 +28,7 @@
 
 #include "libgomp.h"
 #include "oacc-int.h"
+#include "gomp-constants.h"
 
 #include <stdbool.h>
 #include <stddef.h>
@@ -69,8 +70,15 @@ host_fini_device (int n __attribute__ ((unused)))
 {
 }
 
+static unsigned
+host_version (void)
+{
+  return GOMP_VERSION;
+}
+
 static int
 host_load_image (int n __attribute__ ((unused)),
+                unsigned v __attribute__ ((unused)),
                 const void *t __attribute__ ((unused)),
                 struct addr_pair **r __attribute__ ((unused)))
 {
@@ -79,6 +87,7 @@ host_load_image (int n __attribute__ ((unused)),
 
 static void
 host_unload_image (int n __attribute__ ((unused)),
+                  unsigned v __attribute__ ((unused)),
                   const void *t __attribute__ ((unused)))
 {
 }
@@ -206,6 +215,7 @@ static struct gomp_device_descr host_dispatch =
     .get_num_devices_func = host_get_num_devices,
     .init_device_func = host_init_device,
     .fini_device_func = host_fini_device,
+    .version_func = host_version,
     .load_image_func = host_load_image,
     .unload_image_func = host_unload_image,
     .alloc_func = host_alloc,
index d02a3fd4b9c2f7024a175512f03eef9dc31b0f3f..a2f950db580a2f5b454c3b603e3c4cc6d5ef4d68 100644 (file)
@@ -36,6 +36,7 @@
 #include "libgomp-plugin.h"
 #include "oacc-ptx.h"
 #include "oacc-plugin.h"
+#include "gomp-constants.h"
 
 #include <pthread.h>
 #include <cuda.h>
@@ -1570,11 +1571,20 @@ typedef struct nvptx_tdata
   size_t fn_num;
 } nvptx_tdata_t;
 
+/* Return the libgomp version number we're compatible with.  There is
+   no requirement for cross-version compatibility.  */
+
+unsigned
+GOMP_OFFLOAD_version (void)
+{
+  return GOMP_VERSION;
+}
+
 /* Load the (partial) program described by TARGET_DATA to device
    number ORD.  Allocate and return TARGET_TABLE.  */
 
 int
-GOMP_OFFLOAD_load_image (int ord, const void *target_data,
+GOMP_OFFLOAD_load_image (int ord, unsigned version, const void *target_data,
                         struct addr_pair **target_table)
 {
   CUmodule module;
@@ -1587,6 +1597,11 @@ GOMP_OFFLOAD_load_image (int ord, const void *target_data,
   struct ptx_image_data *new_image;
   struct ptx_device *dev;
 
+  if (GOMP_VERSION_DEV (version) > GOMP_VERSION_NVIDIA_PTX)
+    GOMP_PLUGIN_fatal ("Offload data incompatible with PTX plugin"
+                      " (expected %u, received %u)",
+                      GOMP_VERSION_NVIDIA_PTX, GOMP_VERSION_DEV (version));
+  
   GOMP_OFFLOAD_init_device (ord);
 
   dev = ptx_devices[ord];
@@ -1656,11 +1671,14 @@ GOMP_OFFLOAD_load_image (int ord, const void *target_data,
    function descriptors allocated by G_O_load_image.  */
 
 void
-GOMP_OFFLOAD_unload_image (int ord, const void *target_data)
+GOMP_OFFLOAD_unload_image (int ord, unsigned version, const void *target_data)
 {
   struct ptx_image_data *image, **prev_p;
   struct ptx_device *dev = ptx_devices[ord];
 
+  if (GOMP_VERSION_DEV (version) > GOMP_VERSION_NVIDIA_PTX)
+    return;
+  
   pthread_mutex_lock (&dev->image_lock);
   for (prev_p = &dev->images; (image = *prev_p) != 0; prev_p = &image->next)
     if (image->target_data == target_data)
index 7b3d0f9572d555fc7722c9a651635689f20d6205..758ece5d78c0e476a10cdd31cf65919899a621aa 100644 (file)
@@ -56,6 +56,7 @@ static gomp_mutex_t register_lock;
    It contains type of the target device, pointer to host table descriptor, and
    pointer to target data.  */
 struct offload_image_descr {
+  unsigned version;
   enum offload_target_type type;
   const void *host_table;
   const void *target_data;
@@ -642,7 +643,7 @@ gomp_update (struct gomp_device_descr *devicep, size_t mapnum, void **hostaddrs,
    emitting variable and functions in the same order.  */
 
 static void
-gomp_load_image_to_device (struct gomp_device_descr *devicep,
+gomp_load_image_to_device (struct gomp_device_descr *devicep, unsigned version,
                           const void *host_table, const void *target_data,
                           bool is_register_lock)
 {
@@ -658,16 +659,20 @@ gomp_load_image_to_device (struct gomp_device_descr *devicep,
 
   /* Load image to device and get target addresses for the image.  */
   struct addr_pair *target_table = NULL;
-  int i, num_target_entries
-    = devicep->load_image_func (devicep->target_id, target_data,
-                               &target_table);
+  int i, num_target_entries;
+
+  num_target_entries
+    = devicep->load_image_func (devicep->target_id, version,
+                               target_data, &target_table);
 
   if (num_target_entries != num_funcs + num_vars)
     {
       gomp_mutex_unlock (&devicep->lock);
       if (is_register_lock)
        gomp_mutex_unlock (&register_lock);
-      gomp_fatal ("Can't map target functions or variables");
+      gomp_fatal ("Cannot map target functions or variables"
+                 " (expected %u, have %u)", num_funcs + num_vars,
+                 num_target_entries);
     }
 
   /* Insert host-target address mapping into splay tree.  */
@@ -732,6 +737,7 @@ gomp_load_image_to_device (struct gomp_device_descr *devicep,
 
 static void
 gomp_unload_image_from_device (struct gomp_device_descr *devicep,
+                              unsigned version,
                               const void *host_table, const void *target_data)
 {
   void **host_func_table = ((void ***) host_table)[0];
@@ -756,8 +762,8 @@ gomp_unload_image_from_device (struct gomp_device_descr *devicep,
       k.host_end = k.host_start + 1;
       node = splay_tree_lookup (&devicep->mem_map, &k);
     }
-  
-  devicep->unload_image_func (devicep->target_id, target_data);
+
+  devicep->unload_image_func (devicep->target_id, version, target_data);
 
   /* Remove mappings from splay tree.  */
   for (j = 0; j < num_funcs; j++)
@@ -786,10 +792,15 @@ gomp_unload_image_from_device (struct gomp_device_descr *devicep,
    the target, and TARGET_DATA needed by target plugin.  */
 
 void
-GOMP_offload_register (const void *host_table, int target_type,
-                      const void *target_data)
+GOMP_offload_register_ver (unsigned version, const void *host_table,
+                          int target_type, const void *target_data)
 {
   int i;
+
+  if (GOMP_VERSION_LIB (version) > GOMP_VERSION)
+    gomp_fatal ("Library too old for offload (version %u < %u)",
+               GOMP_VERSION, GOMP_VERSION_LIB (version));
+  
   gomp_mutex_lock (&register_lock);
 
   /* Load image to all initialized devices.  */
@@ -798,7 +809,8 @@ GOMP_offload_register (const void *host_table, int target_type,
       struct gomp_device_descr *devicep = &devices[i];
       gomp_mutex_lock (&devicep->lock);
       if (devicep->type == target_type && devicep->is_initialized)
-       gomp_load_image_to_device (devicep, host_table, target_data, true);
+       gomp_load_image_to_device (devicep, version,
+                                  host_table, target_data, true);
       gomp_mutex_unlock (&devicep->lock);
     }
 
@@ -807,6 +819,7 @@ GOMP_offload_register (const void *host_table, int target_type,
     = gomp_realloc_unlock (offload_images,
                           (num_offload_images + 1)
                           * sizeof (struct offload_image_descr));
+  offload_images[num_offload_images].version = version;
   offload_images[num_offload_images].type = target_type;
   offload_images[num_offload_images].host_table = host_table;
   offload_images[num_offload_images].target_data = target_data;
@@ -815,13 +828,20 @@ GOMP_offload_register (const void *host_table, int target_type,
   gomp_mutex_unlock (&register_lock);
 }
 
+void
+GOMP_offload_register (const void *host_table, int target_type,
+                      const void *target_data)
+{
+  GOMP_offload_register_ver (0, host_table, target_type, target_data);
+}
+
 /* This function should be called from every offload image while unloading.
    It gets the descriptor of the host func and var tables HOST_TABLE, TYPE of
    the target, and TARGET_DATA needed by target plugin.  */
 
 void
-GOMP_offload_unregister (const void *host_table, int target_type,
-                        const void *target_data)
+GOMP_offload_unregister_ver (unsigned version, const void *host_table,
+                            int target_type, const void *target_data)
 {
   int i;
 
@@ -833,7 +853,8 @@ GOMP_offload_unregister (const void *host_table, int target_type,
       struct gomp_device_descr *devicep = &devices[i];
       gomp_mutex_lock (&devicep->lock);
       if (devicep->type == target_type && devicep->is_initialized)
-       gomp_unload_image_from_device (devicep, host_table, target_data);
+       gomp_unload_image_from_device (devicep, version,
+                                      host_table, target_data);
       gomp_mutex_unlock (&devicep->lock);
     }
 
@@ -848,6 +869,13 @@ GOMP_offload_unregister (const void *host_table, int target_type,
   gomp_mutex_unlock (&register_lock);
 }
 
+void
+GOMP_offload_unregister (const void *host_table, int target_type,
+                        const void *target_data)
+{
+  GOMP_offload_unregister_ver (0, host_table, target_type, target_data);
+}
+
 /* This function initializes the target device, specified by DEVICEP.  DEVICEP
    must be locked on entry, and remains locked on return.  */
 
@@ -862,8 +890,9 @@ gomp_init_device (struct gomp_device_descr *devicep)
     {
       struct offload_image_descr *image = &offload_images[i];
       if (image->type == devicep->type)
-       gomp_load_image_to_device (devicep, image->host_table,
-                                  image->target_data, false);
+       gomp_load_image_to_device (devicep, image->version,
+                                  image->host_table, image->target_data,
+                                  false);
     }
 
   devicep->is_initialized = true;
@@ -881,7 +910,8 @@ gomp_unload_device (struct gomp_device_descr *devicep)
        {
          struct offload_image_descr *image = &offload_images[i];
          if (image->type == devicep->type)
-           gomp_unload_image_from_device (devicep, image->host_table,
+           gomp_unload_image_from_device (devicep, image->version,
+                                          image->host_table,
                                           image->target_data);
        }
     }
@@ -1085,43 +1115,29 @@ gomp_load_plugin_for_device (struct gomp_device_descr *device,
                             const char *plugin_name)
 {
   const char *err = NULL, *last_missing = NULL;
-  int optional_present, optional_total;
-
-  /* Clear any existing error.  */
-  dlerror ();
 
   void *plugin_handle = dlopen (plugin_name, RTLD_LAZY);
   if (!plugin_handle)
-    {
-      err = dlerror ();
-      goto out;
-    }
+    goto dl_fail;
 
   /* Check if all required functions are available in the plugin and store
-     their handlers.  */
+     their handlers.  None of the symbols can legitimately be NULL,
+     so we don't need to check dlerror all the time.  */
 #define DLSYM(f)                                                       \
-  do                                                                   \
-    {                                                                  \
-      device->f##_func = dlsym (plugin_handle, "GOMP_OFFLOAD_" #f);    \
-      err = dlerror ();                                                        \
-      if (err != NULL)                                                 \
-       goto out;                                                       \
-    }                                                                  \
-  while (0)
-  /* Similar, but missing functions are not an error.  */
-#define DLSYM_OPT(f, n)                                                \
-  do                                                                   \
-    {                                                                  \
-      const char *tmp_err;                                                     \
-      device->f##_func = dlsym (plugin_handle, "GOMP_OFFLOAD_" #n);    \
-      tmp_err = dlerror ();                                            \
-      if (tmp_err == NULL)                                             \
-        optional_present++;                                            \
-      else                                                             \
-        last_missing = #n;                                             \
-      optional_total++;                                                        \
-    }                                                                  \
-  while (0)
+  if (!(device->f##_func = dlsym (plugin_handle, "GOMP_OFFLOAD_" #f))) \
+    goto dl_fail
+  /* Similar, but missing functions are not an error.  Return false if
+     failed, true otherwise.  */
+#define DLSYM_OPT(f, n)                                                        \
+  ((device->f##_func = dlsym (plugin_handle, "GOMP_OFFLOAD_" #n))      \
+   || (last_missing = #n, 0))
+
+  DLSYM (version);
+  if (device->version_func () != GOMP_VERSION)
+    {
+      err = "plugin version mismatch";
+      goto fail;
+    }
 
   DLSYM (get_name);
   DLSYM (get_caps);
@@ -1140,53 +1156,57 @@ gomp_load_plugin_for_device (struct gomp_device_descr *device,
     DLSYM (run);
   if (device->capabilities & GOMP_OFFLOAD_CAP_OPENACC_200)
     {
-      optional_present = optional_total = 0;
-      DLSYM_OPT (openacc.exec, openacc_parallel);
-      DLSYM_OPT (openacc.register_async_cleanup,
-                openacc_register_async_cleanup);
-      DLSYM_OPT (openacc.async_test, openacc_async_test);
-      DLSYM_OPT (openacc.async_test_all, openacc_async_test_all);
-      DLSYM_OPT (openacc.async_wait, openacc_async_wait);
-      DLSYM_OPT (openacc.async_wait_async, openacc_async_wait_async);
-      DLSYM_OPT (openacc.async_wait_all, openacc_async_wait_all);
-      DLSYM_OPT (openacc.async_wait_all_async, openacc_async_wait_all_async);
-      DLSYM_OPT (openacc.async_set_async, openacc_async_set_async);
-      DLSYM_OPT (openacc.create_thread_data, openacc_create_thread_data);
-      DLSYM_OPT (openacc.destroy_thread_data, openacc_destroy_thread_data);
-      /* Require all the OpenACC handlers if we have
-        GOMP_OFFLOAD_CAP_OPENACC_200.  */
-      if (optional_present != optional_total)
+      if (!DLSYM_OPT (openacc.exec, openacc_parallel)
+         || !DLSYM_OPT (openacc.register_async_cleanup,
+                        openacc_register_async_cleanup)
+         || !DLSYM_OPT (openacc.async_test, openacc_async_test)
+         || !DLSYM_OPT (openacc.async_test_all, openacc_async_test_all)
+         || !DLSYM_OPT (openacc.async_wait, openacc_async_wait)
+         || !DLSYM_OPT (openacc.async_wait_async, openacc_async_wait_async)
+         || !DLSYM_OPT (openacc.async_wait_all, openacc_async_wait_all)
+         || !DLSYM_OPT (openacc.async_wait_all_async,
+                        openacc_async_wait_all_async)
+         || !DLSYM_OPT (openacc.async_set_async, openacc_async_set_async)
+         || !DLSYM_OPT (openacc.create_thread_data,
+                        openacc_create_thread_data)
+         || !DLSYM_OPT (openacc.destroy_thread_data,
+                        openacc_destroy_thread_data))
        {
+         /* Require all the OpenACC handlers if we have
+            GOMP_OFFLOAD_CAP_OPENACC_200.  */
          err = "plugin missing OpenACC handler function";
-         goto out;
+         goto fail;
        }
-      optional_present = optional_total = 0;
-      DLSYM_OPT (openacc.cuda.get_current_device,
-                openacc_get_current_cuda_device);
-      DLSYM_OPT (openacc.cuda.get_current_context,
-                openacc_get_current_cuda_context);
-      DLSYM_OPT (openacc.cuda.get_stream, openacc_get_cuda_stream);
-      DLSYM_OPT (openacc.cuda.set_stream, openacc_set_cuda_stream);
-      /* Make sure all the CUDA functions are there if any of them are.  */
-      if (optional_present && optional_present != optional_total)
+
+      unsigned cuda = 0;
+      cuda += DLSYM_OPT (openacc.cuda.get_current_device,
+                        openacc_get_current_cuda_device);
+      cuda += DLSYM_OPT (openacc.cuda.get_current_context,
+                        openacc_get_current_cuda_context);
+      cuda += DLSYM_OPT (openacc.cuda.get_stream, openacc_get_cuda_stream);
+      cuda += DLSYM_OPT (openacc.cuda.set_stream, openacc_set_cuda_stream);
+      if (cuda && cuda != 4)
        {
+         /* Make sure all the CUDA functions are there if any of them are.  */
          err = "plugin missing OpenACC CUDA handler function";
-         goto out;
+         goto fail;
        }
     }
 #undef DLSYM
 #undef DLSYM_OPT
 
- out:
-  if (err != NULL)
-    {
-      gomp_error ("while loading %s: %s", plugin_name, err);
-      if (last_missing)
-        gomp_error ("missing function was %s", last_missing);
-      if (plugin_handle)
-       dlclose (plugin_handle);
-    }
-  return err == NULL;
+  return 1;
+
+ dl_fail:
+  err = dlerror ();
+ fail:
+  gomp_error ("while loading %s: %s", plugin_name, err);
+  if (last_missing)
+    gomp_error ("missing function was %s", last_missing);
+  if (plugin_handle)
+    dlclose (plugin_handle);
+
+  return 0;
 }
 
 /* This function initializes the runtime needed for offloading.
index 73c711587cba5df8446f619dee3ab575f6c54031..67a3f6aee5d27029a937600fc99262b50afe8ada 100644 (file)
@@ -1,3 +1,9 @@
+2015-08-24  Nathan Sidwell  <nathan@codesourcery.com>
+
+       * plugin/libgomp-plugin-intelmic.cpp (GOMP_OFFLOAD_version): New.
+       (GOMP_OFFLOAD_load_image): Add version arg and check it.
+       (GOMP_OFFLOAD_unload_image): Likewise.
+
 2015-08-24  Thomas Schwinge  <thomas@codesourcery.com>
 
        * plugin/Makefile.am (include_src_dir): Set.
index aa2d7c69bcd1714192c523a14f037cd7b838fca4..fde7d9e382067dde7618ed3727115e6ef55620c7 100644 (file)
@@ -328,12 +328,26 @@ offload_image (const void *target_image)
   free (image);
 }
 
+/* Return the libgomp version number we're compatible with.  There is
+   no requirement for cross-version compatibility.  */
+
+extern "C" unsigned
+GOMP_OFFLOAD_version (void)
+{
+  return GOMP_VERSION;
+}
+
 extern "C" int
-GOMP_OFFLOAD_load_image (int device, const void *target_image,
-                        addr_pair **result)
+GOMP_OFFLOAD_load_image (int device, const unsigned version,
+                        void *target_image, addr_pair **result)
 {
   TRACE ("(device = %d, target_image = %p)", device, target_image);
 
+  if (GOMP_VERSION_DEV (version) > GOMP_VERSION_INTEL_MIC)
+    GOMP_PLUGIN_fatal ("Offload data incompatible with intelmic plugin"
+                      " (expected %u, received %u)",
+                      GOMP_VERSION_INTEL_MIC, GOMP_VERSION_DEV (version));
+
   /* If target_image is already present in address_table, then there is no need
      to offload it.  */
   if (address_table->count (target_image) == 0)
@@ -354,8 +368,12 @@ GOMP_OFFLOAD_load_image (int device, const void *target_image,
 }
 
 extern "C" void
-GOMP_OFFLOAD_unload_image (int device, const void *target_image)
+GOMP_OFFLOAD_unload_image (int device, unsigned version,
+                          const void *target_image)
 {
+  if (GOMP_VERSION_DEV (version) > GOMP_VERSION_INTEL_MIC)
+    return;
+
   TRACE ("(device = %d, target_image = %p)", device, target_image);
 
   /* TODO: Currently liboffloadmic doesn't support __offload_unregister_image