Files
clang-p2996/openmp/libomptarget/test/api/omp_indirect_call.c
Joseph Huber aa78e94b0b [Libomptarget] Support mapping indirect host calls to device functions
The changes in D157738 allowed for us to emit stub globals on the device
in the offloading entry section. These globals contain the addresses of
device functions and allow us to map host functions to their
corresponding device equivalent. This patch provides the initial support
required to build a table on the device to lookup the associated value.
This is done by finding these entries and creating a global table on the
device that can be searched with a simple binary search.

This requires an allocation, which supposedly should be automatically
freed at plugin shutdown. This includes a basic test which looks up device
pointers via a host pointer using the added function. This will need to be built
upon to provide full support for these calls in the runtime.

To support reverse offloading it would also be useful to provide a reverse table
that allows us to get host functions from device stubs.

Depends on D157738

Reviewed By: jdoerfert

Differential Revision: https://reviews.llvm.org/D157918
2023-08-25 18:51:56 -05:00

48 lines
1.3 KiB
C

// RUN: %libomptarget-compile-run-and-check-generic
#include <assert.h>
#include <stdio.h>
#pragma omp begin declare variant match(device = {kind(gpu)})
// Provided by the runtime.
void *__llvm_omp_indirect_call_lookup(void *host_ptr);
#pragma omp declare target to(__llvm_omp_indirect_call_lookup) \
device_type(nohost)
#pragma omp end declare variant
#pragma omp begin declare variant match(device = {kind(cpu)})
// We assume unified addressing on the CPU target.
void *__llvm_omp_indirect_call_lookup(void *host_ptr) { return host_ptr; }
#pragma omp end declare variant
#pragma omp begin declare target indirect
void foo(int *x) { *x = *x + 1; }
void bar(int *x) { *x = *x + 1; }
void baz(int *x) { *x = *x + 1; }
#pragma omp end declare target
int main() {
void *foo_ptr = foo;
void *bar_ptr = bar;
void *baz_ptr = baz;
int count = 0;
void *foo_res;
void *bar_res;
void *baz_res;
#pragma omp target map(to : foo_ptr, bar_ptr, baz_ptr) map(tofrom : count)
{
foo_res = __llvm_omp_indirect_call_lookup(foo_ptr);
((void (*)(int *))foo_res)(&count);
bar_res = __llvm_omp_indirect_call_lookup(bar_ptr);
((void (*)(int *))bar_res)(&count);
baz_res = __llvm_omp_indirect_call_lookup(baz_ptr);
((void (*)(int *))baz_res)(&count);
}
assert(count == 3 && "Calling failed");
// CHECK: PASS
printf("PASS\n");
}