On Fri, Dec 11, 2015 at 18:27:13 +0100, Jakub Jelinek wrote:
> On Tue, Dec 08, 2015 at 05:45:59PM +0300, Ilya Verbin wrote:
> > --- a/libgomp/oacc-init.c
> > +++ b/libgomp/oacc-init.c
> > @@ -306,10 +306,11 @@ acc_shutdown_1 (acc_device_t d)
> >      {
> >        struct gomp_device_descr *acc_dev = &base_dev[i];
> >        gomp_mutex_lock (&acc_dev->lock);
> > -      if (acc_dev->is_initialized)
> > +      if (acc_dev->state == GOMP_DEVICE_INITIALIZED)
> >          {
> >       devices_active = true;
> > -     gomp_fini_device (acc_dev);
> > +     acc_dev->fini_device_func (acc_dev->target_id);
> > +     acc_dev->state = GOMP_DEVICE_UNINITIALIZED;
> >     }
> >        gomp_mutex_unlock (&acc_dev->lock);
> >      }
> 
> I'd bet you want to set state here to GOMP_DEVICE_FINALIZED too,
> but I'd leave that to the OpenACC folks to do that incrementally
> once they test it and/or decide what to do.

libgomp/testsuite/libgomp.oacc-c-c++-common/lib-5.c contains a call to acc_init,
next acc_shutdown, and acc_init again, so I guess that OpenACC allows to
initialize the device again after acc_shutdown, but GOMP_DEVICE_FINALIZED means
that it's terminally finalized.

> > @@ -356,6 +361,11 @@ gomp_map_vars (struct gomp_device_descr *devicep, 
> > size_t mapnum,
> >      }
> >  
> >    gomp_mutex_lock (&devicep->lock);
> > +  if (devicep->state == GOMP_DEVICE_FINALIZED)
> > +    {
> > +      gomp_mutex_unlock (&devicep->lock);
> 
> You need to free (tgt); here I think to avoid leaking memory.
> 
> > +      return NULL;
> > +    }
> >  
> >    for (i = 0; i < mapnum; i++)
> >      {
> > @@ -834,6 +844,11 @@ gomp_unmap_vars (struct target_mem_desc *tgt, bool 
> > do_copyfrom)
> >      }
> >  
> >    gomp_mutex_lock (&devicep->lock);
> > +  if (devicep->state == GOMP_DEVICE_FINALIZED)
> > +    {
> > +      gomp_mutex_unlock (&devicep->lock);
> > +      return;
> 
> Supposedly you want at least free (tgt->array); free (tgt); here.
> Plus the question is if the mappings shouldn't be removed from the splay tree
> before that.
> 
> > +/* This function finalizes all initialized devices.  */
> > +
> > +static void
> > +gomp_target_fini (void)
> > +{
> > +  int i;
> > +  for (i = 0; i < num_devices; i++)
> > +    {
> > +      struct gomp_device_descr *devicep = &devices[i];
> > +      gomp_mutex_lock (&devicep->lock);
> > +      if (devicep->state == GOMP_DEVICE_INITIALIZED)
> > +   {
> > +     devicep->fini_device_func (devicep->target_id);
> > +     devicep->state = GOMP_DEVICE_FINALIZED;
> > +   }
> > +      gomp_mutex_unlock (&devicep->lock);
> > +    }
> > +}
> 
> The question is what will this do if there are async target tasks still
> running on some of the devices at this point (forgotten #pragma omp taskwait
> or similar if target nowait regions are started outside of parallel region,
> or exit inside of parallel, etc.  But perhaps it can be handled incrementally.
> Also there is the question that the 
> So I think the patch is ok with the above mentioned changes.
> 
> What is the state of the link clause implementation patch?  Does it depend
> on this?

It's ready, but it depends on this.  I will retest and resend "link" patch after
checking-in "init/fini" patch.

  -- Ilya

Reply via email to