summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornathan <nathan@138bc75d-0d04-0410-961f-82ee72b054a4>2015-08-24 17:10:06 +0000
committernathan <nathan@138bc75d-0d04-0410-961f-82ee72b054a4>2015-08-24 17:10:06 +0000
commitd3d8e632f9a4073e705d3af98725f35356b9f7cb (patch)
tree139836bcec017a86c8257b2582f253251c7abb45
parentb8c06a0670bcef3e57e397afa04afcc4965cd002 (diff)
downloadgcc-d3d8e632f9a4073e705d3af98725f35356b9f7cb.tar.gz
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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@227137 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog5
-rw-r--r--gcc/config/nvptx/mkoffload.c24
-rw-r--r--include/ChangeLog6
-rw-r--r--include/gomp-constants.h9
-rw-r--r--libgomp/ChangeLog32
-rw-r--r--libgomp/libgomp.h5
-rw-r--r--libgomp/libgomp.map6
-rw-r--r--libgomp/oacc-host.c10
-rw-r--r--libgomp/plugin/plugin-nvptx.c22
-rw-r--r--libgomp/target.c188
-rw-r--r--liboffloadmic/ChangeLog6
-rw-r--r--liboffloadmic/plugin/libgomp-plugin-intelmic.cpp24
12 files changed, 236 insertions, 101 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 1bac36655a9..6ed8deacea2 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/config/nvptx/mkoffload.c b/gcc/config/nvptx/mkoffload.c
index 1e154c8412c..ba0454e537a 100644
--- a/gcc/config/nvptx/mkoffload.c
+++ b/gcc/config/nvptx/mkoffload.c
@@ -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
diff --git a/include/ChangeLog b/include/ChangeLog
index 6962f858844..c5dd5381a83 100644
--- a/include/ChangeLog
+++ b/include/ChangeLog
@@ -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.
diff --git a/include/gomp-constants.h b/include/gomp-constants.h
index 807e672741a..6e6a8b127a5 100644
--- a/include/gomp-constants.h
+++ b/include/gomp-constants.h
@@ -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
diff --git a/libgomp/ChangeLog b/libgomp/ChangeLog
index 7bb4fafb05f..39c67aff423 100644
--- a/libgomp/ChangeLog
+++ b/libgomp/ChangeLog
@@ -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
diff --git a/libgomp/libgomp.h b/libgomp/libgomp.h
index ac40e2aa510..62454b8527a 100644
--- a/libgomp/libgomp.h
+++ b/libgomp/libgomp.h
@@ -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);
diff --git a/libgomp/libgomp.map b/libgomp/libgomp.map
index 2b2b953e489..ec3c3c1c637 100644
--- a/libgomp/libgomp.map
+++ b/libgomp/libgomp.map
@@ -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;
diff --git a/libgomp/oacc-host.c b/libgomp/oacc-host.c
index 17a5102042b..55bb16b278a 100644
--- a/libgomp/oacc-host.c
+++ b/libgomp/oacc-host.c
@@ -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,
diff --git a/libgomp/plugin/plugin-nvptx.c b/libgomp/plugin/plugin-nvptx.c
index d02a3fd4b9c..a2f950db580 100644
--- a/libgomp/plugin/plugin-nvptx.c
+++ b/libgomp/plugin/plugin-nvptx.c
@@ -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)
diff --git a/libgomp/target.c b/libgomp/target.c
index 7b3d0f9572d..758ece5d78c 100644
--- a/libgomp/target.c
+++ b/libgomp/target.c
@@ -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.
diff --git a/liboffloadmic/ChangeLog b/liboffloadmic/ChangeLog
index 73c711587cb..67a3f6aee5d 100644
--- a/liboffloadmic/ChangeLog
+++ b/liboffloadmic/ChangeLog
@@ -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.
diff --git a/liboffloadmic/plugin/libgomp-plugin-intelmic.cpp b/liboffloadmic/plugin/libgomp-plugin-intelmic.cpp
index aa2d7c69bcd..fde7d9e3820 100644
--- a/liboffloadmic/plugin/libgomp-plugin-intelmic.cpp
+++ b/liboffloadmic/plugin/libgomp-plugin-intelmic.cpp
@@ -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