@@ -407,7 +407,7 @@ static int performPointerAttachment(DeviceTy &Device, AsyncInfoTy &AsyncInfo,
407407 assert (PtrTPR.getEntry () &&
408408 " Need a valid pointer entry to perform pointer-attachment" );
409409
410- int64_t VoidPtrSize = sizeof (void *);
410+ constexpr int64_t VoidPtrSize = sizeof (void *);
411411 assert (HstPtrSize >= VoidPtrSize && " PointerSize is too small" );
412412
413413 uint64_t Delta = reinterpret_cast <uint64_t >(HstPteeBegin) -
@@ -422,23 +422,8 @@ static int performPointerAttachment(DeviceTy &Device, AsyncInfoTy &AsyncInfo,
422422 DPxPTR (TgtPteeBase), DPxPTR (TgtPteeBegin));
423423
424424 // Add shadow pointer tracking
425- // TODO: Support shadow-tracking of larger than VoidPtrSize pointers,
426- // to support restoration of Fortran descriptors. Currently, this check
427- // would return false, even if the host Fortran descriptor had been
428- // updated since its previous map, and we should have updated its
429- // device counterpart. e.g.
430- //
431- // !$omp target enter data map(x(1:100)) ! (1)
432- // p => x(10: 19)
433- // !$omp target enter data map(p, p(:)) ! (2)
434- // p => x(5: 9)
435- // !$omp target enter data map(attach(always): p(:)) ! (3)
436- //
437- // While PtrAddr(&desc_p) and PteeBase(&p(1)) are same for (2) and (3), the
438- // pointer attachment for (3) needs to update the bounds information
439- // in the descriptor of p on device.
440425 if (!PtrTPR.getEntry ()->addShadowPointer (
441- ShadowPtrInfoTy{HstPtrAddr, HstPteeBase, TgtPtrAddr, TgtPteeBase})) {
426+ ShadowPtrInfoTy{HstPtrAddr, TgtPtrAddr, TgtPteeBase, HstPtrSize })) {
442427 DP (" Pointer " DPxMOD " is already attached to " DPxMOD " \n " ,
443428 DPxPTR (TgtPtrAddr), DPxPTR (TgtPteeBase));
444429 return OFFLOAD_SUCCESS;
@@ -969,22 +954,29 @@ postProcessingTargetDataEnd(DeviceTy *Device,
969954 DelEntry = false ;
970955 }
971956
972- // If we copied back to the host a struct/array containing pointers,
973- // we need to restore the original host pointer values from their
974- // shadow copies. If the struct is going to be deallocated, remove any
975- // remaining shadow pointer entries for this struct.
957+ // If we copied back to the host a struct/array containing pointers, or
958+ // Fortran descriptors (which are larger than a "void *"), we need to
959+ // restore the original host pointer/descriptor values from their shadow
960+ // copies. If the struct is going to be deallocated, remove any remaining
961+ // shadow pointer entries for this struct.
976962 const bool HasFrom = ArgType & OMP_TGT_MAPTYPE_FROM;
977963 if (HasFrom) {
978964 Entry->foreachShadowPointerInfo ([&](const ShadowPtrInfoTy &ShadowPtr) {
979- const bool isZeroCopy = PM->getRequirements () & OMPX_REQ_AUTO_ZERO_COPY;
980- const bool isUSMMode =
981- PM->getRequirements () & OMP_REQ_UNIFIED_SHARED_MEMORY;
982- if (*ShadowPtr.HstPtrAddr == nullptr || isZeroCopy || isUSMMode)
983- return OFFLOAD_SUCCESS;
984- *ShadowPtr.HstPtrAddr = ShadowPtr.HstPtrVal ;
985- DP (" Restoring original host pointer value " DPxMOD " for host "
986- " pointer " DPxMOD " \n " ,
987- DPxPTR (ShadowPtr.HstPtrVal ), DPxPTR (ShadowPtr.HstPtrAddr ));
965+ constexpr int64_t VoidPtrSize = sizeof (void *);
966+ if (ShadowPtr.PtrSize > VoidPtrSize) {
967+ DP (" Restoring host descriptor " DPxMOD
968+ " to its original content (%" PRId64
969+ " bytes), containing pointee address " DPxMOD " \n " ,
970+ DPxPTR (ShadowPtr.HstPtrAddr ), ShadowPtr.PtrSize ,
971+ DPxPTR (ShadowPtr.HstPtrContent .data ()));
972+ } else {
973+ DP (" Restoring host pointer " DPxMOD " to its original value " DPxMOD
974+ " \n " ,
975+ DPxPTR (ShadowPtr.HstPtrAddr ),
976+ DPxPTR (ShadowPtr.HstPtrContent .data ()));
977+ }
978+ std::memcpy (ShadowPtr.HstPtrAddr , ShadowPtr.HstPtrContent .data (),
979+ ShadowPtr.PtrSize );
988980 return OFFLOAD_SUCCESS;
989981 });
990982 }
@@ -1197,12 +1189,22 @@ static int targetDataContiguous(ident_t *Loc, DeviceTy &Device, void *ArgsBase,
11971189 if (TPR.getEntry ()) {
11981190 int Ret = TPR.getEntry ()->foreachShadowPointerInfo (
11991191 [&](ShadowPtrInfoTy &ShadowPtr) {
1200- DP (" Restoring original target pointer value " DPxMOD " for target "
1201- " pointer " DPxMOD " \n " ,
1202- DPxPTR (ShadowPtr.TgtPtrVal ), DPxPTR (ShadowPtr.TgtPtrAddr ));
1192+ constexpr int64_t VoidPtrSize = sizeof (void *);
1193+ if (ShadowPtr.PtrSize > VoidPtrSize) {
1194+ DP (" Restoring target descriptor " DPxMOD
1195+ " to its original content (%" PRId64
1196+ " bytes), containing pointee address " DPxMOD " \n " ,
1197+ DPxPTR (ShadowPtr.TgtPtrAddr ), ShadowPtr.PtrSize ,
1198+ DPxPTR (ShadowPtr.TgtPtrContent .data ()));
1199+ } else {
1200+ DP (" Restoring target pointer " DPxMOD
1201+ " to its original value " DPxMOD " \n " ,
1202+ DPxPTR (ShadowPtr.TgtPtrAddr ),
1203+ DPxPTR (ShadowPtr.TgtPtrContent .data ()));
1204+ }
12031205 Ret = Device.submitData (ShadowPtr.TgtPtrAddr ,
1204- ( void *)& ShadowPtr.TgtPtrVal ,
1205- sizeof ( void *) , AsyncInfo);
1206+ ShadowPtr.TgtPtrContent . data () ,
1207+ ShadowPtr. PtrSize , AsyncInfo);
12061208 if (Ret != OFFLOAD_SUCCESS) {
12071209 REPORT (" Copying data to device failed.\n " );
12081210 return OFFLOAD_FAIL;
@@ -1227,21 +1229,26 @@ static int targetDataContiguous(ident_t *Loc, DeviceTy &Device, void *ArgsBase,
12271229 }
12281230
12291231 // Wait for device-to-host memcopies for whole struct to complete,
1230- // before restoring the correct host pointer.
1232+ // before restoring the correct host pointer/descriptor .
12311233 if (auto *Entry = TPR.getEntry ()) {
12321234 AsyncInfo.addPostProcessingFunction ([=]() -> int {
12331235 int Ret = Entry->foreachShadowPointerInfo (
12341236 [&](const ShadowPtrInfoTy &ShadowPtr) {
1235- const bool isZeroCopy =
1236- PM->getRequirements () & OMPX_REQ_AUTO_ZERO_COPY;
1237- const bool isUSMMode =
1238- PM->getRequirements () & OMP_REQ_UNIFIED_SHARED_MEMORY;
1239- if (*ShadowPtr.HstPtrAddr == nullptr || isZeroCopy || isUSMMode)
1240- return OFFLOAD_SUCCESS;
1241- *ShadowPtr.HstPtrAddr = ShadowPtr.HstPtrVal ;
1242- DP (" Restoring original host pointer value " DPxMOD
1243- " for host pointer " DPxMOD " \n " ,
1244- DPxPTR (ShadowPtr.HstPtrVal ), DPxPTR (ShadowPtr.HstPtrAddr ));
1237+ constexpr int64_t VoidPtrSize = sizeof (void *);
1238+ if (ShadowPtr.PtrSize > VoidPtrSize) {
1239+ DP (" Restoring host descriptor " DPxMOD
1240+ " to its original content (%" PRId64
1241+ " bytes), containing pointee address " DPxMOD " \n " ,
1242+ DPxPTR (ShadowPtr.HstPtrAddr ), ShadowPtr.PtrSize ,
1243+ DPxPTR (ShadowPtr.HstPtrContent .data ()));
1244+ } else {
1245+ DP (" Restoring host pointer " DPxMOD
1246+ " to its original value " DPxMOD " \n " ,
1247+ DPxPTR (ShadowPtr.HstPtrAddr ),
1248+ DPxPTR (ShadowPtr.HstPtrContent .data ()));
1249+ }
1250+ std::memcpy (ShadowPtr.HstPtrAddr , ShadowPtr.HstPtrContent .data (),
1251+ ShadowPtr.PtrSize );
12451252 return OFFLOAD_SUCCESS;
12461253 });
12471254 Entry->unlock ();
0 commit comments