diff options
| author | Mingming Liu <mingmingl@google.com> | 2025-09-10 15:25:31 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-09-10 15:25:31 -0700 |
| commit | 1417dafa1db9cb1b2b09438aa9f53ea5ab6e36e2 (patch) | |
| tree | 57f4b1f313c8cf74eed8819870f39c36ea263c68 /offload/libomptarget | |
| parent | 898b813bc8a6d0276bf0f4769f5f2f64b34e632d (diff) | |
| parent | b8cefcb601ddaa18482555c4ff363c01a270c2fe (diff) | |
Merge branch 'main' into users/mingmingl-llvm/samplefdo-profile-formatusers/mingmingl-llvm/samplefdo-profile-format
Diffstat (limited to 'offload/libomptarget')
| -rw-r--r-- | offload/libomptarget/device.cpp | 84 | ||||
| -rw-r--r-- | offload/libomptarget/omptarget.cpp | 6 | ||||
| -rw-r--r-- | offload/libomptarget/private.h | 9 |
3 files changed, 97 insertions, 2 deletions
diff --git a/offload/libomptarget/device.cpp b/offload/libomptarget/device.cpp index 6585286bf428..71423ae0c94d 100644 --- a/offload/libomptarget/device.cpp +++ b/offload/libomptarget/device.cpp @@ -37,6 +37,8 @@ using namespace llvm::omp::target::ompt; #endif +using namespace llvm::omp::target::plugin; + int HostDataToTargetTy::addEventIfNecessary(DeviceTy &Device, AsyncInfoTy &AsyncInfo) const { // First, check if the user disabled atomic map transfer/malloc/dealloc. @@ -97,7 +99,55 @@ llvm::Error DeviceTy::init() { return llvm::Error::success(); } -// Load binary to device. +// Extract the mapping of host function pointers to device function pointers +// from the entry table. Functions marked as 'indirect' in OpenMP will have +// offloading entries generated for them which map the host's function pointer +// to a global containing the corresponding function pointer on the device. +static llvm::Expected<std::pair<void *, uint64_t>> +setupIndirectCallTable(DeviceTy &Device, __tgt_device_image *Image, + __tgt_device_binary Binary) { + AsyncInfoTy AsyncInfo(Device); + llvm::ArrayRef<llvm::offloading::EntryTy> Entries(Image->EntriesBegin, + Image->EntriesEnd); + llvm::SmallVector<std::pair<void *, void *>> IndirectCallTable; + for (const auto &Entry : Entries) { + if (Entry.Kind != llvm::object::OffloadKind::OFK_OpenMP || + Entry.Size == 0 || !(Entry.Flags & OMP_DECLARE_TARGET_INDIRECT)) + continue; + + assert(Entry.Size == sizeof(void *) && "Global not a function pointer?"); + auto &[HstPtr, DevPtr] = IndirectCallTable.emplace_back(); + + void *Ptr; + if (Device.RTL->get_global(Binary, Entry.Size, Entry.SymbolName, &Ptr)) + return error::createOffloadError(error::ErrorCode::INVALID_BINARY, + "failed to load %s", Entry.SymbolName); + + HstPtr = Entry.Address; + if (Device.retrieveData(&DevPtr, Ptr, Entry.Size, AsyncInfo)) + return error::createOffloadError(error::ErrorCode::INVALID_BINARY, + "failed to load %s", Entry.SymbolName); + } + + // If we do not have any indirect globals we exit early. + if (IndirectCallTable.empty()) + return std::pair{nullptr, 0}; + + // Sort the array to allow for more efficient lookup of device pointers. + llvm::sort(IndirectCallTable, + [](const auto &x, const auto &y) { return x.first < y.first; }); + + uint64_t TableSize = + IndirectCallTable.size() * sizeof(std::pair<void *, void *>); + void *DevicePtr = Device.allocData(TableSize, nullptr, TARGET_ALLOC_DEVICE); + if (Device.submitData(DevicePtr, IndirectCallTable.data(), TableSize, + AsyncInfo)) + return error::createOffloadError(error::ErrorCode::INVALID_BINARY, + "failed to copy data"); + return std::pair<void *, uint64_t>(DevicePtr, IndirectCallTable.size()); +} + +// Load binary to device and perform global initialization if needed. llvm::Expected<__tgt_device_binary> DeviceTy::loadBinary(__tgt_device_image *Img) { __tgt_device_binary Binary; @@ -105,6 +155,38 @@ DeviceTy::loadBinary(__tgt_device_image *Img) { if (RTL->load_binary(RTLDeviceID, Img, &Binary) != OFFLOAD_SUCCESS) return error::createOffloadError(error::ErrorCode::INVALID_BINARY, "failed to load binary %p", Img); + + // This symbol is optional. + void *DeviceEnvironmentPtr; + if (RTL->get_global(Binary, sizeof(DeviceEnvironmentTy), + "__omp_rtl_device_environment", &DeviceEnvironmentPtr)) + return Binary; + + // Obtain a table mapping host function pointers to device function pointers. + auto CallTablePairOrErr = setupIndirectCallTable(*this, Img, Binary); + if (!CallTablePairOrErr) + return CallTablePairOrErr.takeError(); + + GenericDeviceTy &GenericDevice = RTL->getDevice(RTLDeviceID); + DeviceEnvironmentTy DeviceEnvironment; + DeviceEnvironment.DeviceDebugKind = GenericDevice.getDebugKind(); + DeviceEnvironment.NumDevices = RTL->getNumDevices(); + // TODO: The device ID used here is not the real device ID used by OpenMP. + DeviceEnvironment.DeviceNum = RTLDeviceID; + DeviceEnvironment.DynamicMemSize = GenericDevice.getDynamicMemorySize(); + DeviceEnvironment.ClockFrequency = GenericDevice.getClockFrequency(); + DeviceEnvironment.IndirectCallTable = + reinterpret_cast<uintptr_t>(CallTablePairOrErr->first); + DeviceEnvironment.IndirectCallTableSize = CallTablePairOrErr->second; + DeviceEnvironment.HardwareParallelism = + GenericDevice.getHardwareParallelism(); + + AsyncInfoTy AsyncInfo(*this); + if (submitData(DeviceEnvironmentPtr, &DeviceEnvironment, + sizeof(DeviceEnvironment), AsyncInfo)) + return error::createOffloadError(error::ErrorCode::INVALID_BINARY, + "failed to copy data"); + return Binary; } diff --git a/offload/libomptarget/omptarget.cpp b/offload/libomptarget/omptarget.cpp index 32e89cc75efc..4c8eba1e7180 100644 --- a/offload/libomptarget/omptarget.cpp +++ b/offload/libomptarget/omptarget.cpp @@ -403,6 +403,12 @@ static int performPointerAttachment(DeviceTy &Device, AsyncInfoTy &AsyncInfo, reinterpret_cast<uint64_t>(HstPteeBase); void *TgtPteeBase = reinterpret_cast<void *>( reinterpret_cast<uint64_t>(TgtPteeBegin) - Delta); + DP("HstPteeBase: " DPxMOD ", HstPteeBegin: " DPxMOD + ", Delta (HstPteeBegin - HstPteeBase): %" PRIu64 ".\n", + DPxPTR(HstPteeBase), DPxPTR(HstPteeBegin), Delta); + DP("TgtPteeBase (TgtPteeBegin - Delta): " DPxMOD ", TgtPteeBegin : " DPxMOD + "\n", + DPxPTR(TgtPteeBase), DPxPTR(TgtPteeBegin)); // Add shadow pointer tracking // TODO: Support shadow-tracking of larger than VoidPtrSize pointers, diff --git a/offload/libomptarget/private.h b/offload/libomptarget/private.h index 0b3d54599048..90e5e1780e66 100644 --- a/offload/libomptarget/private.h +++ b/offload/libomptarget/private.h @@ -55,7 +55,14 @@ printKernelArguments(const ident_t *Loc, const int64_t DeviceId, const char *Type = nullptr; const char *Implicit = (ArgTypes[I] & OMP_TGT_MAPTYPE_IMPLICIT) ? "(implicit)" : ""; - if (ArgTypes[I] & OMP_TGT_MAPTYPE_TO && ArgTypes[I] & OMP_TGT_MAPTYPE_FROM) + + if (ArgTypes[I] & OMP_TGT_MAPTYPE_ATTACH && + ArgTypes[I] & OMP_TGT_MAPTYPE_ALWAYS) + Type = "attach:always"; + else if (ArgTypes[I] & OMP_TGT_MAPTYPE_ATTACH) + Type = "attach"; + else if (ArgTypes[I] & OMP_TGT_MAPTYPE_TO && + ArgTypes[I] & OMP_TGT_MAPTYPE_FROM) Type = "tofrom"; else if (ArgTypes[I] & OMP_TGT_MAPTYPE_TO) Type = "to"; |
