Summary: The current logic tries to map target mapping tables to the current device. Right now it assumes that data is only mapped a single time per device. This is only true if we have a single instance of the runtime running on a single program. However, in the case of dynamic library loads or shared libraries, this may happen multiple times. Given a case of a simple dynamic library load which has its own target kernel instruction, the current logic had only the first call to `__tgt_target_kernel` to the data mapping for that device. Then, when the next dynamic library load got called, it would see that the global were already mapped for that device and skip registering its own entires, even though they were distinct. This resulted in none of the mappings being done and hitting an assertion. This patch simply gets rid of this per-device check. The check should instead be on the host offloading entries. We already have logic that calls `continue` if we already have entries for that pointer, so we can simply rely on that instead.
35 lines
735 B
C
35 lines
735 B
C
// RUN: %libomptarget-compile-generic -DSHARED -fPIC -shared -o %t.so && %clang %flags %s -o %t -ldl && %libomptarget-run-generic %t.so 2>&1 | %fcheck-generic
|
|
|
|
#ifdef SHARED
|
|
#include <stdio.h>
|
|
int foo() {
|
|
#pragma omp target
|
|
;
|
|
printf("%s\n", "DONE.");
|
|
return 0;
|
|
}
|
|
#else
|
|
#include <dlfcn.h>
|
|
#include <stdio.h>
|
|
int main(int argc, char **argv) {
|
|
#pragma omp target
|
|
;
|
|
|
|
void *Handle = dlopen(argv[1], RTLD_NOW);
|
|
int (*Foo)(void);
|
|
|
|
if (Handle == NULL) {
|
|
printf("dlopen() failed: %s\n", dlerror());
|
|
return 1;
|
|
}
|
|
Foo = (int (*)(void))dlsym(Handle, "foo");
|
|
if (Handle == NULL) {
|
|
printf("dlsym() failed: %s\n", dlerror());
|
|
return 1;
|
|
}
|
|
// CHECK: DONE.
|
|
// CHECK-NOT: {{abort|fault}}
|
|
return Foo();
|
|
}
|
|
#endif
|