Hi Julian! On 2019-12-17T22:02:27-0800, Julian Brown <jul...@codesourcery.com> wrote: > --- a/libgomp/oacc-mem.c > +++ b/libgomp/oacc-mem.c
(Unhelpful diff trimmed.) > +/* Unmap variables for OpenACC "exit data", with optional finalization > + (affecting all mappings in this operation). */ > +static void > +goacc_exit_data_internal (struct gomp_device_descr *acc_dev, size_t mapnum, > + void **hostaddrs, size_t *sizes, > + unsigned short *kinds, bool finalize, goacc_aq aq) > +{ > + gomp_mutex_lock (&acc_dev->lock); > + for (size_t i = 0; i < mapnum; ++i) > { > + unsigned char kind = kinds[i] & 0xff; > + bool copyfrom = false; > + switch (kind) > + case GOMP_MAP_FROM: > + case GOMP_MAP_FORCE_FROM: > + case GOMP_MAP_ALWAYS_FROM: > + copyfrom = true; > + /* Fallthrough. */ What is the case that a 'GOMP_MAP_ALWAYS_FROM' would be generated for OpenACC code? Putting an 'assert' here, it never triggers, given the current set of libgomp test cases. If there is such a case, we should add a test case, otherwise, I suggest we do put an 'assert' here (whilst leaving in the supposedly correct code, if you'd like), to document that this not currently expected, and thus not tested? > + > + case GOMP_MAP_TO_PSET: > + case GOMP_MAP_POINTER: > + case GOMP_MAP_DELETE: > + case GOMP_MAP_RELEASE: > + { > + struct splay_tree_key_s cur_node; > + cur_node.host_start = (uintptr_t) hostaddrs[i]; > + cur_node.host_end = cur_node.host_start > + + (kind == GOMP_MAP_POINTER > + ? sizeof (void *) : sizes[i]); > + splay_tree_key n > + = splay_tree_lookup (&acc_dev->mem_map, &cur_node); > + > + if (n == NULL) > + continue; > + > + if (finalize) > + { > + if (n->refcount != REFCOUNT_INFINITY) > + n->refcount -= n->virtual_refcount; > + n->virtual_refcount = 0; > + } > + > + if (n->virtual_refcount > 0) > + { > + if (n->refcount != REFCOUNT_INFINITY) > + n->refcount--; > + n->virtual_refcount--; > + } > + else if (n->refcount > 0 && n->refcount != REFCOUNT_INFINITY) > + n->refcount--; > + > + if (copyfrom > + && (kind != GOMP_MAP_FROM || n->refcount == 0)) > + gomp_copy_dev2host (acc_dev, aq, (void *) cur_node.host_start, > + (void *) (n->tgt->tgt_start + n->tgt_offset > + + cur_node.host_start > + - n->host_start), > + cur_node.host_end - cur_node.host_start); That 'kind != GOMP_MAP_FROM' conditional looks wrong to me. This should instead be 'kind == GOMP_MAP_ALWAYS_FROM'? Or, get removed, together with the 'GOMP_MAP_ALWAYS_FROM' handling above? But definitely 'GOMP_MAP_FORCE_FROM' and 'GOMP_MAP_FROM' need to be handled the same, as far as I can tell? > + > + if (n->refcount == 0) > + gomp_remove_var_async (acc_dev, n, aq); > + } > + break; > + default: > + gomp_fatal (">>>> goacc_exit_data_internal UNHANDLED kind 0x%.2x", > + kind); > } > } > > gomp_mutex_unlock (&acc_dev->lock); > } Grüße Thomas ----------------- Mentor Graphics (Deutschland) GmbH, Arnulfstraße 201, 80634 München / Germany Registergericht München HRB 106955, Geschäftsführer: Thomas Heurung, Alexander Walter