Index: openmp/libomptarget/src/omptarget.cpp =================================================================== --- openmp/libomptarget/src/omptarget.cpp +++ openmp/libomptarget/src/omptarget.cpp @@ -665,6 +665,12 @@ int Ret; std::vector DeallocTgtPtrs; void *FromMapperBase = nullptr; + + // List of shadow pointers to be restored. The boolean associate with + // each iterator indicates whether we need to delete the iterator + // from the ShadowMapPtr map + std::vector> ShadowPtrsToRestore; + // process each input. for (int32_t I = ArgNum - 1; I >= 0; --I) { // Ignore private variables and arrays - there is no mapping for them. @@ -800,21 +806,13 @@ // shadow pointer entries for this struct. auto CB = [&](ShadowPtrListTy::iterator &Itr) { // If we copied the struct to the host, we need to restore the pointer. - if (ArgTypes[I] & OMP_TGT_MAPTYPE_FROM) { - void **ShadowHstPtrAddr = (void **)Itr->first; - *ShadowHstPtrAddr = Itr->second.HstPtrVal; - DP("Restoring original host pointer value " DPxMOD " for host " - "pointer " DPxMOD "\n", - DPxPTR(Itr->second.HstPtrVal), DPxPTR(ShadowHstPtrAddr)); - } - // If the struct is to be deallocated, remove the shadow entry. - if (DelEntry) { - DP("Removing shadow pointer " DPxMOD "\n", - DPxPTR((void **)Itr->first)); - Itr = Device.ShadowPtrMap.erase(Itr); - } else { - ++Itr; - } + // Save pointer to restore after data retrive's are completed to + // prevent rewriting of device pointer + if (ArgTypes[I] & OMP_TGT_MAPTYPE_FROM) + ShadowPtrsToRestore.emplace_back( + std::make_pair( + std::move(Itr), DelEntry ? true : false)); + ++Itr; return OFFLOAD_SUCCESS; }; applyToShadowMapEntries(Device, CB, HstPtrBegin, DataSize, TPR); @@ -833,6 +831,21 @@ if (Ret != OFFLOAD_SUCCESS) return OFFLOAD_FAIL; + // restore host pointers using saved shadow ptr iterators + for (auto it : ShadowPtrsToRestore) { + ShadowPtrListTy::iterator Itr = it.first; + void **ShadowHstPtrAddr = (void **)Itr->first; + *ShadowHstPtrAddr = Itr->second.HstPtrVal; + DP("Restoring original host pointer value " DPxMOD " for host " + "pointer " DPxMOD "\n", + DPxPTR(Itr->second.HstPtrVal), DPxPTR(ShadowHstPtrAddr)); + // DelEntry? + if (it.second) { + DP("Removing shadow pointer " DPxMOD "\n", DPxPTR((void **)Itr->first)); + Device.ShadowPtrMap.erase(Itr); + } + } + // Deallocate target pointer for (DeallocTgtPtrInfo &Info : DeallocTgtPtrs) { if (FromMapperBase && FromMapperBase == Info.HstPtrBegin) @@ -885,6 +898,12 @@ auto CB = [&](ShadowPtrListTy::iterator &Itr) { void **ShadowHstPtrAddr = (void **)Itr->first; + + // wait for device-to-host memcopies for whole struct to complete, before + // restoring the correct host pointer + if (AsyncInfo.synchronize() != OFFLOAD_SUCCESS) + return OFFLOAD_FAIL; + *ShadowHstPtrAddr = Itr->second.HstPtrVal; DP("Restoring original host pointer value " DPxMOD " for host pointer " DPxMOD "\n",