On Fri, Jul 31, 2015 at 16:08:27 +0200, Thomas Schwinge wrote: > We had established the use of a boolean flag have_offload in gcc::context > to indicate whether during compilation, we've actually seen any code to > be offloaded (see cited below the relevant parts of the patch by Ilya et > al.). This means that currently, the whole offload machinery will not be > run unless we actually have any offloaded data. This means that the > configured mkoffload programs (-foffload=[...], defaulting to > configure-time --enable-offload-targets=[...]) will not be invoked unless > we actually have any offloaded data. This means that we will not > actually generate constructor code to call libgomp's > GOMP_offload_register unless we actually have any offloaded data.
Yes, that was the plan. > runtime, in libgomp, we then cannot reliably tell which -foffload=[...] > targets have been specified during compilation. > > But: at runtime, I'd like to know which -foffload=[...] targets have been > specified during compilation, so that we can, for example, reliably > resort to host fallback execution for -foffload=disable instead of > getting error message that an offloaded function is missing. It's easy to fix: diff --git a/libgomp/target.c b/libgomp/target.c index a5fb164..f81d570 100644 --- a/libgomp/target.c +++ b/libgomp/target.c @@ -1066,9 +1066,6 @@ gomp_get_target_fn_addr (struct gomp_device_descr *devicep, k.host_end = k.host_start + 1; splay_tree_key tgt_fn = splay_tree_lookup (&devicep->mem_map, &k); gomp_mutex_unlock (&devicep->lock); - if (tgt_fn == NULL) - gomp_fatal ("Target function wasn't mapped"); - return (void *) tgt_fn->tgt_offset; } } @@ -1095,6 +1092,8 @@ GOMP_target (int device, void (*fn) (void *), const void *unused, return gomp_target_fallback (fn, hostaddrs); void *fn_addr = gomp_get_target_fn_addr (devicep, fn); + if (fn_addr == NULL) + return gomp_target_fallback (fn, hostaddrs); struct target_mem_desc *tgt_vars = gomp_map_vars (devicep, mapnum, hostaddrs, NULL, sizes, kinds, false, @@ -1155,6 +1154,8 @@ GOMP_target_41 (int device, void (*fn) (void *), size_t mapnum, } void *fn_addr = gomp_get_target_fn_addr (devicep, fn); + if (fn_addr == NULL) + return gomp_target_fallback (fn, hostaddrs); struct target_mem_desc *tgt_vars = gomp_map_vars (devicep, mapnum, hostaddrs, NULL, sizes, kinds, true, > other hand, for example, for -foffload=nvptx-none, even if user program > code doesn't contain any offloaded data (and thus the offload machinery > has not been run), the user program might still contain any executable > directives or OpenACC runtime library calls, so we'd still like to use > the libgomp nvptx plugin. However, we currently cannot detect this > situation. > > I see two ways to resolve this: a) embed the compile-time -foffload=[...] > configuration in the executable (as a string, for example) for libgomp to > look that up, or b) make it a requirement that (if configured via > -foffload=[...]), the offload machinery is run even if there is not > actually any data to be offloaded, so we then reliably get the respective > constructor call to libgomp's GOMP_offload_register. I once began to > implement a), but this to get a big ugly, so then looked into b) instead. > Compared to the status quo, always running the whole offloading machinery > for the configured -foffload=[...] targets whenever -fopenacc/-fopenmp > are active, certainly does introduce some overhead when there isn't > actually any code to be offloaded, so I'm not sure whether that is > acceptable? I vote for (a). -- Ilya