#ifndef _OMPTARGET_H_
#define _OMPTARGET_H_
+#include <deque>
#include <stddef.h>
#include <stdint.h>
/// associated with a libomptarget layer device. RAII semantics to avoid
/// mistakes.
class AsyncInfoTy {
+ /// Locations we used in (potentially) asynchronous calls which should live
+ /// as long as this AsyncInfoTy object.
+ std::deque<void *> BufferLocations;
+
__tgt_async_info AsyncInfo;
DeviceTy &Device;
///
/// \returns OFFLOAD_FAIL or OFFLOAD_SUCCESS appropriately.
int synchronize();
+
+ /// Return a void* reference with a lifetime that is at least as long as this
+ /// AsyncInfoTy object. The location can be used as intermediate buffer.
+ void *&getVoidPtrLocation();
};
/// This struct is a record of non-contiguous information
return Result;
}
+void *&AsyncInfoTy::getVoidPtrLocation() {
+ BufferLocations.push_back(nullptr);
+ return BufferLocations.back();
+}
+
/* All begin addresses for partially mapped structs must be 8-aligned in order
* to ensure proper alignment of members. E.g.
*
DP("Update pointer (" DPxMOD ") -> [" DPxMOD "]\n",
DPxPTR(PointerTgtPtrBegin), DPxPTR(TgtPtrBegin));
uint64_t Delta = (uint64_t)HstPtrBegin - (uint64_t)HstPtrBase;
- void *TgtPtrBase = (void *)((uint64_t)TgtPtrBegin - Delta);
+ void *&TgtPtrBase = AsyncInfo.getVoidPtrLocation();
+ TgtPtrBase = (void *)((uint64_t)TgtPtrBegin - Delta);
int rt = Device.submitData(PointerTgtPtrBegin, &TgtPtrBase,
sizeof(void *), AsyncInfo);
if (rt != OFFLOAD_SUCCESS) {
DP("Parent lambda base " DPxMOD "\n", DPxPTR(TgtPtrBase));
uint64_t Delta = (uint64_t)HstPtrBegin - (uint64_t)HstPtrBase;
void *TgtPtrBegin = (void *)((uintptr_t)TgtPtrBase + Delta);
- void *PointerTgtPtrBegin = Device.getTgtPtrBegin(
- HstPtrVal, ArgSizes[I], IsLast, false, IsHostPtr);
+ void *&PointerTgtPtrBegin = AsyncInfo.getVoidPtrLocation();
+ PointerTgtPtrBegin = Device.getTgtPtrBegin(HstPtrVal, ArgSizes[I],
+ IsLast, false, IsHostPtr);
if (!PointerTgtPtrBegin) {
DP("No lambda captured variable mapped (" DPxMOD ") - ignored\n",
DPxPTR(HstPtrVal));