Skip to content

Commit 0b45ba3

Browse files
George Rokosmemfrob
authored andcommitted
[libomptarget] Update device pointer only if needed
Currently, libomptarget will always perform a host-to-device memory transfer in order to update the device pointer of a PTR_AND_OBJ entry. This is not always necessary because the device pointer may have been set to the correct pointee address already, so we can eliminate the redundant memory transfer.
1 parent bea4e92 commit 0b45ba3

File tree

2 files changed

+70
-13
lines changed

2 files changed

+70
-13
lines changed

openmp/libomptarget/src/omptarget.cpp

Lines changed: 26 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -556,22 +556,35 @@ int targetDataBegin(ident_t *loc, DeviceTy &Device, int32_t arg_num,
556556
}
557557

558558
if (arg_types[i] & OMP_TGT_MAPTYPE_PTR_AND_OBJ && !IsHostPtr) {
559-
DP("Update pointer (" DPxMOD ") -> [" DPxMOD "]\n",
560-
DPxPTR(PointerTgtPtrBegin), DPxPTR(TgtPtrBegin));
559+
// Check whether we need to update the pointer on the device
560+
bool UpdateDevPtr = false;
561+
561562
uint64_t Delta = (uint64_t)HstPtrBegin - (uint64_t)HstPtrBase;
562-
void *&TgtPtrBase = AsyncInfo.getVoidPtrLocation();
563-
TgtPtrBase = (void *)((uint64_t)TgtPtrBegin - Delta);
564-
int rt = Device.submitData(PointerTgtPtrBegin, &TgtPtrBase,
565-
sizeof(void *), AsyncInfo);
566-
if (rt != OFFLOAD_SUCCESS) {
567-
REPORT("Copying data to device failed.\n");
568-
return OFFLOAD_FAIL;
569-
}
570-
// create shadow pointers for this entry
563+
void *ExpectedTgtPtrBase = (void *)((uint64_t)TgtPtrBegin - Delta);
564+
571565
Device.ShadowMtx.lock();
572-
Device.ShadowPtrMap[Pointer_HstPtrBegin] = {
573-
HstPtrBase, PointerTgtPtrBegin, TgtPtrBase};
566+
auto Entry = Device.ShadowPtrMap.find(Pointer_HstPtrBegin);
567+
// If this pointer is not in the map we need to insert it.
568+
if (Entry == Device.ShadowPtrMap.end()) {
569+
// create shadow pointers for this entry
570+
Device.ShadowPtrMap[Pointer_HstPtrBegin] = {
571+
HstPtrBase, PointerTgtPtrBegin, ExpectedTgtPtrBase};
572+
UpdateDevPtr = true;
573+
}
574574
Device.ShadowMtx.unlock();
575+
576+
if (UpdateDevPtr) {
577+
DP("Update pointer (" DPxMOD ") -> [" DPxMOD "]\n",
578+
DPxPTR(PointerTgtPtrBegin), DPxPTR(TgtPtrBegin));
579+
void *&TgtPtrBase = AsyncInfo.getVoidPtrLocation();
580+
TgtPtrBase = ExpectedTgtPtrBase;
581+
int rt = Device.submitData(PointerTgtPtrBegin, &TgtPtrBase,
582+
sizeof(void *), AsyncInfo);
583+
if (rt != OFFLOAD_SUCCESS) {
584+
REPORT("Copying data to device failed.\n");
585+
return OFFLOAD_FAIL;
586+
}
587+
}
575588
}
576589
}
577590

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
// RUN: %libomptarget-compile-generic
2+
// RUN: env LIBOMPTARGET_DEBUG=1 %libomptarget-run-generic 2>&1 \
3+
// RUN: | %fcheck-generic -check-prefix=DEBUG -check-prefix=CHECK
4+
// REQUIRES: libomptarget-debug
5+
6+
#include <stdio.h>
7+
8+
struct S {
9+
int *p;
10+
};
11+
12+
int main(void) {
13+
int A[10];
14+
struct S s1;
15+
16+
s1.p = A;
17+
18+
// DEBUG: Update pointer ([[DEV_PTR:0x[^ ]+]]) -> {{\[}}[[DEV_OBJ_A:0x[^ ]+]]{{\]}}
19+
#pragma omp target enter data map(alloc : s1.p [0:10])
20+
21+
// DEBUG-NOT: Update pointer ([[DEV_PTR]]) -> {{\[}}[[DEV_OBJ_A]]{{\]}}
22+
#pragma omp target map(alloc : s1.p [0:10])
23+
{
24+
for (int i = 0; i < 10; ++i)
25+
s1.p[i] = i;
26+
}
27+
28+
#pragma omp target exit data map(from : s1.p [0:10])
29+
30+
int fail_A = 0;
31+
for (int i = 0; i < 10; ++i) {
32+
if (A[i] != i) {
33+
fail_A = 1;
34+
break;
35+
}
36+
}
37+
38+
// CHECK-NOT: Test A failed
39+
if (fail_A) {
40+
printf("Test A failed\n");
41+
}
42+
43+
return fail_A;
44+
}

0 commit comments

Comments
 (0)