}
}
-/* ACC_DEVICE_LOCK should be held before calling this function. */
+/* ACC_DEVICE_LOCK must be held before calling this function. If FAIL_IS_ERROR
+ is true, this function raises an error if there are no devices of type D,
+ otherwise it returns NULL in that case. */
static struct gomp_device_descr *
-resolve_device (acc_device_t d)
+resolve_device (acc_device_t d, bool fail_is_error)
{
acc_device_t d_arg = d;
&& dispatchers[d]->get_num_devices_func () > 0)
goto found;
- gomp_fatal ("device type %s not supported", goacc_device_type);
+ if (fail_is_error)
+ {
+ gomp_mutex_unlock (&acc_device_lock);
+ gomp_fatal ("device type %s not supported", goacc_device_type);
+ }
+ else
+ return NULL;
}
/* No default device specified, so start scanning for any non-host
d = acc_device_host;
goto found;
}
- gomp_fatal ("no device found");
+ if (fail_is_error)
+ {
+ gomp_mutex_unlock (&acc_device_lock);
+ gomp_fatal ("no device found");
+ }
+ else
+ return NULL;
break;
case acc_device_host:
default:
if (d > _ACC_device_hwm)
- gomp_fatal ("device %u out of range", (unsigned)d);
+ {
+ if (fail_is_error)
+ goto unsupported_device;
+ else
+ return NULL;
+ }
break;
}
found:
&& d != acc_device_default
&& d != acc_device_not_host);
+ if (dispatchers[d] == NULL && fail_is_error)
+ {
+ unsupported_device:
+ gomp_mutex_unlock (&acc_device_lock);
+ gomp_fatal ("device type %s not supported", name_of_acc_device_t (d));
+ }
+
return dispatchers[d];
}
+/* Emit a suitable error if no device of a particular type is available, or
+ the given device number is out-of-range. */
+static void
+acc_dev_num_out_of_range (acc_device_t d, int ord, int ndevs)
+{
+ if (ndevs == 0)
+ gomp_fatal ("no devices of type %s available", name_of_acc_device_t (d));
+ else
+ gomp_fatal ("device %u out of range", ord);
+}
+
/* This is called when plugins have been initialized, and serves to call
(indirectly) the target's device_init hook. Calling multiple times without
- an intervening acc_shutdown_1 call is an error. ACC_DEVICE_LOCK should be
+ an intervening acc_shutdown_1 call is an error. ACC_DEVICE_LOCK must be
held before calling this function. */
static struct gomp_device_descr *
struct gomp_device_descr *base_dev, *acc_dev;
int ndevs;
- base_dev = resolve_device (d);
+ base_dev = resolve_device (d, true);
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));
+ 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];
return base_dev;
}
-/* ACC_DEVICE_LOCK should be held before calling this function. */
+/* ACC_DEVICE_LOCK must be held before calling this function. */
static void
acc_shutdown_1 (acc_device_t d)
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));
+ base_dev = resolve_device (d, true);
gomp_mutex_lock (&goacc_thread_lock);
num_devices = base_dev->get_num_devices_func ();
if (num_devices <= 0 || ord >= num_devices)
- gomp_fatal ("device %u out of range", ord);
+ acc_dev_num_out_of_range (acc_device_type (base_dev->type), ord,
+ num_devices);
if (!thr)
thr = goacc_new_thread ();
gomp_init_targets_once ();
gomp_mutex_lock (&acc_device_lock);
- acc_dev = resolve_device (d);
+ acc_dev = resolve_device (d, false);
gomp_mutex_unlock (&acc_device_lock);
if (!acc_dev)
if (!cached_base_dev)
gomp_init_targets_once ();
- cached_base_dev = base_dev = resolve_device (d);
+ cached_base_dev = base_dev = resolve_device (d, true);
acc_dev = &base_dev[goacc_device_num];
gomp_mutex_lock (&acc_dev->lock);
gomp_init_targets_once ();
gomp_mutex_lock (&acc_device_lock);
- dev = resolve_device (acc_device_default);
+ dev = resolve_device (acc_device_default, true);
gomp_mutex_unlock (&acc_device_lock);
res = acc_device_type (dev->type);
}
struct goacc_thread *thr = goacc_thread ();
if (d >= _ACC_device_hwm)
- gomp_fatal ("device %u out of range", (unsigned)d);
+ 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);
+ dev = resolve_device (d, true);
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;
{
gomp_mutex_lock (&acc_device_lock);
- cached_base_dev = base_dev = resolve_device (d);
+ cached_base_dev = base_dev = resolve_device (d, true);
num_devices = base_dev->get_num_devices_func ();
- if (ord >= num_devices)
- gomp_fatal ("device %u out of range", ord);
+ if (num_devices <= 0 || ord >= num_devices)
+ acc_dev_num_out_of_range (d, ord, num_devices);
acc_dev = &base_dev[ord];