[Openmp-commits] [openmp] bb0166d - [libomptarget] Update device pointer only if needed
George Rokos via Openmp-commits
openmp-commits at lists.llvm.org
Tue Jul 13 04:23:29 PDT 2021
Author: George Rokos
Date: 2021-07-13T04:18:55-07:00
New Revision: bb0166dc72791e2cefdb0c8dc9e495ea0555357b
URL: https://github.com/llvm/llvm-project/commit/bb0166dc72791e2cefdb0c8dc9e495ea0555357b
DIFF: https://github.com/llvm/llvm-project/commit/bb0166dc72791e2cefdb0c8dc9e495ea0555357b.diff
LOG: [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.
Added:
openmp/libomptarget/test/mapping/device_ptr_update.c
Modified:
openmp/libomptarget/src/omptarget.cpp
Removed:
################################################################################
diff --git a/openmp/libomptarget/src/omptarget.cpp b/openmp/libomptarget/src/omptarget.cpp
index 80cb9381ffbb5..0255f94599ee1 100644
--- a/openmp/libomptarget/src/omptarget.cpp
+++ b/openmp/libomptarget/src/omptarget.cpp
@@ -556,22 +556,35 @@ int targetDataBegin(ident_t *loc, DeviceTy &Device, int32_t arg_num,
}
if (arg_types[i] & OMP_TGT_MAPTYPE_PTR_AND_OBJ && !IsHostPtr) {
- DP("Update pointer (" DPxMOD ") -> [" DPxMOD "]\n",
- DPxPTR(PointerTgtPtrBegin), DPxPTR(TgtPtrBegin));
+ // Check whether we need to update the pointer on the device
+ bool UpdateDevPtr = false;
+
uint64_t Delta = (uint64_t)HstPtrBegin - (uint64_t)HstPtrBase;
- void *&TgtPtrBase = AsyncInfo.getVoidPtrLocation();
- TgtPtrBase = (void *)((uint64_t)TgtPtrBegin - Delta);
- int rt = Device.submitData(PointerTgtPtrBegin, &TgtPtrBase,
- sizeof(void *), AsyncInfo);
- if (rt != OFFLOAD_SUCCESS) {
- REPORT("Copying data to device failed.\n");
- return OFFLOAD_FAIL;
- }
- // create shadow pointers for this entry
+ void *ExpectedTgtPtrBase = (void *)((uint64_t)TgtPtrBegin - Delta);
+
Device.ShadowMtx.lock();
- Device.ShadowPtrMap[Pointer_HstPtrBegin] = {
- HstPtrBase, PointerTgtPtrBegin, TgtPtrBase};
+ auto Entry = Device.ShadowPtrMap.find(Pointer_HstPtrBegin);
+ // If this pointer is not in the map we need to insert it.
+ if (Entry == Device.ShadowPtrMap.end()) {
+ // create shadow pointers for this entry
+ Device.ShadowPtrMap[Pointer_HstPtrBegin] = {
+ HstPtrBase, PointerTgtPtrBegin, ExpectedTgtPtrBase};
+ UpdateDevPtr = true;
+ }
Device.ShadowMtx.unlock();
+
+ if (UpdateDevPtr) {
+ DP("Update pointer (" DPxMOD ") -> [" DPxMOD "]\n",
+ DPxPTR(PointerTgtPtrBegin), DPxPTR(TgtPtrBegin));
+ void *&TgtPtrBase = AsyncInfo.getVoidPtrLocation();
+ TgtPtrBase = ExpectedTgtPtrBase;
+ int rt = Device.submitData(PointerTgtPtrBegin, &TgtPtrBase,
+ sizeof(void *), AsyncInfo);
+ if (rt != OFFLOAD_SUCCESS) {
+ REPORT("Copying data to device failed.\n");
+ return OFFLOAD_FAIL;
+ }
+ }
}
}
diff --git a/openmp/libomptarget/test/mapping/device_ptr_update.c b/openmp/libomptarget/test/mapping/device_ptr_update.c
new file mode 100644
index 0000000000000..e3dd12f3d4340
--- /dev/null
+++ b/openmp/libomptarget/test/mapping/device_ptr_update.c
@@ -0,0 +1,44 @@
+// RUN: %libomptarget-compile-generic
+// RUN: env LIBOMPTARGET_DEBUG=1 %libomptarget-run-generic 2>&1 \
+// RUN: | %fcheck-generic -check-prefix=DEBUG -check-prefix=CHECK
+// REQUIRES: libomptarget-debug
+
+#include <stdio.h>
+
+struct S {
+ int *p;
+};
+
+int main(void) {
+ int A[10];
+ struct S s1;
+
+ s1.p = A;
+
+ // DEBUG: Update pointer ([[DEV_PTR:0x[^ ]+]]) -> {{\[}}[[DEV_OBJ_A:0x[^ ]+]]{{\]}}
+ #pragma omp target enter data map(alloc : s1.p [0:10])
+
+ // DEBUG-NOT: Update pointer ([[DEV_PTR]]) -> {{\[}}[[DEV_OBJ_A]]{{\]}}
+ #pragma omp target map(alloc : s1.p [0:10])
+ {
+ for (int i = 0; i < 10; ++i)
+ s1.p[i] = i;
+ }
+
+ #pragma omp target exit data map(from : s1.p [0:10])
+
+ int fail_A = 0;
+ for (int i = 0; i < 10; ++i) {
+ if (A[i] != i) {
+ fail_A = 1;
+ break;
+ }
+ }
+
+ // CHECK-NOT: Test A failed
+ if (fail_A) {
+ printf("Test A failed\n");
+ }
+
+ return fail_A;
+}
More information about the Openmp-commits
mailing list