@@ -396,7 +396,7 @@ static int performPointerAttachment(DeviceTy &Device, AsyncInfoTy &AsyncInfo,
396396 assert (PtrTPR.getEntry () &&
397397 " Need a valid pointer entry to perform pointer-attachment" );
398398
399- int64_t VoidPtrSize = sizeof (void *);
399+ constexpr int64_t VoidPtrSize = sizeof (void *);
400400 assert (HstPtrSize >= VoidPtrSize && " PointerSize is too small" );
401401
402402 uint64_t Delta = reinterpret_cast <uint64_t >(HstPteeBegin) -
@@ -411,23 +411,8 @@ static int performPointerAttachment(DeviceTy &Device, AsyncInfoTy &AsyncInfo,
411411 DPxPTR (TgtPteeBase), DPxPTR (TgtPteeBegin));
412412
413413 // Add shadow pointer tracking
414- // TODO: Support shadow-tracking of larger than VoidPtrSize pointers,
415- // to support restoration of Fortran descriptors. Currently, this check
416- // would return false, even if the host Fortran descriptor had been
417- // updated since its previous map, and we should have updated its
418- // device counterpart. e.g.
419- //
420- // !$omp target enter data map(x(1:100)) ! (1)
421- // p => x(10: 19)
422- // !$omp target enter data map(p, p(:)) ! (2)
423- // p => x(5: 9)
424- // !$omp target enter data map(attach(always): p(:)) ! (3)
425- //
426- // While PtrAddr(&desc_p) and PteeBase(&p(1)) are same for (2) and (3), the
427- // pointer attachment for (3) needs to update the bounds information
428- // in the descriptor of p on device.
429414 if (!PtrTPR.getEntry ()->addShadowPointer (
430- ShadowPtrInfoTy{HstPtrAddr, HstPteeBase, TgtPtrAddr, TgtPteeBase})) {
415+ ShadowPtrInfoTy{HstPtrAddr, TgtPtrAddr, TgtPteeBase, HstPtrSize })) {
431416 DP (" Pointer " DPxMOD " is already attached to " DPxMOD " \n " ,
432417 DPxPTR (TgtPtrAddr), DPxPTR (TgtPteeBase));
433418 return OFFLOAD_SUCCESS;
@@ -940,17 +925,29 @@ postProcessingTargetDataEnd(DeviceTy *Device,
940925 DelEntry = false ;
941926 }
942927
943- // If we copied back to the host a struct/array containing pointers,
944- // we need to restore the original host pointer values from their
945- // shadow copies. If the struct is going to be deallocated, remove any
946- // remaining shadow pointer entries for this struct.
928+ // If we copied back to the host a struct/array containing pointers, or
929+ // Fortran descriptors (which are larger than a "void *"), we need to
930+ // restore the original host pointer/descriptor values from their shadow
931+ // copies. If the struct is going to be deallocated, remove any remaining
932+ // shadow pointer entries for this struct.
947933 const bool HasFrom = ArgType & OMP_TGT_MAPTYPE_FROM;
948934 if (HasFrom) {
949935 Entry->foreachShadowPointerInfo ([&](const ShadowPtrInfoTy &ShadowPtr) {
950- *ShadowPtr.HstPtrAddr = ShadowPtr.HstPtrVal ;
951- DP (" Restoring original host pointer value " DPxMOD " for host "
952- " pointer " DPxMOD " \n " ,
953- DPxPTR (ShadowPtr.HstPtrVal ), DPxPTR (ShadowPtr.HstPtrAddr ));
936+ constexpr int64_t VoidPtrSize = sizeof (void *);
937+ if (ShadowPtr.PtrSize > VoidPtrSize) {
938+ DP (" Restoring host descriptor " DPxMOD
939+ " to its original content (%" PRId64
940+ " bytes), containing pointee address " DPxMOD " \n " ,
941+ DPxPTR (ShadowPtr.HstPtrAddr ), ShadowPtr.PtrSize ,
942+ DPxPTR (ShadowPtr.HstPtrContent .data ()));
943+ } else {
944+ DP (" Restoring host pointer " DPxMOD " to its original value " DPxMOD
945+ " \n " ,
946+ DPxPTR (ShadowPtr.HstPtrAddr ),
947+ DPxPTR (ShadowPtr.HstPtrContent .data ()));
948+ }
949+ std::memcpy (ShadowPtr.HstPtrAddr , ShadowPtr.HstPtrContent .data (),
950+ ShadowPtr.PtrSize );
954951 return OFFLOAD_SUCCESS;
955952 });
956953 }
@@ -1163,12 +1160,22 @@ static int targetDataContiguous(ident_t *Loc, DeviceTy &Device, void *ArgsBase,
11631160 if (TPR.getEntry ()) {
11641161 int Ret = TPR.getEntry ()->foreachShadowPointerInfo (
11651162 [&](ShadowPtrInfoTy &ShadowPtr) {
1166- DP (" Restoring original target pointer value " DPxMOD " for target "
1167- " pointer " DPxMOD " \n " ,
1168- DPxPTR (ShadowPtr.TgtPtrVal ), DPxPTR (ShadowPtr.TgtPtrAddr ));
1163+ constexpr int64_t VoidPtrSize = sizeof (void *);
1164+ if (ShadowPtr.PtrSize > VoidPtrSize) {
1165+ DP (" Restoring target descriptor " DPxMOD
1166+ " to its original content (%" PRId64
1167+ " bytes), containing pointee address " DPxMOD " \n " ,
1168+ DPxPTR (ShadowPtr.TgtPtrAddr ), ShadowPtr.PtrSize ,
1169+ DPxPTR (ShadowPtr.TgtPtrContent .data ()));
1170+ } else {
1171+ DP (" Restoring target pointer " DPxMOD
1172+ " to its original value " DPxMOD " \n " ,
1173+ DPxPTR (ShadowPtr.TgtPtrAddr ),
1174+ DPxPTR (ShadowPtr.TgtPtrContent .data ()));
1175+ }
11691176 Ret = Device.submitData (ShadowPtr.TgtPtrAddr ,
1170- ( void *)& ShadowPtr.TgtPtrVal ,
1171- sizeof ( void *) , AsyncInfo);
1177+ ShadowPtr.TgtPtrContent . data () ,
1178+ ShadowPtr. PtrSize , AsyncInfo);
11721179 if (Ret != OFFLOAD_SUCCESS) {
11731180 REPORT (" Copying data to device failed.\n " );
11741181 return OFFLOAD_FAIL;
@@ -1193,15 +1200,26 @@ static int targetDataContiguous(ident_t *Loc, DeviceTy &Device, void *ArgsBase,
11931200 }
11941201
11951202 // Wait for device-to-host memcopies for whole struct to complete,
1196- // before restoring the correct host pointer.
1203+ // before restoring the correct host pointer/descriptor .
11971204 if (auto *Entry = TPR.getEntry ()) {
11981205 AsyncInfo.addPostProcessingFunction ([=]() -> int {
11991206 int Ret = Entry->foreachShadowPointerInfo (
12001207 [&](const ShadowPtrInfoTy &ShadowPtr) {
1201- *ShadowPtr.HstPtrAddr = ShadowPtr.HstPtrVal ;
1202- DP (" Restoring original host pointer value " DPxMOD
1203- " for host pointer " DPxMOD " \n " ,
1204- DPxPTR (ShadowPtr.HstPtrVal ), DPxPTR (ShadowPtr.HstPtrAddr ));
1208+ constexpr int64_t VoidPtrSize = sizeof (void *);
1209+ if (ShadowPtr.PtrSize > VoidPtrSize) {
1210+ DP (" Restoring host descriptor " DPxMOD
1211+ " to its original content (%" PRId64
1212+ " bytes), containing pointee address " DPxMOD " \n " ,
1213+ DPxPTR (ShadowPtr.HstPtrAddr ), ShadowPtr.PtrSize ,
1214+ DPxPTR (ShadowPtr.HstPtrContent .data ()));
1215+ } else {
1216+ DP (" Restoring host pointer " DPxMOD
1217+ " to its original value " DPxMOD " \n " ,
1218+ DPxPTR (ShadowPtr.HstPtrAddr ),
1219+ DPxPTR (ShadowPtr.HstPtrContent .data ()));
1220+ }
1221+ std::memcpy (ShadowPtr.HstPtrAddr , ShadowPtr.HstPtrContent .data (),
1222+ ShadowPtr.PtrSize );
12051223 return OFFLOAD_SUCCESS;
12061224 });
12071225 Entry->unlock ();
0 commit comments