[Openmp-commits] [PATCH] D51107: [LIBOMPTARGET] Add support for mapping of lambda captures.

Alexey Bataev via Phabricator via Openmp-commits openmp-commits at lists.llvm.org
Wed Aug 22 09:02:29 PDT 2018


ABataev created this revision.
ABataev added reviewers: kkwli0, gtbercea, grokos.

Added support for correct mapping of variables captured by reference in
lambdas. That kind of mapping may appear only in target-executable
regions and must follow the original lambda or another lambda capture
for the same lambda.
The expected data: base address - the address of the lambda, begin
pointer - pointer to the address of the lambda capture, size - size of
the captured variable.
When OMP_TGT_MAPTYPE_LAMBDA_REF mapping type is seen in
target-executable region, the target address of the last processed item
is taken as the address of the original lambda `tgt_lambda_ptr`. Then,
the pointer to capture on the device is calculated like `tgt_lambda_ptr
+ (host_begin_pointer - host_begin_base)` and the target-based address
of the original variable (which host address is
`*(void**)begin_pointer`) is written to that pointer.


Repository:
  rOMP OpenMP

https://reviews.llvm.org/D51107

Files:
  libomptarget/include/omptarget.h
  libomptarget/src/omptarget.cpp


Index: libomptarget/src/omptarget.cpp
===================================================================
--- libomptarget/src/omptarget.cpp
+++ libomptarget/src/omptarget.cpp
@@ -215,8 +215,10 @@
   int rc = OFFLOAD_SUCCESS;
   for (int32_t i = 0; i < arg_num; ++i) {
     // Ignore private variables and arrays - there is no mapping for them.
+    // Also ignore implicit mappings for lambdas - only in target.
     if ((arg_types[i] & OMP_TGT_MAPTYPE_LITERAL) ||
-        (arg_types[i] & OMP_TGT_MAPTYPE_PRIVATE))
+        (arg_types[i] & OMP_TGT_MAPTYPE_PRIVATE) ||
+        (arg_types[i] & OMP_TGT_MAPTYPE_LAMBDA_REF))
       continue;
 
     void *HstPtrBegin = args[i];
@@ -341,8 +343,10 @@
   for (int32_t i = arg_num - 1; i >= 0; --i) {
     // Ignore private variables and arrays - there is no mapping for them.
     // Also, ignore the use_device_ptr directive, it has no effect here.
+    // Also ignore implicit mappings for lambdas - only in target.
     if ((arg_types[i] & OMP_TGT_MAPTYPE_LITERAL) ||
-        (arg_types[i] & OMP_TGT_MAPTYPE_PRIVATE))
+        (arg_types[i] & OMP_TGT_MAPTYPE_PRIVATE) ||
+        (arg_types[i] & OMP_TGT_MAPTYPE_LAMBDA_REF))
       continue;
 
     void *HstPtrBegin = args[i];
@@ -461,8 +465,10 @@
     void **args_base, void **args, int64_t *arg_sizes, int64_t *arg_types) {
   // process each input.
   for (int32_t i = 0; i < arg_num; ++i) {
+    // Ignore implicit mappings for lambdas - only in target.
     if ((arg_types[i] & OMP_TGT_MAPTYPE_LITERAL) ||
-        (arg_types[i] & OMP_TGT_MAPTYPE_PRIVATE))
+        (arg_types[i] & OMP_TGT_MAPTYPE_PRIVATE) ||
+        (arg_types[i] & OMP_TGT_MAPTYPE_LAMBDA_REF))
       continue;
 
     void *HstPtrBegin = args[i];
@@ -603,6 +609,35 @@
   for (int32_t i = 0; i < arg_num; ++i) {
     if (!(arg_types[i] & OMP_TGT_MAPTYPE_TARGET_PARAM)) {
       // This is not a target parameter, do not push it into tgt_args.
+      // Check for lambda mapping.
+      if (arg_types[i] & OMP_TGT_MAPTYPE_LAMBDA_REF) {
+        // The parent lambda must be processed already and it must be the last
+        // in tgt_args and tgt_offsets arrays.
+        void *HstPtrBegin = args[i];
+        void *HstPtrBase = args_base[i];
+        bool IsLast; // unused.
+        void *TgtPtrBase =
+            (void *)((intptr_t)tgt_args.back() + tgt_offsets.back());
+        DP("Parent lambda base " DPxMOD "\n", DPxPTR(TgtPtrBase));
+        uint64_t Delta = (uint64_t)HstPtrBegin - (uint64_t)HstPtrBase;
+        void *TgtPtrBegin = (void *)((uintptr_t)TgtPtrBase + Delta);
+        void *Pointer_TgtPtrBegin = Device.getTgtPtrBegin(
+            *(void **)HstPtrBegin, arg_sizes[i], IsLast, false);
+        if (!Pointer_TgtPtrBegin) {
+          DP("No lambda captured variable mapped (" DPxMOD ") - ignored\n",
+             DPxPTR(*(void **)HstPtrBegin));
+          continue;
+        }
+        DP("Update lambda reference (" DPxMOD ") -> [" DPxMOD "]\n",
+           DPxPTR(Pointer_TgtPtrBegin), DPxPTR(TgtPtrBegin));
+        int rt = Device.data_submit(TgtPtrBegin, &Pointer_TgtPtrBegin,
+                                    sizeof(void *));
+        if (rt != OFFLOAD_SUCCESS) {
+          DP("Copying data to device failed.\n");
+          rc = OFFLOAD_FAIL;
+          break;
+        }
+      }
       continue;
     }
     void *HstPtrBegin = args[i];
Index: libomptarget/include/omptarget.h
===================================================================
--- libomptarget/include/omptarget.h
+++ libomptarget/include/omptarget.h
@@ -48,6 +48,8 @@
   OMP_TGT_MAPTYPE_LITERAL         = 0x100,
   // mapping is implicit
   OMP_TGT_MAPTYPE_IMPLICIT        = 0x200,
+  // map the pointer as well as the pointee as reference
+  OMP_TGT_MAPTYPE_LAMBDA_REF     = 0x400,
   // member of struct, member given by [16 MSBs] - 1
   OMP_TGT_MAPTYPE_MEMBER_OF       = 0xffff000000000000
 };


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D51107.161976.patch
Type: text/x-patch
Size: 3881 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/openmp-commits/attachments/20180822/263d37f4/attachment.bin>


More information about the Openmp-commits mailing list