@@ -319,8 +319,8 @@ static int prepareAndSubmitData(DeviceTy &Device, void *HstPtrBegin,
319
319
void *ExpectedTgtPtrBase = (void *)((uint64_t )LocalTgtPtrBegin - Delta);
320
320
321
321
if (PointerTpr.getEntry ()->addShadowPointer (
322
- ShadowPtrInfoTy{(void **)PointerHstPtrBegin, HstPtrBase,
323
- (void **)PointerTgtPtrBegin, ExpectedTgtPtrBase})) {
322
+ ShadowPtrInfoTy{(void **)PointerHstPtrBegin,
323
+ (void **)PointerTgtPtrBegin, ExpectedTgtPtrBase, sizeof ( void *) })) {
324
324
DP (" USM_SPECIAL: Update pointer (" DPxMOD " ) -> [" DPxMOD " ]\n " ,
325
325
DPxPTR (PointerTgtPtrBegin), DPxPTR (LocalTgtPtrBegin));
326
326
@@ -407,7 +407,7 @@ static int performPointerAttachment(DeviceTy &Device, AsyncInfoTy &AsyncInfo,
407
407
assert (PtrTPR.getEntry () &&
408
408
" Need a valid pointer entry to perform pointer-attachment" );
409
409
410
- int64_t VoidPtrSize = sizeof (void *);
410
+ constexpr int64_t VoidPtrSize = sizeof (void *);
411
411
assert (HstPtrSize >= VoidPtrSize && " PointerSize is too small" );
412
412
413
413
uint64_t Delta = reinterpret_cast <uint64_t >(HstPteeBegin) -
@@ -422,23 +422,8 @@ static int performPointerAttachment(DeviceTy &Device, AsyncInfoTy &AsyncInfo,
422
422
DPxPTR (TgtPteeBase), DPxPTR (TgtPteeBegin));
423
423
424
424
// 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.
440
425
if (!PtrTPR.getEntry ()->addShadowPointer (
441
- ShadowPtrInfoTy{HstPtrAddr, HstPteeBase, TgtPtrAddr, TgtPteeBase})) {
426
+ ShadowPtrInfoTy{HstPtrAddr, TgtPtrAddr, TgtPteeBase, HstPtrSize })) {
442
427
DP (" Pointer " DPxMOD " is already attached to " DPxMOD " \n " ,
443
428
DPxPTR (TgtPtrAddr), DPxPTR (TgtPteeBase));
444
429
return OFFLOAD_SUCCESS;
@@ -969,10 +954,11 @@ postProcessingTargetDataEnd(DeviceTy *Device,
969
954
DelEntry = false ;
970
955
}
971
956
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.
976
962
const bool HasFrom = ArgType & OMP_TGT_MAPTYPE_FROM;
977
963
if (HasFrom) {
978
964
Entry->foreachShadowPointerInfo ([&](const ShadowPtrInfoTy &ShadowPtr) {
@@ -981,10 +967,21 @@ postProcessingTargetDataEnd(DeviceTy *Device,
981
967
PM->getRequirements () & OMP_REQ_UNIFIED_SHARED_MEMORY;
982
968
if (*ShadowPtr.HstPtrAddr == nullptr || isZeroCopy || isUSMMode)
983
969
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 ));
970
+ constexpr int64_t VoidPtrSize = sizeof (void *);
971
+ if (ShadowPtr.PtrSize > VoidPtrSize) {
972
+ DP (" Restoring host descriptor " DPxMOD
973
+ " to its original content (%" PRId64
974
+ " bytes), containing pointee address " DPxMOD " \n " ,
975
+ DPxPTR (ShadowPtr.HstPtrAddr ), ShadowPtr.PtrSize ,
976
+ DPxPTR (ShadowPtr.HstPtrContent .data ()));
977
+ } else {
978
+ DP (" Restoring host pointer " DPxMOD " to its original value " DPxMOD
979
+ " \n " ,
980
+ DPxPTR (ShadowPtr.HstPtrAddr ),
981
+ DPxPTR (ShadowPtr.HstPtrContent .data ()));
982
+ }
983
+ std::memcpy (ShadowPtr.HstPtrAddr , ShadowPtr.HstPtrContent .data (),
984
+ ShadowPtr.PtrSize );
988
985
return OFFLOAD_SUCCESS;
989
986
});
990
987
}
@@ -1197,12 +1194,22 @@ static int targetDataContiguous(ident_t *Loc, DeviceTy &Device, void *ArgsBase,
1197
1194
if (TPR.getEntry ()) {
1198
1195
int Ret = TPR.getEntry ()->foreachShadowPointerInfo (
1199
1196
[&](ShadowPtrInfoTy &ShadowPtr) {
1200
- DP (" Restoring original target pointer value " DPxMOD " for target "
1201
- " pointer " DPxMOD " \n " ,
1202
- DPxPTR (ShadowPtr.TgtPtrVal ), DPxPTR (ShadowPtr.TgtPtrAddr ));
1197
+ constexpr int64_t VoidPtrSize = sizeof (void *);
1198
+ if (ShadowPtr.PtrSize > VoidPtrSize) {
1199
+ DP (" Restoring target descriptor " DPxMOD
1200
+ " to its original content (%" PRId64
1201
+ " bytes), containing pointee address " DPxMOD " \n " ,
1202
+ DPxPTR (ShadowPtr.TgtPtrAddr ), ShadowPtr.PtrSize ,
1203
+ DPxPTR (ShadowPtr.TgtPtrContent .data ()));
1204
+ } else {
1205
+ DP (" Restoring target pointer " DPxMOD
1206
+ " to its original value " DPxMOD " \n " ,
1207
+ DPxPTR (ShadowPtr.TgtPtrAddr ),
1208
+ DPxPTR (ShadowPtr.TgtPtrContent .data ()));
1209
+ }
1203
1210
Ret = Device.submitData (ShadowPtr.TgtPtrAddr ,
1204
- ( void *)& ShadowPtr.TgtPtrVal ,
1205
- sizeof ( void *) , AsyncInfo);
1211
+ ShadowPtr.TgtPtrContent . data () ,
1212
+ ShadowPtr. PtrSize , AsyncInfo);
1206
1213
if (Ret != OFFLOAD_SUCCESS) {
1207
1214
REPORT (" Copying data to device failed.\n " );
1208
1215
return OFFLOAD_FAIL;
@@ -1227,7 +1234,7 @@ static int targetDataContiguous(ident_t *Loc, DeviceTy &Device, void *ArgsBase,
1227
1234
}
1228
1235
1229
1236
// Wait for device-to-host memcopies for whole struct to complete,
1230
- // before restoring the correct host pointer.
1237
+ // before restoring the correct host pointer/descriptor .
1231
1238
if (auto *Entry = TPR.getEntry ()) {
1232
1239
AsyncInfo.addPostProcessingFunction ([=]() -> int {
1233
1240
int Ret = Entry->foreachShadowPointerInfo (
@@ -1238,10 +1245,21 @@ static int targetDataContiguous(ident_t *Loc, DeviceTy &Device, void *ArgsBase,
1238
1245
PM->getRequirements () & OMP_REQ_UNIFIED_SHARED_MEMORY;
1239
1246
if (*ShadowPtr.HstPtrAddr == nullptr || isZeroCopy || isUSMMode)
1240
1247
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 ));
1248
+ constexpr int64_t VoidPtrSize = sizeof (void *);
1249
+ if (ShadowPtr.PtrSize > VoidPtrSize) {
1250
+ DP (" Restoring host descriptor " DPxMOD
1251
+ " to its original content (%" PRId64
1252
+ " bytes), containing pointee address " DPxMOD " \n " ,
1253
+ DPxPTR (ShadowPtr.HstPtrAddr ), ShadowPtr.PtrSize ,
1254
+ DPxPTR (ShadowPtr.HstPtrContent .data ()));
1255
+ } else {
1256
+ DP (" Restoring host pointer " DPxMOD
1257
+ " to its original value " DPxMOD " \n " ,
1258
+ DPxPTR (ShadowPtr.HstPtrAddr ),
1259
+ DPxPTR (ShadowPtr.HstPtrContent .data ()));
1260
+ }
1261
+ std::memcpy (ShadowPtr.HstPtrAddr , ShadowPtr.HstPtrContent .data (),
1262
+ ShadowPtr.PtrSize );
1245
1263
return OFFLOAD_SUCCESS;
1246
1264
});
1247
1265
Entry->unlock ();
0 commit comments