aboutsummaryrefslogtreecommitdiff
path: root/libgomp/target.c
diff options
context:
space:
mode:
Diffstat (limited to 'libgomp/target.c')
-rw-r--r--libgomp/target.c214
1 files changed, 188 insertions, 26 deletions
diff --git a/libgomp/target.c b/libgomp/target.c
index dbc4535..a64ee96 100644
--- a/libgomp/target.c
+++ b/libgomp/target.c
@@ -146,7 +146,8 @@ resolve_device (int device_id, bool remapped)
called, which must be done before using default_device_var. */
int num_devices = gomp_get_num_devices ();
- if (remapped && device_id == GOMP_DEVICE_ICV)
+ if ((remapped && device_id == GOMP_DEVICE_ICV)
+ || device_id == GOMP_DEVICE_DEFAULT_OMP_61)
{
struct gomp_task_icv *icv = gomp_icv (false);
device_id = icv->default_device_var;
@@ -5136,45 +5137,78 @@ omp_get_num_interop_properties (const omp_interop_t interop
}
omp_intptr_t
-omp_get_interop_int (const omp_interop_t interop __attribute__ ((unused)),
+omp_get_interop_int (const omp_interop_t interop,
omp_interop_property_t property_id,
omp_interop_rc_t *ret_code)
{
- if (ret_code == NULL)
- return 0;
+ struct interop_obj_t *obj = (struct interop_obj_t *) interop;
+ struct gomp_device_descr *devicep;
+
if (property_id < omp_ipr_first || property_id >= 0)
- *ret_code = omp_irc_out_of_range;
- else
- *ret_code = omp_irc_empty; /* Assume omp_interop_none. */
- return 0;
+ {
+ if (ret_code)
+ *ret_code = omp_irc_out_of_range;
+ return 0;
+ }
+ if (obj == NULL
+ || (devicep = resolve_device (obj->device_num, false)) == NULL
+ || devicep->get_interop_int_func == NULL)
+ {
+ if (ret_code)
+ *ret_code = omp_irc_empty; /* Assume omp_interop_none. */
+ return 0;
+ }
+ return devicep->get_interop_int_func (obj, property_id, ret_code);
}
void *
-omp_get_interop_ptr (const omp_interop_t interop __attribute__ ((unused)),
+omp_get_interop_ptr (const omp_interop_t interop,
omp_interop_property_t property_id,
omp_interop_rc_t *ret_code)
{
- if (ret_code == NULL)
- return NULL;
+ struct interop_obj_t *obj = (struct interop_obj_t *) interop;
+ struct gomp_device_descr *devicep;
+
if (property_id < omp_ipr_first || property_id >= 0)
- *ret_code = omp_irc_out_of_range;
- else
- *ret_code = omp_irc_empty; /* Assume omp_interop_none. */
- return NULL;
+ {
+ if (ret_code)
+ *ret_code = omp_irc_out_of_range;
+ return 0;
+ }
+ if (obj == NULL
+ || (devicep = resolve_device (obj->device_num, false)) == NULL
+ || devicep->get_interop_int_func == NULL)
+ {
+ if (ret_code)
+ *ret_code = omp_irc_empty; /* Assume omp_interop_none. */
+ return 0;
+ }
+ return devicep->get_interop_ptr_func (obj, property_id, ret_code);
}
const char *
-omp_get_interop_str (const omp_interop_t interop __attribute__ ((unused)),
+omp_get_interop_str (const omp_interop_t interop,
omp_interop_property_t property_id,
omp_interop_rc_t *ret_code)
{
- if (ret_code == NULL)
- return NULL;
+ struct interop_obj_t *obj = (struct interop_obj_t *) interop;
+ struct gomp_device_descr *devicep;
+
if (property_id < omp_ipr_first || property_id >= 0)
- *ret_code = omp_irc_out_of_range;
- else
- *ret_code = omp_irc_empty; /* Assume omp_interop_none. */
- return NULL;
+ {
+ if (ret_code)
+ *ret_code = omp_irc_out_of_range;
+ return 0;
+ }
+ if (obj == NULL
+ || (devicep = resolve_device (obj->device_num, false)) == NULL
+ || devicep->get_interop_int_func == NULL)
+ {
+ if (ret_code)
+ *ret_code = omp_irc_empty; /* Assume omp_interop_none. */
+ return 0;
+ }
+ return devicep->get_interop_str_func (obj, property_id, ret_code);
}
const char *
@@ -5194,18 +5228,24 @@ omp_get_interop_type_desc (const omp_interop_t interop,
omp_interop_property_t property_id)
{
static const char *desc[omp_ipr_fr_id - omp_ipr_device_num + 1]
- = {"omp_interop_t", /* fr_id */
- "const char*", /* fr_name */
+ = {"omp_interop_t", /* fr_id */
+ "const char *", /* fr_name */
"int", /* vendor */
"const char *", /* vendor_name */
"int"}; /* device_num */
+
+ struct interop_obj_t *obj = (struct interop_obj_t *) interop;
+ struct gomp_device_descr *devicep;
+
if (property_id > omp_ipr_fr_id || property_id < omp_ipr_first)
return NULL;
- if (interop == omp_interop_none)
+ if (obj == NULL
+ || (devicep = resolve_device (obj->device_num, false)) == NULL
+ || devicep->get_interop_int_func == NULL)
return NULL;
if (property_id >= omp_ipr_device_num)
return desc[omp_ipr_fr_id - property_id];
- return NULL; /* FIXME: Call plugin. */
+ return devicep->get_interop_type_desc_func (obj, property_id);
}
const char *
@@ -5236,6 +5276,120 @@ ialias (omp_get_interop_name)
ialias (omp_get_interop_type_desc)
ialias (omp_get_interop_rc_desc)
+struct interop_data_t
+{
+ int device_num, n_init, n_use, n_destroy;
+ struct interop_obj_t ***init;
+ struct interop_obj_t **use;
+ struct interop_obj_t ***destroy;
+ const int *target_targetsync;
+ const char **prefer_type;
+};
+
+static void
+gomp_interop_internal (void *data)
+{
+ struct interop_data_t *args = (struct interop_data_t *) data;
+ struct gomp_device_descr *devicep;
+
+ /* Destroy objects to free resources. */
+ for (int i = 0; i < args->n_destroy; i++)
+ {
+ struct interop_obj_t **obj = args->destroy[i];
+ if (*obj == NULL /* omp_interop_none */)
+ continue;
+ devicep = resolve_device ((*obj)->device_num, false);
+ if (devicep != NULL && devicep->interop_func)
+ devicep->interop_func (*obj, devicep->target_id,
+ gomp_interop_flag_destroy, false, NULL);
+ free (*obj);
+ *obj = NULL;
+ }
+
+ /* Init streams next to give 'use' more time for completion. */
+ if (args->n_init)
+ {
+ devicep = resolve_device (args->device_num, false);
+ for (int i = 0; i < args->n_init; i++)
+ {
+ struct interop_obj_t **obj = args->init[i];
+ bool targetsync
+ = (args->target_targetsync[i] & GOMP_INTEROP_TARGETSYNC);
+ const char *prefer_type
+ = (args->prefer_type ? args->prefer_type[i] : NULL);
+ if (devicep == NULL || !devicep->interop_func)
+ {
+ *obj = NULL;
+ continue;
+ }
+ *obj =
+ (struct interop_obj_t *) calloc (1, sizeof (struct interop_obj_t));
+ (*obj)->device_num = devicep->target_id;
+ devicep->interop_func (*obj, devicep->target_id,
+ gomp_interop_flag_init, targetsync,
+ prefer_type);
+ }
+ }
+
+ for (int i = 0; i < args->n_use; i++)
+ {
+ struct interop_obj_t *obj = args->use[i];
+ if (obj == NULL)
+ continue;
+ devicep = resolve_device (obj->device_num, false);
+ if (devicep != NULL && devicep->interop_func)
+ devicep->interop_func (obj, devicep->target_id,
+ gomp_interop_flag_use, false, NULL);
+ }
+}
+
+/* Process the OpenMP interop directive. 'init' and 'destroy' take an array
+ of 'omp_interop_t *', 'use' an array of 'omp_interop_t', where
+ 'omp_interop_t' is internally 'struct interop_obj_t *';
+ 'flags' is used for the 'nowait' clause. */
+
+void
+GOMP_interop (int device_num, int n_init, struct interop_obj_t ***init,
+ const int *target_targetsync, const char **prefer_type, int n_use,
+ struct interop_obj_t **use, int n_destroy,
+ struct interop_obj_t ***destroy, unsigned int flags,
+ void **depend)
+{
+ struct interop_data_t args;
+ args.device_num = device_num;
+ args.n_init = n_init;
+ args.n_use = n_use;
+ args.n_destroy = n_destroy;
+ args.init = init;
+ args.target_targetsync = target_targetsync;
+ args.prefer_type = prefer_type;
+ args.use = use;
+ args.destroy = destroy;
+
+ /* No need to create a task for 'init' as that should be fast. */
+ bool use_task = false;
+ if (flags & GOMP_INTEROP_FLAG_NOWAIT)
+ {
+ for (int i = 0; i < n_use && !use_task; i++)
+ if (args.use[i])
+ use_task |= args.use[i]->stream != NULL;
+ for (int i = 0; i < n_destroy && !use_task; i++)
+ if (*args.destroy[i])
+ use_task |= (*args.destroy[i])->stream != NULL;
+ }
+
+ if (use_task)
+ GOMP_task (gomp_interop_internal, &args, NULL, sizeof (args),
+ __alignof__ (args), true, depend ? GOMP_TASK_FLAG_DEPEND : 0,
+ depend, 0, NULL);
+ else
+ {
+ gomp_interop_internal (&args);
+ if (depend)
+ GOMP_taskwait_depend (depend);
+ }
+}
+
static const char *
gomp_get_uid_for_device (struct gomp_device_descr *devicep, int device_num)
{
@@ -5344,6 +5498,14 @@ gomp_load_plugin_for_device (struct gomp_device_descr *device,
DLSYM (host2dev);
DLSYM_OPT (memcpy2d, memcpy2d);
DLSYM_OPT (memcpy3d, memcpy3d);
+ if (DLSYM_OPT (interop, interop))
+ {
+ DLSYM (get_interop_int);
+ DLSYM (get_interop_ptr);
+ DLSYM (get_interop_str);
+ DLSYM (get_interop_type_desc);
+ }
+
device->capabilities = device->get_caps_func ();
if (device->capabilities & GOMP_OFFLOAD_CAP_OPENMP_400)
{