static void lazy_open (int ord) { struct goacc_thread *thr = goacc_thread (); struct gomp_device_descr *acc_dev; if (thr && thr->dev) { assert (ord < 0 || ord == thr->dev->target_id); return; } assert (base_dev); if (ord < 0) ord = goacc_device_num; /* The OpenACC 2.0 spec leaves the runtime's behaviour when an out-of-range device is requested as implementation-defined (4.2 ACC_DEVICE_NUM). We choose to raise an error in such a case. */ if (ord >= base_dev->get_num_devices_func ()) gomp_fatal ("device %u does not exist", ord); if (!thr) thr = goacc_new_thread (); acc_dev = thr->dev = &base_dev[ord]; assert (acc_dev->target_id == ord); thr->saved_bound_dev = NULL; thr->mapped_data = NULL; if (!acc_dev->openacc.target_data) acc_dev->openacc.target_data = acc_dev->openacc.open_device_func (ord); thr->target_tls = acc_dev->openacc.create_thread_data_func (acc_dev->openacc.target_data); acc_dev->openacc.async_set_async_func (acc_async_sync); struct gomp_memory_mapping *mem_map = &acc_dev->mem_map; gomp_mutex_lock (&mem_map->lock); if (!mem_map->is_initialized) gomp_init_tables (acc_dev, mem_map); gomp_mutex_unlock (&mem_map->lock); }
void goacc_attach_host_thread_to_device (int ord) { struct goacc_thread *thr = goacc_thread (); struct gomp_device_descr *acc_dev = NULL, *base_dev = NULL; int num_devices; if (thr && thr->dev && (thr->dev->target_id == ord || ord < 0)) return; if (ord < 0) ord = goacc_device_num; /* Decide which type of device to use. If the current thread has a device type already (e.g. set by acc_set_device_type), use that, else use the global default. */ if (thr && thr->base_dev) base_dev = thr->base_dev; else { assert (cached_base_dev); base_dev = cached_base_dev; } num_devices = base_dev->get_num_devices_func (); if (num_devices <= 0 || ord >= num_devices) acc_dev_num_out_of_range (acc_device_type (base_dev->type), ord, num_devices); if (!thr) thr = goacc_new_thread (); thr->base_dev = base_dev; thr->dev = acc_dev = &base_dev[ord]; thr->saved_bound_dev = NULL; thr->mapped_data = NULL; thr->target_tls = acc_dev->openacc.create_thread_data_func (ord); acc_dev->openacc.async_set_async_func (acc_async_sync); }