Exemple #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;
}
Exemple #2
0
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);
}
Exemple #3
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, 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;
}
Exemple #4
0
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);
    }
}
Exemple #5
0
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;
}
Exemple #6
0
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;
}
Exemple #7
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 ("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;
}
Exemple #8
0
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;
}
Exemple #9
0
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;
}
Exemple #10
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;
}
Exemple #11
0
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;
}
Exemple #12
0
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;
}
Exemple #13
0
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;
}
Exemple #14
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");
}