static struct gomp_device_descr * acc_init_1 (acc_device_t d) { struct gomp_device_descr *base_dev, *acc_dev; int ndevs; base_dev = resolve_device (d); ndevs = base_dev->get_num_devices_func (); if (!base_dev || ndevs <= 0 || goacc_device_num >= ndevs) gomp_fatal ("device %s not supported", name_of_acc_device_t (d)); acc_dev = &base_dev[goacc_device_num]; gomp_mutex_lock (&acc_dev->lock); if (acc_dev->is_initialized) { gomp_mutex_unlock (&acc_dev->lock); gomp_fatal ("device already active"); } gomp_init_device (acc_dev); gomp_mutex_unlock (&acc_dev->lock); return base_dev; }
void acc_set_device_type (acc_device_t d) { struct gomp_device_descr *base_dev, *acc_dev; struct goacc_thread *thr = goacc_thread (); gomp_mutex_lock (&acc_device_lock); if (!cached_base_dev) gomp_init_targets_once (); cached_base_dev = base_dev = resolve_device (d); acc_dev = &base_dev[goacc_device_num]; gomp_mutex_lock (&acc_dev->lock); if (!acc_dev->is_initialized) gomp_init_device (acc_dev); gomp_mutex_unlock (&acc_dev->lock); gomp_mutex_unlock (&acc_device_lock); /* We're changing device type: invalidate the current thread's dev and base_dev pointers. */ if (thr && thr->base_dev != base_dev) { thr->base_dev = thr->dev = NULL; if (thr->mapped_data) gomp_fatal ("acc_set_device_type in 'acc data' region"); } goacc_attach_host_thread_to_device (-1); }
static struct gomp_device_descr * acc_init_1 (acc_device_t d) { struct gomp_device_descr *base_dev, *acc_dev; int ndevs; base_dev = resolve_device (d, true); ndevs = base_dev->get_num_devices_func (); if (ndevs <= 0 || goacc_device_num >= ndevs) acc_dev_num_out_of_range (d, goacc_device_num, ndevs); acc_dev = &base_dev[goacc_device_num]; gomp_mutex_lock (&acc_dev->lock); if (acc_dev->is_initialized) { gomp_mutex_unlock (&acc_dev->lock); gomp_fatal ("device already active"); } gomp_init_device (acc_dev); gomp_mutex_unlock (&acc_dev->lock); return base_dev; }
void acc_set_device_num (int n, acc_device_t d) { const struct gomp_device_descr *dev; int num_devices; if (!base_dev) gomp_init_targets_once (); if ((int) d == 0) { int i; /* A device setting of zero sets all device types on the system to use the Nth instance of that device type. Only attempt it for initialized devices though. */ for (i = acc_device_not_host + 1; i < _ACC_device_hwm; i++) { dev = resolve_device (d); if (dev && dev->is_initialized) dev->openacc.set_device_num_func (n); } /* ...and for future calls to acc_init/acc_set_device_type, etc. */ goacc_device_num = n; } else { struct goacc_thread *thr = goacc_thread (); gomp_mutex_lock (&acc_device_lock); base_dev = lazy_init (d); num_devices = base_dev->get_num_devices_func (); if (n >= num_devices) gomp_fatal ("device %u out of range", n); /* If we're changing the device number, de-associate this thread with the device (but don't close the device, since it may be in use by other threads). */ if (thr && thr->dev && n != thr->dev->target_id) thr->dev = NULL; lazy_open (n); gomp_mutex_unlock (&acc_device_lock); } }
void acc_set_device_num (int ord, acc_device_t d) { struct gomp_device_descr *base_dev, *acc_dev; int num_devices; if (!cached_base_dev) gomp_init_targets_once (); if (ord < 0) ord = goacc_device_num; if ((int) d == 0) /* Set whatever device is being used by the current host thread to use device instance ORD. It's unclear if this is supposed to affect other host threads too (OpenACC 2.0 (3.2.4) acc_set_device_num). */ goacc_attach_host_thread_to_device (ord); else { gomp_mutex_lock (&acc_device_lock); cached_base_dev = base_dev = resolve_device (d); num_devices = base_dev->get_num_devices_func (); if (ord >= num_devices) gomp_fatal ("device %u out of range", ord); acc_dev = &base_dev[ord]; gomp_mutex_lock (&acc_dev->lock); if (!acc_dev->is_initialized) gomp_init_device (acc_dev); gomp_mutex_unlock (&acc_dev->lock); gomp_mutex_unlock (&acc_device_lock); goacc_attach_host_thread_to_device (ord); } goacc_device_num = ord; }
static struct gomp_device_descr * acc_init_1 (acc_device_t d) { struct gomp_device_descr *acc_dev; acc_dev = resolve_device (d); if (!acc_dev || acc_dev->get_num_devices_func () <= 0) gomp_fatal ("device %u not supported", (unsigned)d); if (acc_dev->is_initialized) gomp_fatal ("device already active"); /* We need to remember what we were intialized as, to check shutdown etc. */ init_key = d; gomp_init_device (acc_dev); return acc_dev; }
int acc_get_device_num (acc_device_t d) { const struct gomp_device_descr *dev; struct goacc_thread *thr = goacc_thread (); if (d >= _ACC_device_hwm) gomp_fatal ("unknown device type %u", (unsigned) d); if (!cached_base_dev) gomp_init_targets_once (); gomp_mutex_lock (&acc_device_lock); dev = resolve_device (d, true); gomp_mutex_unlock (&acc_device_lock); if (thr && thr->base_dev == dev && thr->dev) return thr->dev->target_id; return goacc_device_num; }
acc_device_t acc_get_device_type (void) { acc_device_t res = acc_device_none; const struct gomp_device_descr *dev; if (base_dev) res = acc_device_type (base_dev->type); else { gomp_init_targets_once (); dev = resolve_device (acc_device_default); res = acc_device_type (dev->type); } assert (res != acc_device_default && res != acc_device_not_host); return res; }
int acc_get_num_devices (acc_device_t d) { int n = 0; const struct gomp_device_descr *acc_dev; if (d == acc_device_none) return 0; if (!base_dev) gomp_init_targets_once (); acc_dev = resolve_device (d); if (!acc_dev) return 0; n = acc_dev->get_num_devices_func (); if (n < 0) n = 0; return n; }
int acc_get_device_num (acc_device_t d) { const struct gomp_device_descr *dev; struct goacc_thread *thr = goacc_thread (); if (d >= _ACC_device_hwm) gomp_fatal ("device %u out of range", (unsigned)d); if (!cached_base_dev) gomp_init_targets_once (); gomp_mutex_lock (&acc_device_lock); dev = resolve_device (d); gomp_mutex_unlock (&acc_device_lock); if (!dev) gomp_fatal ("device %s not supported", name_of_acc_device_t (d)); if (thr && thr->base_dev == dev && thr->dev) return thr->dev->target_id; return goacc_device_num; }
acc_device_t acc_get_device_type (void) { acc_device_t res = acc_device_none; struct gomp_device_descr *dev; struct goacc_thread *thr = goacc_thread (); if (thr && thr->base_dev) res = acc_device_type (thr->base_dev->type); else { gomp_init_targets_once (); gomp_mutex_lock (&acc_device_lock); dev = resolve_device (acc_device_default); gomp_mutex_unlock (&acc_device_lock); res = acc_device_type (dev->type); } assert (res != acc_device_default && res != acc_device_not_host); return res; }
int acc_get_num_devices (acc_device_t d) { int n = 0; struct gomp_device_descr *acc_dev; if (d == acc_device_none) return 0; gomp_init_targets_once (); gomp_mutex_lock (&acc_device_lock); acc_dev = resolve_device (d); gomp_mutex_unlock (&acc_device_lock); if (!acc_dev) return 0; n = acc_dev->get_num_devices_func (); if (n < 0) n = 0; return n; }
int acc_get_device_num (acc_device_t d) { const struct gomp_device_descr *dev; int num; if (d >= _ACC_device_hwm) gomp_fatal ("device %u out of range", (unsigned)d); if (!base_dev) gomp_init_targets_once (); dev = resolve_device (d); if (!dev) gomp_fatal ("no devices of type %u", d); /* We might not have called lazy_open for this host thread yet, in which case the get_device_num_func hook will return -1. */ num = dev->openacc.get_device_num_func (); if (num < 0) num = goacc_device_num; return num; }
static void acc_shutdown_1 (acc_device_t d) { struct gomp_device_descr *base_dev; struct goacc_thread *walk; int ndevs, i; bool devices_active = false; /* Get the base device for this device type. */ base_dev = resolve_device (d); if (!base_dev) gomp_fatal ("device %s not supported", name_of_acc_device_t (d)); gomp_mutex_lock (&goacc_thread_lock); /* Free target-specific TLS data and close all devices. */ for (walk = goacc_threads; walk != NULL; walk = walk->next) { if (walk->target_tls) base_dev->openacc.destroy_thread_data_func (walk->target_tls); walk->target_tls = NULL; /* This would mean the user is shutting down OpenACC in the middle of an "acc data" pragma. Likely not intentional. */ if (walk->mapped_data) { gomp_mutex_unlock (&goacc_thread_lock); gomp_fatal ("shutdown in 'acc data' region"); } /* Similarly, if this happens then user code has done something weird. */ if (walk->saved_bound_dev) { gomp_mutex_unlock (&goacc_thread_lock); gomp_fatal ("shutdown during host fallback"); } if (walk->dev) { gomp_mutex_lock (&walk->dev->lock); gomp_free_memmap (&walk->dev->mem_map); gomp_mutex_unlock (&walk->dev->lock); walk->dev = NULL; walk->base_dev = NULL; } } gomp_mutex_unlock (&goacc_thread_lock); ndevs = base_dev->get_num_devices_func (); /* Close all the devices of this type that have been opened. */ for (i = 0; i < ndevs; i++) { struct gomp_device_descr *acc_dev = &base_dev[i]; gomp_mutex_lock (&acc_dev->lock); if (acc_dev->is_initialized) { devices_active = true; gomp_fini_device (acc_dev); } gomp_mutex_unlock (&acc_dev->lock); } if (!devices_active) gomp_fatal ("no device initialized"); }