@@ -396,7 +396,7 @@ static int performPointerAttachment(DeviceTy &Device, AsyncInfoTy &AsyncInfo,
396
396
assert (PtrTPR.getEntry () &&
397
397
" Need a valid pointer entry to perform pointer-attachment" );
398
398
399
- int64_t VoidPtrSize = sizeof (void *);
399
+ constexpr int64_t VoidPtrSize = sizeof (void *);
400
400
assert (HstPtrSize >= VoidPtrSize && " PointerSize is too small" );
401
401
402
402
uint64_t Delta = reinterpret_cast <uint64_t >(HstPteeBegin) -
@@ -411,23 +411,8 @@ static int performPointerAttachment(DeviceTy &Device, AsyncInfoTy &AsyncInfo,
411
411
DPxPTR (TgtPteeBase), DPxPTR (TgtPteeBegin));
412
412
413
413
// 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.
429
414
if (!PtrTPR.getEntry ()->addShadowPointer (
430
- ShadowPtrInfoTy{HstPtrAddr, HstPteeBase, TgtPtrAddr, TgtPteeBase})) {
415
+ ShadowPtrInfoTy{HstPtrAddr, TgtPtrAddr, TgtPteeBase, HstPtrSize })) {
431
416
DP (" Pointer " DPxMOD " is already attached to " DPxMOD " \n " ,
432
417
DPxPTR (TgtPtrAddr), DPxPTR (TgtPteeBase));
433
418
return OFFLOAD_SUCCESS;
@@ -940,17 +925,29 @@ postProcessingTargetDataEnd(DeviceTy *Device,
940
925
DelEntry = false ;
941
926
}
942
927
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.
947
933
const bool HasFrom = ArgType & OMP_TGT_MAPTYPE_FROM;
948
934
if (HasFrom) {
949
935
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 );
954
951
return OFFLOAD_SUCCESS;
955
952
});
956
953
}
@@ -1163,12 +1160,22 @@ static int targetDataContiguous(ident_t *Loc, DeviceTy &Device, void *ArgsBase,
1163
1160
if (TPR.getEntry ()) {
1164
1161
int Ret = TPR.getEntry ()->foreachShadowPointerInfo (
1165
1162
[&](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
+ }
1169
1176
Ret = Device.submitData (ShadowPtr.TgtPtrAddr ,
1170
- ( void *)& ShadowPtr.TgtPtrVal ,
1171
- sizeof ( void *) , AsyncInfo);
1177
+ ShadowPtr.TgtPtrContent . data () ,
1178
+ ShadowPtr. PtrSize , AsyncInfo);
1172
1179
if (Ret != OFFLOAD_SUCCESS) {
1173
1180
REPORT (" Copying data to device failed.\n " );
1174
1181
return OFFLOAD_FAIL;
@@ -1193,15 +1200,26 @@ static int targetDataContiguous(ident_t *Loc, DeviceTy &Device, void *ArgsBase,
1193
1200
}
1194
1201
1195
1202
// 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 .
1197
1204
if (auto *Entry = TPR.getEntry ()) {
1198
1205
AsyncInfo.addPostProcessingFunction ([=]() -> int {
1199
1206
int Ret = Entry->foreachShadowPointerInfo (
1200
1207
[&](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 );
1205
1223
return OFFLOAD_SUCCESS;
1206
1224
});
1207
1225
Entry->unlock ();
0 commit comments