Skip to content

Commit 2d739f1

Browse files
authored
[OpenMP][Offload] Automatically map indirect function pointers (#71462)
We already have all the information to automatically map function pointers that have been declared as `indirect` declare target by the user. This is just enabling and testing the functionality by looking through the one level of indirection.
1 parent 7b9d73c commit 2d739f1

File tree

2 files changed

+79
-30
lines changed

2 files changed

+79
-30
lines changed

openmp/libomptarget/src/omptarget.cpp

Lines changed: 42 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -191,38 +191,50 @@ static int initLibrary(DeviceTy &Device) {
191191
*EntryDeviceEnd = TargetTable->EntriesEnd;
192192
CurrDeviceEntry != EntryDeviceEnd;
193193
CurrDeviceEntry++, CurrHostEntry++) {
194-
if (CurrDeviceEntry->size != 0) {
195-
// has data.
196-
assert(CurrDeviceEntry->size == CurrHostEntry->size &&
197-
"data size mismatch");
198-
199-
// Fortran may use multiple weak declarations for the same symbol,
200-
// therefore we must allow for multiple weak symbols to be loaded from
201-
// the fat binary. Treat these mappings as any other "regular"
202-
// mapping. Add entry to map.
203-
if (Device.getTgtPtrBegin(HDTTMap, CurrHostEntry->addr,
204-
CurrHostEntry->size))
205-
continue;
206-
207-
DP("Add mapping from host " DPxMOD " to device " DPxMOD
208-
" with size %zu"
209-
"\n",
210-
DPxPTR(CurrHostEntry->addr), DPxPTR(CurrDeviceEntry->addr),
211-
CurrDeviceEntry->size);
212-
HDTTMap->emplace(new HostDataToTargetTy(
213-
(uintptr_t)CurrHostEntry->addr /*HstPtrBase*/,
214-
(uintptr_t)CurrHostEntry->addr /*HstPtrBegin*/,
215-
(uintptr_t)CurrHostEntry->addr +
216-
CurrHostEntry->size /*HstPtrEnd*/,
217-
(uintptr_t)CurrDeviceEntry->addr /*TgtAllocBegin*/,
218-
(uintptr_t)CurrDeviceEntry->addr /*TgtPtrBegin*/,
219-
false /*UseHoldRefCount*/, CurrHostEntry->name,
220-
true /*IsRefCountINF*/));
221-
222-
// Notify about the new mapping.
223-
if (Device.notifyDataMapped(CurrHostEntry->addr, CurrHostEntry->size))
194+
if (CurrDeviceEntry->size == 0)
195+
continue;
196+
197+
assert(CurrDeviceEntry->size == CurrHostEntry->size &&
198+
"data size mismatch");
199+
200+
// Fortran may use multiple weak declarations for the same symbol,
201+
// therefore we must allow for multiple weak symbols to be loaded from
202+
// the fat binary. Treat these mappings as any other "regular"
203+
// mapping. Add entry to map.
204+
if (Device.getTgtPtrBegin(HDTTMap, CurrHostEntry->addr,
205+
CurrHostEntry->size))
206+
continue;
207+
208+
void *CurrDeviceEntryAddr = CurrDeviceEntry->addr;
209+
210+
// For indirect mapping, follow the indirection and map the actual
211+
// target.
212+
if (CurrDeviceEntry->flags & OMP_DECLARE_TARGET_INDIRECT) {
213+
AsyncInfoTy AsyncInfo(Device);
214+
void *DevPtr;
215+
Device.retrieveData(&DevPtr, CurrDeviceEntryAddr, sizeof(void *),
216+
AsyncInfo);
217+
if (AsyncInfo.synchronize() != OFFLOAD_SUCCESS)
224218
return OFFLOAD_FAIL;
219+
CurrDeviceEntryAddr = DevPtr;
225220
}
221+
222+
DP("Add mapping from host " DPxMOD " to device " DPxMOD " with size %zu"
223+
", name \"%s\"\n",
224+
DPxPTR(CurrHostEntry->addr), DPxPTR(CurrDeviceEntry->addr),
225+
CurrDeviceEntry->size, CurrDeviceEntry->name);
226+
HDTTMap->emplace(new HostDataToTargetTy(
227+
(uintptr_t)CurrHostEntry->addr /*HstPtrBase*/,
228+
(uintptr_t)CurrHostEntry->addr /*HstPtrBegin*/,
229+
(uintptr_t)CurrHostEntry->addr + CurrHostEntry->size /*HstPtrEnd*/,
230+
(uintptr_t)CurrDeviceEntryAddr /*TgtAllocBegin*/,
231+
(uintptr_t)CurrDeviceEntryAddr /*TgtPtrBegin*/,
232+
false /*UseHoldRefCount*/, CurrHostEntry->name,
233+
true /*IsRefCountINF*/));
234+
235+
// Notify about the new mapping.
236+
if (Device.notifyDataMapped(CurrHostEntry->addr, CurrHostEntry->size))
237+
return OFFLOAD_FAIL;
226238
}
227239
}
228240
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
// RUN: %libomptarget-compile-generic -fopenmp-version=51
2+
// RUN: %libomptarget-run-generic | %fcheck-generic
3+
// RUN: %libomptarget-compileopt-generic -fopenmp-version=51
4+
// RUN: %libomptarget-run-generic | %fcheck-generic
5+
6+
#include <stdio.h>
7+
8+
int square(int x) { return x * x; }
9+
#pragma omp declare target indirect to(square)
10+
11+
typedef int (*fp_t)(int);
12+
13+
int main() {
14+
int i = 17, r;
15+
16+
fp_t fp = &square;
17+
// CHECK: host: &square =
18+
printf("host: &square = %p\n", fp);
19+
20+
#pragma omp target map(from : fp)
21+
fp = &square;
22+
// CHECK: device: &square = [[DEV_FP:.*]]
23+
printf("device: &square = %p\n", fp);
24+
25+
fp_t fp1 = square;
26+
fp_t fp2 = 0;
27+
#pragma omp target map(from : fp2)
28+
fp2 = fp1;
29+
// CHECK: device: fp2 = [[DEV_FP]]
30+
printf("device: fp2 = %p\n", fp2);
31+
32+
#pragma omp target map(from : r)
33+
{ r = fp1(i); }
34+
35+
// CHECK: 17*17 = 289
36+
printf("%i*%i = %i\n", i, i, r);
37+
}

0 commit comments

Comments
 (0)