Beispiel #1
0
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;
}
Beispiel #2
0
/* 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);
}
Beispiel #3
0
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;
}
Beispiel #4
0
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");
}
Beispiel #5
0
static struct gomp_device_descr *
resolve_device (acc_device_t d, bool fail_is_error)
{
  acc_device_t d_arg = d;

  switch (d)
    {
    case acc_device_default:
      {
	if (goacc_device_type)
	  {
	    /* Lookup the named device.  */
	    while (++d != _ACC_device_hwm)
	      if (dispatchers[d]
		  && !strcasecmp (goacc_device_type,
				  get_openacc_name (dispatchers[d]->name))
		  && dispatchers[d]->get_num_devices_func () > 0)
		goto found;

	    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
	   device that is available.  */
	d = acc_device_not_host;
      }
      /* FALLTHROUGH */

    case acc_device_not_host:
      /* Find the first available device after acc_device_not_host.  */
      while (++d != _ACC_device_hwm)
	if (dispatchers[d] && dispatchers[d]->get_num_devices_func () > 0)
	  goto found;
      if (d_arg == acc_device_default)
	{
	  d = acc_device_host;
	  goto found;
	}
      if (fail_is_error)
        {
	  gomp_mutex_unlock (&acc_device_lock);
	  gomp_fatal ("no device found");
	}
      else
        return NULL;
      break;

    case acc_device_host:
      break;

    default:
      if (d > _ACC_device_hwm)
	{
	  if (fail_is_error)
	    goto unsupported_device;
	  else
	    return NULL;
	}
      break;
    }
 found:

  assert (d != acc_device_none
	  && 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];
}