https://github.com/adurang updated https://github.com/llvm/llvm-project/pull/226444
>From a6ce40f59a7b1b2e61ee6293cd01937ecca95342 Mon Sep 17 00:00:00 2001 From: "Duran, Alex" <[email protected]> Date: Mon, 7 Sep 2026 03:18:41 -0700 Subject: [PATCH 1/7] [offload][omp] Use olIterateCompatibleDevices for device init and image registration --- offload/include/PluginManager.h | 13 +- offload/include/device.h | 5 +- offload/liboffload/src/OffloadImpl.cpp | 4 + offload/libompaccsupport/PluginManager.cpp | 246 ++++++++++-------- offload/libompaccsupport/device.cpp | 17 +- .../common/include/PluginInterface.h | 6 - .../common/src/PluginInterface.cpp | 15 -- 7 files changed, 154 insertions(+), 152 deletions(-) diff --git a/offload/include/PluginManager.h b/offload/include/PluginManager.h index eea8b62a8c39da..36b8f7d3c914ba 100644 --- a/offload/include/PluginManager.h +++ b/offload/include/PluginManager.h @@ -120,11 +120,9 @@ struct PluginManager { return Devices.getExclusiveAccessor(); } - /// Initialize \p Plugin. Returns true on success. - bool initializePlugin(GenericPluginTy &Plugin); - - /// Initialize device \p DeviceNo of \p Plugin. Returns true on success. - bool initializeDevice(GenericPluginTy &Plugin, int32_t DeviceId); + /// Initialize device \p DeviceHandle as on OpenMP device. Returns true on + /// success. + bool initializeDevice(ol_device_handle_t DeviceHandle); /// Eagerly initialize all plugins and their devices. void initializeAllDevices(); @@ -158,9 +156,8 @@ struct PluginManager { // List of all plugins, in use or not. llvm::SmallVector<GenericPluginTy *> Plugins; - // Mapping of plugins to the OpenMP device identifier. - llvm::DenseMap<std::pair<const GenericPluginTy *, int32_t>, int32_t> - DeviceIds; + // Mapping of device handles to the OpenMP device identifier. + llvm::DenseMap<ol_device_handle_t, int32_t> DeviceIds; // Set of all device images currently in use. llvm::DenseSet<const __tgt_device_image *> UsedImages; diff --git a/offload/include/device.h b/offload/include/device.h index 283f49c5191e89..8b53c7fabc4abd 100644 --- a/offload/include/device.h +++ b/offload/include/device.h @@ -34,6 +34,7 @@ #include "llvm/ADT/SmallVector.h" #include "GlobalHandler.h" +#include "OffloadAPI.h" #include "PluginInterface.h" using GenericPluginTy = llvm::omp::target::plugin::GenericPluginTy; @@ -89,8 +90,10 @@ struct DeviceTy { int32_t DeviceID; GenericPluginTy *RTL; int32_t RTLDeviceID; + ol_device_handle_t DeviceHandle; - DeviceTy(GenericPluginTy *RTL, int32_t DeviceID, int32_t RTLDeviceID); + DeviceTy(GenericPluginTy *RTL, int32_t DeviceID, int32_t RTLDeviceID, + ol_device_handle_t DeviceHandle); // DeviceTy is not copyable DeviceTy(const DeviceTy &D) = delete; DeviceTy &operator=(const DeviceTy &D) = delete; diff --git a/offload/liboffload/src/OffloadImpl.cpp b/offload/liboffload/src/OffloadImpl.cpp index 6eca51f49ecf13..e79c1e2d8832e7 100644 --- a/offload/liboffload/src/OffloadImpl.cpp +++ b/offload/liboffload/src/OffloadImpl.cpp @@ -1528,6 +1528,10 @@ namespace tmp { GenericPluginTy *__ol_tgt_GetPluginFromPlatform(ol_platform_handle_t Platform) { return Platform->Plugin.get(); } + +int32_t __ol_tgt_GetPluginDeviceId(ol_device_handle_t Device) { + return Device->DeviceNum; +} } // namespace tmp } // namespace offload diff --git a/offload/libompaccsupport/PluginManager.cpp b/offload/libompaccsupport/PluginManager.cpp index d008be8d72954d..7c4b554e075f61 100644 --- a/offload/libompaccsupport/PluginManager.cpp +++ b/offload/libompaccsupport/PluginManager.cpp @@ -37,6 +37,7 @@ PluginManager *PM = nullptr; namespace llvm::offload::tmp { GenericPluginTy *__ol_tgt_GetPluginFromPlatform(ol_platform_handle_t Platform); +int32_t __ol_tgt_GetPluginDeviceId(ol_device_handle_t Device); } // namespace llvm::offload::tmp void PluginManager::init() { @@ -83,38 +84,34 @@ void PluginManager::deinit() { ODBG(ODT_Deinit) << "RTLs unloaded!"; } -bool PluginManager::initializePlugin(GenericPluginTy &Plugin) { - if (Plugin.is_initialized()) +bool PluginManager::initializeDevice(ol_device_handle_t DeviceHandle) { + if (PM->DeviceIds.find(DeviceHandle) != PM->DeviceIds.end()) { + auto ExclusiveDevicesAccessor = getExclusiveDevicesAccessor(); + (*ExclusiveDevicesAccessor)[PM->DeviceIds[DeviceHandle]] + ->setHasPendingImages(true); return true; + } - if (auto Err = Plugin.init()) { - std::string InfoMsg = toString(std::move(Err)); - ODBG(ODT_Init) << "Failed to init plugin: " << InfoMsg; + ol_platform_handle_t PlatformHandle; + if (auto Ret = olGetDeviceInfo(DeviceHandle, OL_DEVICE_INFO_PLATFORM, + sizeof(PlatformHandle), &PlatformHandle); + Ret != OL_SUCCESS) { + REPORT() << "Failed to get platform while initializing device " + << DeviceHandle; return false; } - ODBG(ODT_Init) << "Registered plugin " << Plugin.getName() << " with " - << Plugin.number_of_devices() << " visible device(s)"; - - return true; -} - -bool PluginManager::initializeDevice(GenericPluginTy &Plugin, - int32_t DeviceId) { - if (Plugin.is_device_initialized(DeviceId)) { - auto ExclusiveDevicesAccessor = getExclusiveDevicesAccessor(); - (*ExclusiveDevicesAccessor)[PM->DeviceIds[std::make_pair(&Plugin, - DeviceId)]] - ->setHasPendingImages(true); - return true; - } + GenericPluginTy &Plugin = + *llvm::offload::tmp::__ol_tgt_GetPluginFromPlatform(PlatformHandle); + int32_t DeviceId = + llvm::offload::tmp::__ol_tgt_GetPluginDeviceId(DeviceHandle); - // Initialize the device information for the RTL we are about to use. auto ExclusiveDevicesAccessor = getExclusiveDevicesAccessor(); - + // Initialize the device information for the RTL we are about to use. int32_t UserId = ExclusiveDevicesAccessor->size(); - auto Device = std::make_unique<DeviceTy>(&Plugin, UserId, DeviceId); + auto Device = + std::make_unique<DeviceTy>(&Plugin, UserId, DeviceId, DeviceHandle); if (auto Err = Device->init()) { std::string InfoMsg = toString(std::move(Err)); ODBG(ODT_Init) << "Failed to init device " << DeviceId << ": " << InfoMsg; @@ -125,21 +122,18 @@ bool PluginManager::initializeDevice(GenericPluginTy &Plugin, // We need to map between the plugin's device identifier and the one // that OpenMP will use. - PM->DeviceIds[std::make_pair(&Plugin, DeviceId)] = UserId; + PM->DeviceIds[DeviceHandle] = UserId; return true; } void PluginManager::initializeAllDevices() { - for (auto &Plugin : plugins()) { - if (!initializePlugin(Plugin)) - continue; - - for (int32_t DeviceId = 0; DeviceId < Plugin.number_of_devices(); - ++DeviceId) { - initializeDevice(Plugin, DeviceId); - } - } + olIterateDevices( + [](ol_device_handle_t Device, void *UserData) { + PM->initializeDevice(Device); + return true; + }, + nullptr); // After all plugins are initialized, register atExit cleanup handlers std::atexit([]() { // Interop cleanup should be done before the plugins are deinitialized as @@ -221,91 +215,115 @@ void PluginManager::registerLib(__tgt_bin_desc *Desc) { PM->addDeviceImage(*Desc, Desc->DeviceImages[i]); // Register the images with the RTLs that understand them, if any. - llvm::DenseMap<GenericPluginTy *, llvm::DenseSet<int32_t>> UsedDevices; + llvm::SmallVector<ol_device_handle_t> UsedDevices; for (int32_t i = 0; i < Desc->NumDeviceImages; ++i) { // Obtain the image and information that was previously extracted. __tgt_device_image *Img = &Desc->DeviceImages[i]; - GenericPluginTy *FoundRTL = nullptr; - - // Scan the RTLs that have associated images until we find one that supports - // the current image. - for (auto &R : plugins()) { - StringRef Buffer(reinterpret_cast<const char *>(Img->ImageStart), - utils::getPtrDiff(Img->ImageEnd, Img->ImageStart)); - - if (!R.isPluginCompatible(Buffer)) - continue; - - if (!initializePlugin(R)) - continue; - - if (!R.number_of_devices()) { - ODBG(ODT_Init) << "Skipping plugin " << R.getName() - << " with no visible devices"; - continue; - } - - for (int32_t DeviceId = 0; DeviceId < R.number_of_devices(); ++DeviceId) { - // We only want a single matching image to be registered for each binary - // descriptor. This prevents multiple of the same image from being - // registered for the same device in the case that they are mutually - // compatible, such as sm_80 and sm_89. - if (UsedDevices[&R].contains(DeviceId)) { - ODBG(ODT_Init) << "Image " << Img->ImageStart - << " is a duplicate, not loaded on RTL " << R.getName() - << " device " << DeviceId; - continue; - } - - if (!R.isDeviceCompatible(DeviceId, Buffer)) - continue; - - ODBG(ODT_Init) << "Image " << Img->ImageStart - << " is compatible with RTL " << R.getName() - << " device " << DeviceId; - - if (!initializeDevice(R, DeviceId)) - continue; - - // Initialize (if necessary) translation table for this library. - PM->TrlTblMtx.lock(); - if (!PM->HostEntriesBeginToTransTable.count(Desc->HostEntriesBegin)) { - PM->HostEntriesBeginRegistrationOrder.push_back( - Desc->HostEntriesBegin); - TranslationTable &TT = - (PM->HostEntriesBeginToTransTable)[Desc->HostEntriesBegin]; - TT.HostTable.EntriesBegin = Desc->HostEntriesBegin; - TT.HostTable.EntriesEnd = Desc->HostEntriesEnd; - } - - // Retrieve translation table for this library. - TranslationTable &TT = - (PM->HostEntriesBeginToTransTable)[Desc->HostEntriesBegin]; - - ODBG(ODT_Init) << "Registering image " << Img->ImageStart - << " with RTL " << R.getName(); - - auto UserId = PM->DeviceIds[std::make_pair(&R, DeviceId)]; - if (TT.TargetsTable.size() < static_cast<size_t>(UserId + 1)) { - TT.DeviceTables.resize(UserId + 1, {}); - TT.TargetsImages.resize(UserId + 1, nullptr); - TT.TargetsEntries.resize(UserId + 1, {}); - TT.TargetsTable.resize(UserId + 1, nullptr); - } - - // Register the image for this target type and invalidate the table. - TT.TargetsImages[UserId] = Img; - TT.TargetsTable[UserId] = nullptr; - - UsedDevices[&R].insert(DeviceId); - PM->UsedImages.insert(Img); - FoundRTL = &R; - - PM->TrlTblMtx.unlock(); - } - } - if (!FoundRTL) + struct RegisterImageState { + __tgt_bin_desc *Desc; + __tgt_device_image *Img; + llvm::SmallVector<ol_device_handle_t> &UsedDevices; + bool FoundRTL = false; + } State{Desc, Img, UsedDevices, false}; + + if (ol_result_t Res = olIterateCompatibleDevices( + Img->ImageStart, utils::getPtrDiff(Img->ImageEnd, Img->ImageStart), + [](ol_device_handle_t DeviceHandle, void *Data) { + auto &State = *static_cast<RegisterImageState *>(Data); + + ol_platform_handle_t PlatformHandle; + if (auto Res = + olGetDeviceInfo(DeviceHandle, OL_DEVICE_INFO_PLATFORM, + sizeof(PlatformHandle), &PlatformHandle); + Res != OL_SUCCESS) { + REPORT() << "Failed to get platform info for device " + << DeviceHandle << ":" << Res->Details; + PlatformHandle = nullptr; + } + + llvm::SmallString<256> PlatformName("Unknown"); + if (PlatformHandle) { + size_t PlatformNameSize = 0; + if (auto Res = olGetPlatformInfoSize(PlatformHandle, + OL_PLATFORM_INFO_NAME, + &PlatformNameSize); + Res != OL_SUCCESS) + PlatformNameSize = 0; + + PlatformName.resize(PlatformNameSize); + if (PlatformNameSize > 0) { + if (auto Res = olGetPlatformInfo( + PlatformHandle, OL_PLATFORM_INFO_NAME, + PlatformNameSize, PlatformName.data()); + Res != OL_SUCCESS) + PlatformName = "Unknown"; + } else + PlatformName = "Unknown"; + } + + // We only want a single matching image to be registered for each + // binary descriptor. This prevents multiple of the same image + // from being registered for the same device in the case that + // they are mutually compatible, such as sm_80 and sm_89. + if (llvm::is_contained(State.UsedDevices, DeviceHandle)) { + ODBG(ODT_Init) << "Image " << State.Img->ImageStart + << " is a duplicate, not loaded on RTL " + << PlatformName << " on device " << DeviceHandle; + return true; + } + + ODBG(ODT_Init) + << "Image " << State.Img->ImageStart << " with RTL " + << PlatformName << " on device " << DeviceHandle; + + PM->initializeDevice(DeviceHandle); + + // Initialize (if necessary) translation table for this library. + PM->TrlTblMtx.lock(); + if (!PM->HostEntriesBeginToTransTable.count( + State.Desc->HostEntriesBegin)) { + PM->HostEntriesBeginRegistrationOrder.push_back( + State.Desc->HostEntriesBegin); + TranslationTable &TT = + (PM->HostEntriesBeginToTransTable)[State.Desc + ->HostEntriesBegin]; + TT.HostTable.EntriesBegin = State.Desc->HostEntriesBegin; + TT.HostTable.EntriesEnd = State.Desc->HostEntriesEnd; + } + + // Retrieve translation table for this library. + TranslationTable &TT = + (PM->HostEntriesBeginToTransTable)[State.Desc + ->HostEntriesBegin]; + + ODBG(ODT_Init) << "Registering image " << State.Img->ImageStart + << " with RTL " << PlatformName; + + auto UserId = PM->DeviceIds[DeviceHandle]; + if (TT.TargetsTable.size() < static_cast<size_t>(UserId + 1)) { + TT.DeviceTables.resize(UserId + 1, {}); + TT.TargetsImages.resize(UserId + 1, nullptr); + TT.TargetsEntries.resize(UserId + 1, {}); + TT.TargetsTable.resize(UserId + 1, nullptr); + } + + // Register the image for this target type and invalidate the + // table. + TT.TargetsImages[UserId] = State.Img; + TT.TargetsTable[UserId] = nullptr; + + State.UsedDevices.push_back(DeviceHandle); + PM->UsedImages.insert(State.Img); + State.FoundRTL = true; + + PM->TrlTblMtx.unlock(); + return true; + }, + &State)) + REPORT() << "Failed to iterate compatible devices: " << Res->Details; + + if (!State.FoundRTL) ODBG(ODT_Init) << "No RTL found for image " << Img->ImageStart << "!"; } PM->RTLsMtx.unlock(); diff --git a/offload/libompaccsupport/device.cpp b/offload/libompaccsupport/device.cpp index cf73d504611984..e064cbdeef8588 100644 --- a/offload/libompaccsupport/device.cpp +++ b/offload/libompaccsupport/device.cpp @@ -70,9 +70,10 @@ int HostDataToTargetTy::addEventIfNecessary(DeviceTy &Device, return OFFLOAD_SUCCESS; } -DeviceTy::DeviceTy(GenericPluginTy *RTL, int32_t DeviceID, int32_t RTLDeviceID) +DeviceTy::DeviceTy(GenericPluginTy *RTL, int32_t DeviceID, int32_t RTLDeviceID, + ol_device_handle_t DeviceHandle) : DeviceID(DeviceID), RTL(RTL), RTLDeviceID(RTLDeviceID), - MappingInfo(*this) {} + DeviceHandle(DeviceHandle), MappingInfo(*this) {} DeviceTy::~DeviceTy() { if (DeviceID == -1 || !(getInfoLevel() & OMP_INFOTYPE_DUMP_TABLE)) @@ -83,11 +84,11 @@ DeviceTy::~DeviceTy() { } llvm::Error DeviceTy::init() { - int32_t Ret = RTL->init_device(RTLDeviceID); - if (Ret != OFFLOAD_SUCCESS) - return error::createOffloadError(error::ErrorCode::BACKEND_FAILURE, - "failed to initialize device %d\n", - DeviceID); + // TODO: Remove this once all device operations go through liboffload + // This just ensures the device is initialized for cases where we go through + // the plugin interface. + size_t Size = 0; + olGetDeviceInfoSize(DeviceHandle, OL_DEVICE_INFO_GLOBAL_MEM_SIZE, &Size); OMPT_IF_BUILT_AND_INITIALIZED({ GenericDeviceTy &GenericDevice = RTL->getDevice(RTLDeviceID); @@ -115,7 +116,7 @@ llvm::Error DeviceTy::init() { bool EmitReport = OMPX_EmitRecordReport || !OMPX_RecordReportFilename.get().empty(); - Ret = RTL->initialize_record_replay( + int32_t Ret = RTL->initialize_record_replay( RTLDeviceID, OMPX_RecordMemSize, nullptr, /*IsRecord=*/true, /*IsNative=*/true, OMPX_RecordOutput, EmitReport, OMPX_RecordReportFilename.get().c_str(), diff --git a/offload/plugins-nextgen/common/include/PluginInterface.h b/offload/plugins-nextgen/common/include/PluginInterface.h index 3f8050bcfbc322..f0c67599c0e1e9 100644 --- a/offload/plugins-nextgen/common/include/PluginInterface.h +++ b/offload/plugins-nextgen/common/include/PluginInterface.h @@ -1644,12 +1644,6 @@ struct GenericPluginTy { /// Returns non-zero if the \p Image is compatible with the device. int32_t isDeviceCompatible(int32_t DeviceId, StringRef Image); - /// Returns non-zero if the plugin device has been initialized. - int32_t is_device_initialized(int32_t DeviceId) const; - - /// Initialize the device inside of the plugin. - int32_t init_device(int32_t DeviceId); - /// Return the number of devices this plugin can support. int32_t number_of_devices(); diff --git a/offload/plugins-nextgen/common/src/PluginInterface.cpp b/offload/plugins-nextgen/common/src/PluginInterface.cpp index c28b0df8b6d5ad..01891f5ddbae74 100644 --- a/offload/plugins-nextgen/common/src/PluginInterface.cpp +++ b/offload/plugins-nextgen/common/src/PluginInterface.cpp @@ -1219,21 +1219,6 @@ int32_t GenericPluginTy::isDeviceCompatible(int32_t DeviceId, StringRef Image) { } } -int32_t GenericPluginTy::is_device_initialized(int32_t DeviceId) const { - return isValidDeviceId(DeviceId) && Devices[DeviceId] != nullptr; -} - -int32_t GenericPluginTy::init_device(int32_t DeviceId) { - auto Err = initDevice(DeviceId); - if (Err) { - REPORT() << "Failure to initialize device " << DeviceId << ": " - << toString(std::move(Err)); - return OFFLOAD_FAIL; - } - - return OFFLOAD_SUCCESS; -} - int32_t GenericPluginTy::number_of_devices() { return getNumDevices(); } int32_t GenericPluginTy::is_data_exchangable(int32_t SrcDeviceId, >From 6fc908fde2ba9c89ac7bcfdf2a6eb09517e63dc3 Mon Sep 17 00:00:00 2001 From: "Duran, Alex" <[email protected]> Date: Mon, 7 Sep 2026 22:38:35 -0700 Subject: [PATCH 2/7] remove two export lines --- offload/liboffload/exports | 56 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/offload/liboffload/exports b/offload/liboffload/exports index 168341aa7d9380..dd7c0881c94b10 100644 --- a/offload/liboffload/exports +++ b/offload/liboffload/exports @@ -1,6 +1,62 @@ VERS1.0 { global: ol*; +<<<<<<< HEAD +======= + # Symbols currently used by libomptarget. They should be removed from here as + # they become replaced by calls to the liboffload API. + # No new symbols should be added here. + extern "C++" { + error::OffloadError::ID; + "error::OffloadErrCategory()"; + "llvm::omp::target::RPCServerTy::registerCallback(unsigned int (*)(void*, unsigned int))"; + "llvm::omp::target::plugin::GenericDeviceTy::dataFill(void*, void const*, long, long, __tgt_async_info*)"; + "llvm::omp::target::plugin::GenericPluginTy::async_barrier(omp_interop_val_t*)"; + "llvm::omp::target::plugin::GenericPluginTy::create_event(int, void**)"; + "llvm::omp::target::plugin::GenericPluginTy::create_interop(int, int, interop_spec_t*)"; + "llvm::omp::target::plugin::GenericPluginTy::data_alloc(int, long, void*, int)"; + "llvm::omp::target::plugin::GenericPluginTy::data_delete(int, void*, int)"; + "llvm::omp::target::plugin::GenericPluginTy::data_exchange(int, void*, int, void*, long)"; + "llvm::omp::target::plugin::GenericPluginTy::data_exchange_async(int, void*, int, void*, long, __tgt_async_info*)"; + "llvm::omp::target::plugin::GenericPluginTy::data_fence(int, __tgt_async_info*)"; + "llvm::omp::target::plugin::GenericPluginTy::data_lock(int, void*, long, void**)"; + "llvm::omp::target::plugin::GenericPluginTy::data_notify_mapped(int, void*, long)"; + "llvm::omp::target::plugin::GenericPluginTy::data_notify_unmapped(int, void*)"; + "llvm::omp::target::plugin::GenericPluginTy::data_retrieve_async(int, void*, void*, long, __tgt_async_info*)"; + "llvm::omp::target::plugin::GenericPluginTy::data_submit(int, void*, void*, long)"; + "llvm::omp::target::plugin::GenericPluginTy::data_submit_async(int, void*, void*, long, __tgt_async_info*)"; + "llvm::omp::target::plugin::GenericPluginTy::data_unlock(int, void*)"; + "llvm::omp::target::plugin::GenericPluginTy::destroy_event(int, void*)"; + "llvm::omp::target::plugin::GenericPluginTy::flush_queue(omp_interop_val_t*)"; + "llvm::omp::target::plugin::GenericPluginTy::get_function(__tgt_device_binary, char const*, void**)"; + "llvm::omp::target::plugin::GenericPluginTy::get_global(__tgt_device_binary, unsigned long, char const*, void**)"; + "llvm::omp::target::plugin::GenericPluginTy::initialize_record_replay(int, long, void*, bool, bool, bool, bool, char const*, char const*)"; + "llvm::omp::target::plugin::GenericPluginTy::is_accessible_ptr(int, void const*, unsigned long)"; + "llvm::omp::target::plugin::GenericPluginTy::is_data_exchangable(int, int)"; + "llvm::omp::target::plugin::GenericPluginTy::is_initialized() const"; + "llvm::omp::target::plugin::GenericPluginTy::launch_kernel(int, void*, llvm::omp::target::plugin::KernelLaunchArgsTy&, __tgt_async_info*)"; + "llvm::omp::target::plugin::GenericPluginTy::load_binary(int, __tgt_device_image*, __tgt_device_binary*)"; + "llvm::omp::target::plugin::GenericPluginTy::number_of_devices()"; + "llvm::omp::target::plugin::GenericPluginTy::obtain_device_info(int)"; + "llvm::omp::target::plugin::GenericPluginTy::print_device_info(int)"; + "llvm::omp::target::plugin::GenericPluginTy::query_async(int, __tgt_async_info*)"; + "llvm::omp::target::plugin::GenericPluginTy::record_event(int, void*, __tgt_async_info*)"; + "llvm::omp::target::plugin::GenericPluginTy::release_interop(int, omp_interop_val_t*)"; + "llvm::omp::target::plugin::GenericPluginTy::set_device_identifier(int, int)"; + "llvm::omp::target::plugin::GenericPluginTy::sync_barrier(omp_interop_val_t*)"; + "llvm::omp::target::plugin::GenericPluginTy::sync_event(int, void*)"; + "llvm::omp::target::plugin::GenericPluginTy::synchronize(int, __tgt_async_info*)"; + "llvm::omp::target::plugin::GenericPluginTy::use_auto_zero_copy(int)"; + "llvm::omp::target::plugin::GenericPluginTy::wait_event(int, void*, __tgt_async_info*)"; + llvm::omp::target::ompt::Initialized; + llvm::omp::target::ompt::lookupCallbackByCode; + llvm::omp::target::ompt::lookupCallbackByName; + # Temporary helpers to help transition of libomptarget to liboffload. + __ol_tgt_setInfoFlag; + __ol_tgt_GetPluginFromPlatform; + __ol_tgt_GetPluginDeviceId; + }; +>>>>>>> 885a6c290ea9 (remove two export lines) local: *; }; >From 26677d68f49cada70d6b14486bb1856d87b557d5 Mon Sep 17 00:00:00 2001 From: "Duran, Alex" <[email protected]> Date: Fri, 25 Sep 2026 02:07:25 -0700 Subject: [PATCH 3/7] restore export file --- offload/liboffload/exports | 56 ---------------------- offload/libompaccsupport/PluginManager.cpp | 7 +-- offload/libompaccsupport/device.cpp | 6 --- 3 files changed, 4 insertions(+), 65 deletions(-) diff --git a/offload/liboffload/exports b/offload/liboffload/exports index dd7c0881c94b10..168341aa7d9380 100644 --- a/offload/liboffload/exports +++ b/offload/liboffload/exports @@ -1,62 +1,6 @@ VERS1.0 { global: ol*; -<<<<<<< HEAD -======= - # Symbols currently used by libomptarget. They should be removed from here as - # they become replaced by calls to the liboffload API. - # No new symbols should be added here. - extern "C++" { - error::OffloadError::ID; - "error::OffloadErrCategory()"; - "llvm::omp::target::RPCServerTy::registerCallback(unsigned int (*)(void*, unsigned int))"; - "llvm::omp::target::plugin::GenericDeviceTy::dataFill(void*, void const*, long, long, __tgt_async_info*)"; - "llvm::omp::target::plugin::GenericPluginTy::async_barrier(omp_interop_val_t*)"; - "llvm::omp::target::plugin::GenericPluginTy::create_event(int, void**)"; - "llvm::omp::target::plugin::GenericPluginTy::create_interop(int, int, interop_spec_t*)"; - "llvm::omp::target::plugin::GenericPluginTy::data_alloc(int, long, void*, int)"; - "llvm::omp::target::plugin::GenericPluginTy::data_delete(int, void*, int)"; - "llvm::omp::target::plugin::GenericPluginTy::data_exchange(int, void*, int, void*, long)"; - "llvm::omp::target::plugin::GenericPluginTy::data_exchange_async(int, void*, int, void*, long, __tgt_async_info*)"; - "llvm::omp::target::plugin::GenericPluginTy::data_fence(int, __tgt_async_info*)"; - "llvm::omp::target::plugin::GenericPluginTy::data_lock(int, void*, long, void**)"; - "llvm::omp::target::plugin::GenericPluginTy::data_notify_mapped(int, void*, long)"; - "llvm::omp::target::plugin::GenericPluginTy::data_notify_unmapped(int, void*)"; - "llvm::omp::target::plugin::GenericPluginTy::data_retrieve_async(int, void*, void*, long, __tgt_async_info*)"; - "llvm::omp::target::plugin::GenericPluginTy::data_submit(int, void*, void*, long)"; - "llvm::omp::target::plugin::GenericPluginTy::data_submit_async(int, void*, void*, long, __tgt_async_info*)"; - "llvm::omp::target::plugin::GenericPluginTy::data_unlock(int, void*)"; - "llvm::omp::target::plugin::GenericPluginTy::destroy_event(int, void*)"; - "llvm::omp::target::plugin::GenericPluginTy::flush_queue(omp_interop_val_t*)"; - "llvm::omp::target::plugin::GenericPluginTy::get_function(__tgt_device_binary, char const*, void**)"; - "llvm::omp::target::plugin::GenericPluginTy::get_global(__tgt_device_binary, unsigned long, char const*, void**)"; - "llvm::omp::target::plugin::GenericPluginTy::initialize_record_replay(int, long, void*, bool, bool, bool, bool, char const*, char const*)"; - "llvm::omp::target::plugin::GenericPluginTy::is_accessible_ptr(int, void const*, unsigned long)"; - "llvm::omp::target::plugin::GenericPluginTy::is_data_exchangable(int, int)"; - "llvm::omp::target::plugin::GenericPluginTy::is_initialized() const"; - "llvm::omp::target::plugin::GenericPluginTy::launch_kernel(int, void*, llvm::omp::target::plugin::KernelLaunchArgsTy&, __tgt_async_info*)"; - "llvm::omp::target::plugin::GenericPluginTy::load_binary(int, __tgt_device_image*, __tgt_device_binary*)"; - "llvm::omp::target::plugin::GenericPluginTy::number_of_devices()"; - "llvm::omp::target::plugin::GenericPluginTy::obtain_device_info(int)"; - "llvm::omp::target::plugin::GenericPluginTy::print_device_info(int)"; - "llvm::omp::target::plugin::GenericPluginTy::query_async(int, __tgt_async_info*)"; - "llvm::omp::target::plugin::GenericPluginTy::record_event(int, void*, __tgt_async_info*)"; - "llvm::omp::target::plugin::GenericPluginTy::release_interop(int, omp_interop_val_t*)"; - "llvm::omp::target::plugin::GenericPluginTy::set_device_identifier(int, int)"; - "llvm::omp::target::plugin::GenericPluginTy::sync_barrier(omp_interop_val_t*)"; - "llvm::omp::target::plugin::GenericPluginTy::sync_event(int, void*)"; - "llvm::omp::target::plugin::GenericPluginTy::synchronize(int, __tgt_async_info*)"; - "llvm::omp::target::plugin::GenericPluginTy::use_auto_zero_copy(int)"; - "llvm::omp::target::plugin::GenericPluginTy::wait_event(int, void*, __tgt_async_info*)"; - llvm::omp::target::ompt::Initialized; - llvm::omp::target::ompt::lookupCallbackByCode; - llvm::omp::target::ompt::lookupCallbackByName; - # Temporary helpers to help transition of libomptarget to liboffload. - __ol_tgt_setInfoFlag; - __ol_tgt_GetPluginFromPlatform; - __ol_tgt_GetPluginDeviceId; - }; ->>>>>>> 885a6c290ea9 (remove two export lines) local: *; }; diff --git a/offload/libompaccsupport/PluginManager.cpp b/offload/libompaccsupport/PluginManager.cpp index 7c4b554e075f61..efbdb2f47a0633 100644 --- a/offload/libompaccsupport/PluginManager.cpp +++ b/offload/libompaccsupport/PluginManager.cpp @@ -106,8 +106,9 @@ bool PluginManager::initializeDevice(ol_device_handle_t DeviceHandle) { int32_t DeviceId = llvm::offload::tmp::__ol_tgt_GetPluginDeviceId(DeviceHandle); - auto ExclusiveDevicesAccessor = getExclusiveDevicesAccessor(); // Initialize the device information for the RTL we are about to use. + auto ExclusiveDevicesAccessor = getExclusiveDevicesAccessor(); + int32_t UserId = ExclusiveDevicesAccessor->size(); auto Device = @@ -120,8 +121,8 @@ bool PluginManager::initializeDevice(ol_device_handle_t DeviceHandle) { ExclusiveDevicesAccessor->push_back(std::move(Device)); - // We need to map between the plugin's device identifier and the one - // that OpenMP will use. + // We need to map between the liboffload device handle and the OpenMP device + // id. PM->DeviceIds[DeviceHandle] = UserId; return true; diff --git a/offload/libompaccsupport/device.cpp b/offload/libompaccsupport/device.cpp index e064cbdeef8588..af30aa757a15a2 100644 --- a/offload/libompaccsupport/device.cpp +++ b/offload/libompaccsupport/device.cpp @@ -84,12 +84,6 @@ DeviceTy::~DeviceTy() { } llvm::Error DeviceTy::init() { - // TODO: Remove this once all device operations go through liboffload - // This just ensures the device is initialized for cases where we go through - // the plugin interface. - size_t Size = 0; - olGetDeviceInfoSize(DeviceHandle, OL_DEVICE_INFO_GLOBAL_MEM_SIZE, &Size); - OMPT_IF_BUILT_AND_INITIALIZED({ GenericDeviceTy &GenericDevice = RTL->getDevice(RTLDeviceID); std::string ComputeUnitKind = GenericDevice.getComputeUnitKind(); >From a6d02105881bd571e74d02d38e823ca1ad6c0b8d Mon Sep 17 00:00:00 2001 From: "Duran, Alex" <[email protected]> Date: Mon, 5 Oct 2026 13:24:58 -0700 Subject: [PATCH 4/7] move lambda to helper --- offload/include/PluginManager.h | 8 + offload/libompaccsupport/PluginManager.cpp | 172 ++++++++++----------- 2 files changed, 92 insertions(+), 88 deletions(-) diff --git a/offload/include/PluginManager.h b/offload/include/PluginManager.h index 36b8f7d3c914ba..ee299c1cf4af29 100644 --- a/offload/include/PluginManager.h +++ b/offload/include/PluginManager.h @@ -179,6 +179,14 @@ struct PluginManager { std::list<llvm::SmallVector<__tgt_device_image, 0>> LegacyImages; llvm::DenseMap<__tgt_bin_desc *, __tgt_bin_desc> UpgradedDescriptors; __tgt_bin_desc *upgradeLegacyEntries(__tgt_bin_desc *Desc); + + /// Register the image \p Img from \p Desc on the compatible device + /// \p DeviceHandle, unless the device is already in \p UsedDevices. Returns + /// true if the image was registered. + bool + registerImageOnDevice(ol_device_handle_t DeviceHandle, __tgt_bin_desc *Desc, + __tgt_device_image *Img, + llvm::SmallVectorImpl<ol_device_handle_t> &UsedDevices); }; /// Initialize the plugin manager and OpenMP runtime. diff --git a/offload/libompaccsupport/PluginManager.cpp b/offload/libompaccsupport/PluginManager.cpp index efbdb2f47a0633..9732b0ce98de1b 100644 --- a/offload/libompaccsupport/PluginManager.cpp +++ b/offload/libompaccsupport/PluginManager.cpp @@ -198,6 +198,86 @@ __tgt_bin_desc *PluginManager::upgradeLegacyEntries(__tgt_bin_desc *Desc) { return &NewDesc; } +bool PluginManager::registerImageOnDevice( + ol_device_handle_t DeviceHandle, __tgt_bin_desc *Desc, + __tgt_device_image *Img, + llvm::SmallVectorImpl<ol_device_handle_t> &UsedDevices) { + + ol_platform_handle_t PlatformHandle; + if (auto Res = olGetDeviceInfo(DeviceHandle, OL_DEVICE_INFO_PLATFORM, + sizeof(PlatformHandle), &PlatformHandle); + Res != OL_SUCCESS) { + REPORT() << "Failed to get platform info for device " << DeviceHandle << ":" + << Res->Details; + PlatformHandle = nullptr; + } + + llvm::SmallString<256> PlatformName("Unknown"); + if (PlatformHandle) { + size_t PlatformNameSize = 0; + if (auto Res = olGetPlatformInfoSize(PlatformHandle, OL_PLATFORM_INFO_NAME, + &PlatformNameSize); + Res != OL_SUCCESS) + PlatformNameSize = 0; + + PlatformName.resize(PlatformNameSize); + if (PlatformNameSize > 0) { + if (auto Res = olGetPlatformInfo(PlatformHandle, OL_PLATFORM_INFO_NAME, + PlatformNameSize, PlatformName.data()); + Res != OL_SUCCESS) + PlatformName = "Unknown"; + } else + PlatformName = "Unknown"; + } + + // We only want a single matching image to be registered for each binary + // descriptor. This prevents multiple of the same image from being registered + // for the same device in the case that they are mutually compatible, such as + // sm_80 and sm_89. + if (llvm::is_contained(UsedDevices, DeviceHandle)) { + ODBG(ODT_Init) << "Image " << Img->ImageStart + << " is a duplicate, not loaded on RTL " << PlatformName + << " on device " << DeviceHandle; + return false; + } + + ODBG(ODT_Init) << "Image " << Img->ImageStart << " with RTL " << PlatformName + << " on device " << DeviceHandle; + + initializeDevice(DeviceHandle); + + // Initialize (if necessary) translation table for this library. + std::lock_guard<std::mutex> LG(TrlTblMtx); + if (!HostEntriesBeginToTransTable.count(Desc->HostEntriesBegin)) { + HostEntriesBeginRegistrationOrder.push_back(Desc->HostEntriesBegin); + TranslationTable &TT = HostEntriesBeginToTransTable[Desc->HostEntriesBegin]; + TT.HostTable.EntriesBegin = Desc->HostEntriesBegin; + TT.HostTable.EntriesEnd = Desc->HostEntriesEnd; + } + + // Retrieve translation table for this library. + TranslationTable &TT = HostEntriesBeginToTransTable[Desc->HostEntriesBegin]; + + ODBG(ODT_Init) << "Registering image " << Img->ImageStart << " with RTL " + << PlatformName; + + auto UserId = DeviceIds[DeviceHandle]; + if (TT.TargetsTable.size() < static_cast<size_t>(UserId + 1)) { + TT.DeviceTables.resize(UserId + 1, {}); + TT.TargetsImages.resize(UserId + 1, nullptr); + TT.TargetsEntries.resize(UserId + 1, {}); + TT.TargetsTable.resize(UserId + 1, nullptr); + } + + // Register the image for this target type and invalidate the table. + TT.TargetsImages[UserId] = Img; + TT.TargetsTable[UserId] = nullptr; + + UsedDevices.push_back(DeviceHandle); + UsedImages.insert(Img); + return true; +} + void PluginManager::registerLib(__tgt_bin_desc *Desc) { PM->RTLsMtx.lock(); @@ -224,7 +304,7 @@ void PluginManager::registerLib(__tgt_bin_desc *Desc) { struct RegisterImageState { __tgt_bin_desc *Desc; __tgt_device_image *Img; - llvm::SmallVector<ol_device_handle_t> &UsedDevices; + llvm::SmallVectorImpl<ol_device_handle_t> &UsedDevices; bool FoundRTL = false; } State{Desc, Img, UsedDevices, false}; @@ -232,93 +312,9 @@ void PluginManager::registerLib(__tgt_bin_desc *Desc) { Img->ImageStart, utils::getPtrDiff(Img->ImageEnd, Img->ImageStart), [](ol_device_handle_t DeviceHandle, void *Data) { auto &State = *static_cast<RegisterImageState *>(Data); - - ol_platform_handle_t PlatformHandle; - if (auto Res = - olGetDeviceInfo(DeviceHandle, OL_DEVICE_INFO_PLATFORM, - sizeof(PlatformHandle), &PlatformHandle); - Res != OL_SUCCESS) { - REPORT() << "Failed to get platform info for device " - << DeviceHandle << ":" << Res->Details; - PlatformHandle = nullptr; - } - - llvm::SmallString<256> PlatformName("Unknown"); - if (PlatformHandle) { - size_t PlatformNameSize = 0; - if (auto Res = olGetPlatformInfoSize(PlatformHandle, - OL_PLATFORM_INFO_NAME, - &PlatformNameSize); - Res != OL_SUCCESS) - PlatformNameSize = 0; - - PlatformName.resize(PlatformNameSize); - if (PlatformNameSize > 0) { - if (auto Res = olGetPlatformInfo( - PlatformHandle, OL_PLATFORM_INFO_NAME, - PlatformNameSize, PlatformName.data()); - Res != OL_SUCCESS) - PlatformName = "Unknown"; - } else - PlatformName = "Unknown"; - } - - // We only want a single matching image to be registered for each - // binary descriptor. This prevents multiple of the same image - // from being registered for the same device in the case that - // they are mutually compatible, such as sm_80 and sm_89. - if (llvm::is_contained(State.UsedDevices, DeviceHandle)) { - ODBG(ODT_Init) << "Image " << State.Img->ImageStart - << " is a duplicate, not loaded on RTL " - << PlatformName << " on device " << DeviceHandle; - return true; - } - - ODBG(ODT_Init) - << "Image " << State.Img->ImageStart << " with RTL " - << PlatformName << " on device " << DeviceHandle; - - PM->initializeDevice(DeviceHandle); - - // Initialize (if necessary) translation table for this library. - PM->TrlTblMtx.lock(); - if (!PM->HostEntriesBeginToTransTable.count( - State.Desc->HostEntriesBegin)) { - PM->HostEntriesBeginRegistrationOrder.push_back( - State.Desc->HostEntriesBegin); - TranslationTable &TT = - (PM->HostEntriesBeginToTransTable)[State.Desc - ->HostEntriesBegin]; - TT.HostTable.EntriesBegin = State.Desc->HostEntriesBegin; - TT.HostTable.EntriesEnd = State.Desc->HostEntriesEnd; - } - - // Retrieve translation table for this library. - TranslationTable &TT = - (PM->HostEntriesBeginToTransTable)[State.Desc - ->HostEntriesBegin]; - - ODBG(ODT_Init) << "Registering image " << State.Img->ImageStart - << " with RTL " << PlatformName; - - auto UserId = PM->DeviceIds[DeviceHandle]; - if (TT.TargetsTable.size() < static_cast<size_t>(UserId + 1)) { - TT.DeviceTables.resize(UserId + 1, {}); - TT.TargetsImages.resize(UserId + 1, nullptr); - TT.TargetsEntries.resize(UserId + 1, {}); - TT.TargetsTable.resize(UserId + 1, nullptr); - } - - // Register the image for this target type and invalidate the - // table. - TT.TargetsImages[UserId] = State.Img; - TT.TargetsTable[UserId] = nullptr; - - State.UsedDevices.push_back(DeviceHandle); - PM->UsedImages.insert(State.Img); - State.FoundRTL = true; - - PM->TrlTblMtx.unlock(); + if (PM->registerImageOnDevice(DeviceHandle, State.Desc, State.Img, + State.UsedDevices)) + State.FoundRTL = true; return true; }, &State)) >From 6033262dc26de4f3b6575ccb3874e1a137a723c9 Mon Sep 17 00:00:00 2001 From: "Duran, Alex" <[email protected]> Date: Mon, 7 Sep 2026 03:26:53 -0700 Subject: [PATCH 5/7] [offload][omp] memory operations through liboffload --- offload/include/PluginManager.h | 6 ++ offload/include/device.h | 4 + offload/include/omptarget.h | 21 +++-- offload/liboffload/src/OffloadImpl.cpp | 5 ++ offload/libompaccsupport/AsyncInfo.cpp | 29 +++++- offload/libompaccsupport/PluginManager.cpp | 47 ++++++++-- offload/libompaccsupport/device.cpp | 80 ++++++++++++++--- offload/libomptarget/OpenMP/API.cpp | 36 +++----- .../common/include/PluginInterface.h | 31 ------- .../common/src/PluginInterface.cpp | 90 ------------------- offload/tools/kernelreplay/CMakeLists.txt | 1 + 11 files changed, 180 insertions(+), 170 deletions(-) diff --git a/offload/include/PluginManager.h b/offload/include/PluginManager.h index ee299c1cf4af29..955bbefef7cecf 100644 --- a/offload/include/PluginManager.h +++ b/offload/include/PluginManager.h @@ -149,6 +149,8 @@ struct PluginManager { return count; } + ol_device_handle_t getHostDevice(); + private: bool RTLsLoaded = false; llvm::SmallVector<__tgt_bin_desc *> DelayedBinDesc; @@ -180,6 +182,10 @@ struct PluginManager { llvm::DenseMap<__tgt_bin_desc *, __tgt_bin_desc> UpgradedDescriptors; __tgt_bin_desc *upgradeLegacyEntries(__tgt_bin_desc *Desc); + // Platform and device handles for host device operations. + ol_platform_handle_t HostPlatform = nullptr; + ol_device_handle_t HostDevice = nullptr; + /// Register the image \p Img from \p Desc on the compatible device /// \p DeviceHandle, unless the device is already in \p UsedDevices. Returns /// true if the image was registered. diff --git a/offload/include/device.h b/offload/include/device.h index 8b53c7fabc4abd..0488fedb616e65 100644 --- a/offload/include/device.h +++ b/offload/include/device.h @@ -91,6 +91,7 @@ struct DeviceTy { GenericPluginTy *RTL; int32_t RTLDeviceID; ol_device_handle_t DeviceHandle; + ol_context_handle_t Context; DeviceTy(GenericPluginTy *RTL, int32_t DeviceID, int32_t RTLDeviceID, ol_device_handle_t DeviceHandle); @@ -103,6 +104,9 @@ struct DeviceTy { /// Try to initialize the device and return any failure. llvm::Error init(); + /// Deinitialize the OpenMP device. + llvm::Error deinit(); + /// Provide access to the mapping handler. MappingInfoTy &getMappingInfo() { return MappingInfo; } diff --git a/offload/include/omptarget.h b/offload/include/omptarget.h index 6bd61036cc4b34..5299b7eabe4b5d 100644 --- a/offload/include/omptarget.h +++ b/offload/include/omptarget.h @@ -14,6 +14,8 @@ #ifndef _OMPTARGET_H_ #define _OMPTARGET_H_ +#include "OffloadAPI.h" + #include "Shared/APITypes.h" #include "Shared/Environment.h" #include "Shared/SourceInfo.h" @@ -112,6 +114,11 @@ enum TargetAllocTy : int32_t { struct DeviceTy; +// temporary helper from liboffload until all usage of AsyncInfo +// are migrated to use liboffload queues. +extern "C" __tgt_async_info * +__ol__tgt_GetAsyncInfoFromQueue(ol_queue_handle_t Queue); + /// The libomptarget wrapper around a __tgt_async_info object directly /// associated with a libomptarget layer device. RAII semantics to avoid /// mistakes. @@ -130,20 +137,24 @@ class AsyncInfoTy { using PostProcFuncTy = std::function<int()>; llvm::SmallVector<PostProcFuncTy> PostProcessingFunctions; - __tgt_async_info AsyncInfo; + ol_queue_handle_t Queue; DeviceTy &Device; public: /// Synchronization method to be used. SyncTy SyncType; - AsyncInfoTy(DeviceTy &Device, SyncTy SyncType = SyncTy::BLOCKING) - : Device(Device), SyncType(SyncType) {} - ~AsyncInfoTy() { synchronize(); } + AsyncInfoTy(DeviceTy &Device, SyncTy SyncType = SyncTy::BLOCKING); + ~AsyncInfoTy(); /// Implicit conversion to the __tgt_async_info which is used in the /// plugin interface. - operator __tgt_async_info *() { return &AsyncInfo; } + operator __tgt_async_info *() { + return __ol__tgt_GetAsyncInfoFromQueue(Queue); + } + + /// Get the underlying queue handle. + ol_queue_handle_t getQueue() const { return Queue; } /// Synchronize all pending actions. /// diff --git a/offload/liboffload/src/OffloadImpl.cpp b/offload/liboffload/src/OffloadImpl.cpp index e79c1e2d8832e7..7132d71a7e18f3 100644 --- a/offload/liboffload/src/OffloadImpl.cpp +++ b/offload/liboffload/src/OffloadImpl.cpp @@ -1534,5 +1534,10 @@ int32_t __ol_tgt_GetPluginDeviceId(ol_device_handle_t Device) { } } // namespace tmp +extern "C" __tgt_async_info * +__ol__tgt_GetAsyncInfoFromQueue(ol_queue_handle_t Queue) { + return Queue->AsyncInfo; +} + } // namespace offload } // namespace llvm diff --git a/offload/libompaccsupport/AsyncInfo.cpp b/offload/libompaccsupport/AsyncInfo.cpp index 4a08cc67fcb231..791bc92be412ce 100644 --- a/offload/libompaccsupport/AsyncInfo.cpp +++ b/offload/libompaccsupport/AsyncInfo.cpp @@ -16,6 +16,23 @@ using namespace llvm::omp::target::debug; +AsyncInfoTy::AsyncInfoTy(DeviceTy &Device, SyncTy SyncType) + : Device(Device), SyncType(SyncType) { + + if (auto Res = olCreateQueue(Device.Context, Device.DeviceHandle, &Queue)) { + REPORT() << "Failed to create queue for device " << Device.DeviceHandle + << ": " << Res->Details; + Queue = nullptr; + } +} + +AsyncInfoTy::~AsyncInfoTy() { + if (Queue) { + synchronize(); + olDestroyQueue(Queue); + } +} + int AsyncInfoTy::synchronize() { int Result = OFFLOAD_SUCCESS; if (!isQueueEmpty()) { @@ -23,9 +40,6 @@ int AsyncInfoTy::synchronize() { case SyncTy::BLOCKING: // If we have a queue we need to synchronize it now. Result = Device.synchronize(*this); - assert(AsyncInfo.Queue == nullptr && - "The device plugin should have nulled the queue to indicate there " - "are no outstanding actions!"); break; case SyncTy::NON_BLOCKING: Result = Device.queryAsync(*this); @@ -66,4 +80,11 @@ int32_t AsyncInfoTy::runPostProcessing() { return OFFLOAD_SUCCESS; } -bool AsyncInfoTy::isQueueEmpty() const { return AsyncInfo.Queue == nullptr; } +bool AsyncInfoTy::isQueueEmpty() const { + bool isComplete; + if (auto Res = olQueryQueue(Queue, &isComplete)) { + REPORT() << "Failed to query queue " << Queue << ": " << Res->Details; + return false; + } + return isComplete; +} diff --git a/offload/libompaccsupport/PluginManager.cpp b/offload/libompaccsupport/PluginManager.cpp index 9732b0ce98de1b..1de5c0663681d2 100644 --- a/offload/libompaccsupport/PluginManager.cpp +++ b/offload/libompaccsupport/PluginManager.cpp @@ -59,6 +59,11 @@ void PluginManager::init() { ODBG(ODT_Init) << "Adding plugin " << Plugin->getName() << " from liboffload"; PM->Plugins.push_back(Plugin); + ol_platform_backend_t Backend; + olGetPlatformInfo(Platform, OL_PLATFORM_INFO_BACKEND, + sizeof(Backend), &Backend); + if (Backend == OL_PLATFORM_BACKEND_HOST) + PM->HostPlatform = Platform; return true; }, this)) @@ -71,11 +76,15 @@ void PluginManager::deinit() { TIMESCOPE(); ODBG(ODT_Deinit) << "Unloading RTLs..."; + auto ExclusiveDevicesAccessor = getExclusiveDevicesAccessor(); OMPT_IF_BUILT_AND_INITIALIZED({ - auto ExclusiveDevicesAccessor = getExclusiveDevicesAccessor(); for (DeviceTy &Device : devices(ExclusiveDevicesAccessor)) performOmptCallback(device_finalize, Device.DeviceID); }); + for (auto &Device : *ExclusiveDevicesAccessor) + if (auto Err = Device->deinit()) + REPORT() << "Failed to deinitialize device " << Device->DeviceID << ": " + << toString(std::move(Err)); Plugins.clear(); if (auto Err = olShutDown()) @@ -84,6 +93,33 @@ void PluginManager::deinit() { ODBG(ODT_Deinit) << "RTLs unloaded!"; } +ol_device_handle_t PluginManager::getHostDevice() { + if (!HostDevice) { + olIterateDevices( + [](ol_device_handle_t D, void *Data) { + ol_platform_handle_t Platform; + olGetDeviceInfo(D, OL_DEVICE_INFO_PLATFORM, sizeof(Platform), + &Platform); + ol_platform_backend_t Backend; + olGetPlatformInfo(Platform, OL_PLATFORM_INFO_BACKEND, sizeof(Backend), + &Backend); + + if (Backend == OL_PLATFORM_BACKEND_HOST) { + GenericPluginTy *HostPlugin = + __ol_tgt_GetPluginFromPlatform(Platform); + HostPlugin->set_device_identifier(omp_initial_device, 0); + *(static_cast<ol_device_handle_t *>(Data)) = D; + return false; + } + + return true; + }, + &HostDevice); + } + + return HostDevice; +} + bool PluginManager::initializeDevice(ol_device_handle_t DeviceHandle) { if (PM->DeviceIds.find(DeviceHandle) != PM->DeviceIds.end()) { auto ExclusiveDevicesAccessor = getExclusiveDevicesAccessor(); @@ -477,11 +513,12 @@ static int loadImagesOntoDevice(DeviceTy &Device) { if (!(Entry.Flags & OMP_DECLARE_TARGET_INDIRECT_VTABLE) && !(Entry.Flags & OMP_DECLARE_TARGET_INDIRECT) && ((PM->getRequirements() & OMP_REQ_UNIFIED_SHARED_MEMORY) || - (PM->getRequirements() & OMPX_REQ_AUTO_ZERO_COPY))) - if (Device.RTL->data_submit(DeviceId, DeviceEntry.Address, - Entry.Address, - Entry.Size) != OFFLOAD_SUCCESS) + (PM->getRequirements() & OMPX_REQ_AUTO_ZERO_COPY))) { + AsyncInfoTy AsyncInfo(Device); + if (Device.submitData(DeviceEntry.Address, Entry.Address, + Entry.Size, AsyncInfo) != OFFLOAD_SUCCESS) REPORT() << "Failed to write symbol for USM " << Entry.SymbolName; + } } else if (Entry.Address) { if (Device.RTL->get_function(Binary, Entry.SymbolName, &DeviceEntry.Address) != diff --git a/offload/libompaccsupport/device.cpp b/offload/libompaccsupport/device.cpp index af30aa757a15a2..4dbc2351abf4f7 100644 --- a/offload/libompaccsupport/device.cpp +++ b/offload/libompaccsupport/device.cpp @@ -84,6 +84,12 @@ DeviceTy::~DeviceTy() { } llvm::Error DeviceTy::init() { + if (olCreateContext(1, &DeviceHandle, &Context)) { + return error::createOffloadError(error::ErrorCode::BACKEND_FAILURE, + "failed to create context for device %d\n", + DeviceID); + } + OMPT_IF_BUILT_AND_INITIALIZED({ GenericDeviceTy &GenericDevice = RTL->getDevice(RTLDeviceID); std::string ComputeUnitKind = GenericDevice.getComputeUnitKind(); @@ -124,6 +130,15 @@ llvm::Error DeviceTy::init() { return llvm::Error::success(); } +llvm::Error DeviceTy::deinit() { + if (olDestroyContext(Context)) { + return error::createOffloadError( + error::ErrorCode::BACKEND_FAILURE, + "failed to destroy context for device %d\n", DeviceID); + } + return llvm::Error::success(); +} + // 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 @@ -304,8 +319,18 @@ int32_t DeviceTy::submitData(void *TgtPtrBegin, void *HstPtrBegin, int64_t Size, omp_initial_device, HstPtrBegin, DeviceID, TgtPtrBegin, Size, /*CodePtr=*/OMPT_GET_RETURN_ADDRESS);) - return RTL->data_submit_async(RTLDeviceID, TgtPtrBegin, HstPtrBegin, Size, - AsyncInfo); + ol_queue_handle_t queue = AsyncInfo.getQueue(); + if (!queue) + return OFFLOAD_FAIL; + + if (auto Res = olMemcpy(queue, TgtPtrBegin, DeviceHandle, HstPtrBegin, + PM->getHostDevice(), Size)) { + REPORT() << "Failure to copy data from host to device. Pointers: host " + << "= " << HstPtrBegin << ", device = " << TgtPtrBegin + << ", size = " << Size << ": " << Res->Details; + return OFFLOAD_FAIL; + } + return OFFLOAD_SUCCESS; } // Retrieve data from device @@ -324,8 +349,17 @@ int32_t DeviceTy::retrieveData(void *HstPtrBegin, void *TgtPtrBegin, DeviceID, TgtPtrBegin, omp_initial_device, HstPtrBegin, Size, /*CodePtr=*/OMPT_GET_RETURN_ADDRESS);) - return RTL->data_retrieve_async(RTLDeviceID, HstPtrBegin, TgtPtrBegin, Size, - AsyncInfo); + ol_queue_handle_t queue = AsyncInfo.getQueue(); + if (!queue) + return OFFLOAD_FAIL; + if (auto Res = olMemcpy(queue, HstPtrBegin, PM->getHostDevice(), TgtPtrBegin, + DeviceHandle, Size)) { + REPORT() << "Failure to copy data from device to host. Pointers: host " + << "= " << HstPtrBegin << ", device = " << TgtPtrBegin + << ", size = " << Size << ": " << Res->Details; + return OFFLOAD_FAIL; + } + return OFFLOAD_SUCCESS; } // Copy data from current device to destination device directly @@ -342,12 +376,19 @@ int32_t DeviceTy::dataExchange(void *SrcPtr, DeviceTy &DstDev, void *DstPtr, RegionInterface.getCallbacks<ompt_target_data_transfer_from_device>(), RTLDeviceID, SrcPtr, DstDev.RTLDeviceID, DstPtr, Size, /*CodePtr=*/OMPT_GET_RETURN_ADDRESS);) - if (!AsyncInfo) { - return RTL->data_exchange(RTLDeviceID, SrcPtr, DstDev.RTLDeviceID, DstPtr, - Size); + + ol_queue_handle_t queue = AsyncInfo.getQueue(); + if (!queue) + return OFFLOAD_FAIL; + if (auto Res = olMemcpy(queue, DstPtr, DstDev.DeviceHandle, SrcPtr, + DeviceHandle, Size)) { + REPORT() << "Failure to copy data from device (" << RTLDeviceID + << ") to device (" << DstDev.RTLDeviceID + << "). Pointers: host = " << SrcPtr << ", device = " << DstPtr + << ", size = " << Size << ": " << Res->Details; + return OFFLOAD_FAIL; } - return RTL->data_exchange_async(RTLDeviceID, SrcPtr, DstDev.RTLDeviceID, - DstPtr, Size, AsyncInfo); + return OFFLOAD_SUCCESS; } int32_t DeviceTy::dataFence(AsyncInfoTy &AsyncInfo) { @@ -877,11 +918,28 @@ bool DeviceTy::isDataExchangable(const DeviceTy &DstDevice) { } int32_t DeviceTy::synchronize(AsyncInfoTy &AsyncInfo) { - return RTL->synchronize(RTLDeviceID, AsyncInfo); + ol_queue_handle_t Queue = AsyncInfo.getQueue(); + if (!Queue) + return OFFLOAD_SUCCESS; + if (auto Res = olSyncQueue(Queue)) { + REPORT() << "Failure to synchronize stream " << Queue << ": " + << Res->Details; + return OFFLOAD_FAIL; + } + return OFFLOAD_SUCCESS; } int32_t DeviceTy::queryAsync(AsyncInfoTy &AsyncInfo) { - return RTL->query_async(RTLDeviceID, AsyncInfo); + ol_queue_handle_t Queue = AsyncInfo.getQueue(); + if (!Queue) + return OFFLOAD_SUCCESS; + + bool isComplete; + if (auto Res = olQueryQueue(Queue, &isComplete)) { + REPORT() << "Failure to query stream " << Queue << ": " << Res->Details; + return OFFLOAD_FAIL; + } + return OFFLOAD_SUCCESS; } int32_t DeviceTy::createEvent(void **Event) { diff --git a/offload/libomptarget/OpenMP/API.cpp b/offload/libomptarget/OpenMP/API.cpp index 1590aab702e267..0f1c0a68534af7 100644 --- a/offload/libomptarget/OpenMP/API.cpp +++ b/offload/libomptarget/OpenMP/API.cpp @@ -335,31 +335,13 @@ EXTERN int omp_target_memcpy(void *Dst, const void *Src, size_t Length, if (!SrcDeviceOrErr) FATAL_MESSAGE(SrcDevice, "%s", toString(SrcDeviceOrErr.takeError()).c_str()); - AsyncInfoTy AsyncInfo(*SrcDeviceOrErr); auto DstDeviceOrErr = PM->getDevice(DstDevice); if (!DstDeviceOrErr) FATAL_MESSAGE(DstDevice, "%s", toString(DstDeviceOrErr.takeError()).c_str()); - // First try to use D2D memcpy which is more efficient. If fails, fall back - // to inefficient way. - if (SrcDeviceOrErr->isDataExchangable(*DstDeviceOrErr)) { - AsyncInfoTy AsyncInfo(*SrcDeviceOrErr); - Rc = SrcDeviceOrErr->dataExchange(SrcAddr, *DstDeviceOrErr, DstAddr, - Length, AsyncInfo); - if (Rc == OFFLOAD_SUCCESS) - return OFFLOAD_SUCCESS; - } - - void *Buffer = malloc(Length); - { - AsyncInfoTy AsyncInfo(*SrcDeviceOrErr); - Rc = SrcDeviceOrErr->retrieveData(Buffer, SrcAddr, Length, AsyncInfo); - } - if (Rc == OFFLOAD_SUCCESS) { - AsyncInfoTy AsyncInfo(*DstDeviceOrErr); - Rc = DstDeviceOrErr->submitData(DstAddr, Buffer, Length, AsyncInfo); - } - free(Buffer); + AsyncInfoTy AsyncInfo(*SrcDeviceOrErr); + Rc = SrcDeviceOrErr->dataExchange(SrcAddr, *DstDeviceOrErr, DstAddr, Length, + AsyncInfo); } ODBG(ODT_Interface) << __func__ << " returns " << Rc; @@ -486,10 +468,16 @@ EXTERN void *omp_target_memset(void *Ptr, int ByteVal, size_t NumBytes, if (!DeviceOrErr) FATAL_MESSAGE(DeviceNum, "%s", toString(DeviceOrErr.takeError()).c_str()); AsyncInfoTy AsyncInfo(*DeviceOrErr); - if (auto Error = DeviceOrErr->RTL->getDevice(DeviceOrErr->RTLDeviceID) - .dataFill(Ptr, &ByteVal, 1, NumBytes, AsyncInfo)) { + ol_queue_handle_t Queue = AsyncInfo.getQueue(); + if (!Queue) { + ODBG(ODT_Interface) << "Failed to get queue for async memset on device " + << DeviceNum; + return Ptr; + } + if (auto Res = olMemFill(Queue, Ptr, 1, &ByteVal, NumBytes)) { ODBG(ODT_Interface) - << __func__ << " failed to fill memory due to error with dataFill"; + << __func__ << " failed to fill memory due to error with dataFill:" + << Res->Details; // If the dataFill failed, let's just not do anything. // omp_target_memset does not have any good way to fail. // Depending on the RTL implementation, the application will diff --git a/offload/plugins-nextgen/common/include/PluginInterface.h b/offload/plugins-nextgen/common/include/PluginInterface.h index f0c67599c0e1e9..60495495248dc4 100644 --- a/offload/plugins-nextgen/common/include/PluginInterface.h +++ b/offload/plugins-nextgen/common/include/PluginInterface.h @@ -1680,31 +1680,6 @@ struct GenericPluginTy { /// Notify t he runtime about a mapping that has been deleted. int32_t data_notify_unmapped(int32_t DeviceId, void *HstPtr); - /// Copy data to the given device. - int32_t data_submit(int32_t DeviceId, void *TgtPtr, void *HstPtr, - int64_t Size); - - /// Copy data to the given device asynchronously. - int32_t data_submit_async(int32_t DeviceId, void *TgtPtr, void *HstPtr, - int64_t Size, __tgt_async_info *AsyncInfoPtr); - - /// Copy data from the given device. - int32_t data_retrieve(int32_t DeviceId, void *HstPtr, void *TgtPtr, - int64_t Size); - - /// Copy data from the given device asynchronously. - int32_t data_retrieve_async(int32_t DeviceId, void *HstPtr, void *TgtPtr, - int64_t Size, __tgt_async_info *AsyncInfoPtr); - - /// Exchange memory addresses between two devices. - int32_t data_exchange(int32_t SrcDeviceId, void *SrcPtr, int32_t DstDeviceId, - void *DstPtr, int64_t Size); - - /// Exchange memory addresses between two devices asynchronously. - int32_t data_exchange_async(int32_t SrcDeviceId, void *SrcPtr, - int DstDeviceId, void *DstPtr, int64_t Size, - __tgt_async_info *AsyncInfo); - /// Places a fence between previous data movements and following data /// movements if necessary on the device int32_t data_fence(int32_t DeviceId, __tgt_async_info *AsyncInfo); @@ -1714,12 +1689,6 @@ struct GenericPluginTy { KernelLaunchArgsTy &LaunchArgs, __tgt_async_info *AsyncInfoPtr); - /// Synchronize an asyncrhonous queue with the plugin runtime. - int32_t synchronize(int32_t DeviceId, __tgt_async_info *AsyncInfoPtr); - - /// Query the current state of an asynchronous queue. - int32_t query_async(int32_t DeviceId, __tgt_async_info *AsyncInfoPtr); - /// Obtain information about the given device. InfoTreeNode obtain_device_info(int32_t DeviceId); diff --git a/offload/plugins-nextgen/common/src/PluginInterface.cpp b/offload/plugins-nextgen/common/src/PluginInterface.cpp index 01891f5ddbae74..8404f8bceacdac 100644 --- a/offload/plugins-nextgen/common/src/PluginInterface.cpp +++ b/offload/plugins-nextgen/common/src/PluginInterface.cpp @@ -1347,72 +1347,6 @@ int32_t GenericPluginTy::data_notify_unmapped(int32_t DeviceId, void *HstPtr) { return OFFLOAD_SUCCESS; } -int32_t GenericPluginTy::data_submit(int32_t DeviceId, void *TgtPtr, - void *HstPtr, int64_t Size) { - return data_submit_async(DeviceId, TgtPtr, HstPtr, Size, - /*AsyncInfoPtr=*/nullptr); -} - -int32_t GenericPluginTy::data_submit_async(int32_t DeviceId, void *TgtPtr, - void *HstPtr, int64_t Size, - __tgt_async_info *AsyncInfoPtr) { - auto Err = getDevice(DeviceId).dataSubmit(TgtPtr, HstPtr, Size, AsyncInfoPtr); - if (Err) { - REPORT() << "Failure to copy data from host to device. Pointers: host " - << "= " << HstPtr << ", device = " << TgtPtr << ", size = " << Size - << ": " << toString(std::move(Err)); - return OFFLOAD_FAIL; - } - - return OFFLOAD_SUCCESS; -} - -int32_t GenericPluginTy::data_retrieve(int32_t DeviceId, void *HstPtr, - void *TgtPtr, int64_t Size) { - return data_retrieve_async(DeviceId, HstPtr, TgtPtr, Size, - /*AsyncInfoPtr=*/nullptr); -} - -int32_t GenericPluginTy::data_retrieve_async(int32_t DeviceId, void *HstPtr, - void *TgtPtr, int64_t Size, - __tgt_async_info *AsyncInfoPtr) { - auto Err = - getDevice(DeviceId).dataRetrieve(HstPtr, TgtPtr, Size, AsyncInfoPtr); - if (Err) { - REPORT() << "Failure to copy data from device to host. Pointers: host " - << "= " << HstPtr << ", device = " << TgtPtr << ", size = " << Size - << ": " << toString(std::move(Err)); - return OFFLOAD_FAIL; - } - - return OFFLOAD_SUCCESS; -} - -int32_t GenericPluginTy::data_exchange(int32_t SrcDeviceId, void *SrcPtr, - int32_t DstDeviceId, void *DstPtr, - int64_t Size) { - return data_exchange_async(SrcDeviceId, SrcPtr, DstDeviceId, DstPtr, Size, - /*AsyncInfoPtr=*/nullptr); -} - -int32_t GenericPluginTy::data_exchange_async(int32_t SrcDeviceId, void *SrcPtr, - int DstDeviceId, void *DstPtr, - int64_t Size, - __tgt_async_info *AsyncInfo) { - GenericDeviceTy &SrcDevice = getDevice(SrcDeviceId); - GenericDeviceTy &DstDevice = getDevice(DstDeviceId); - auto Err = SrcDevice.dataExchange(SrcPtr, DstDevice, DstPtr, Size, AsyncInfo); - if (Err) { - REPORT() << "Failure to copy data from device (" << SrcDeviceId - << ") to device (" << DstDeviceId - << "). Pointers: host = " << SrcPtr << ", device = " << DstPtr - << ", size = " << Size << ": " << toString(std::move(Err)); - return OFFLOAD_FAIL; - } - - return OFFLOAD_SUCCESS; -} - int32_t GenericPluginTy::launch_kernel(int32_t DeviceId, void *TgtEntryPtr, KernelLaunchArgsTy &LaunchArgs, __tgt_async_info *AsyncInfoPtr) { @@ -1427,30 +1361,6 @@ int32_t GenericPluginTy::launch_kernel(int32_t DeviceId, void *TgtEntryPtr, return OFFLOAD_SUCCESS; } -int32_t GenericPluginTy::synchronize(int32_t DeviceId, - __tgt_async_info *AsyncInfoPtr) { - auto Err = getDevice(DeviceId).synchronize(AsyncInfoPtr); - if (Err) { - REPORT() << "Failure to synchronize stream " << AsyncInfoPtr->Queue << ": " - << toString(std::move(Err)); - return OFFLOAD_FAIL; - } - - return OFFLOAD_SUCCESS; -} - -int32_t GenericPluginTy::query_async(int32_t DeviceId, - __tgt_async_info *AsyncInfoPtr) { - auto Err = getDevice(DeviceId).queryAsync(AsyncInfoPtr); - if (Err) { - REPORT() << "Failure to query stream " << AsyncInfoPtr->Queue << ": " - << toString(std::move(Err)); - return OFFLOAD_FAIL; - } - - return OFFLOAD_SUCCESS; -} - InfoTreeNode GenericPluginTy::obtain_device_info(int32_t DeviceId) { auto InfoOrErr = getDevice(DeviceId).obtainInfo(); if (auto Err = InfoOrErr.takeError()) { diff --git a/offload/tools/kernelreplay/CMakeLists.txt b/offload/tools/kernelreplay/CMakeLists.txt index c789c8ff018593..e4e359cdf5ff79 100644 --- a/offload/tools/kernelreplay/CMakeLists.txt +++ b/offload/tools/kernelreplay/CMakeLists.txt @@ -6,6 +6,7 @@ add_offload_tool(llvm-omp-kernel-replay llvm-omp-kernel-replay.cpp target_include_directories(llvm-omp-kernel-replay PRIVATE ${LIBOMPTARGET_INCLUDE_DIR} + ${CMAKE_CURRENT_BINARY_DIR}/../../liboffload/API ) target_link_libraries(llvm-omp-kernel-replay PRIVATE omp >From 0572ceedcc60fb20f33cbd77beaf067788098a37 Mon Sep 17 00:00:00 2001 From: "Duran, Alex" <[email protected]> Date: Tue, 8 Sep 2026 03:13:36 -0700 Subject: [PATCH 6/7] Remove isDataExchangable and any associated code Rename helper --- offload/include/device.h | 3 --- offload/include/omptarget.h | 4 ++-- offload/liboffload/src/OffloadImpl.cpp | 2 +- offload/libompaccsupport/PluginManager.cpp | 3 --- offload/libompaccsupport/device.cpp | 10 ---------- .../plugins-nextgen/common/include/PluginInterface.h | 3 --- offload/plugins-nextgen/common/src/PluginInterface.cpp | 5 ----- 7 files changed, 3 insertions(+), 27 deletions(-) diff --git a/offload/include/device.h b/offload/include/device.h index 0488fedb616e65..d848d21ae74e13 100644 --- a/offload/include/device.h +++ b/offload/include/device.h @@ -143,9 +143,6 @@ struct DeviceTy { HostDataToTargetTy *Entry = nullptr, MappingInfoTy::HDTTMapAccessorTy *HDTTMapPtr = nullptr); - // Return true if data can be copied to DstDevice directly - bool isDataExchangable(const DeviceTy &DstDevice); - // Copy data from current device to destination device directly int32_t dataExchange(void *SrcPtr, DeviceTy &DstDev, void *DstPtr, int64_t Size, AsyncInfoTy &AsyncInfo); diff --git a/offload/include/omptarget.h b/offload/include/omptarget.h index 5299b7eabe4b5d..f833e3f7ffbb29 100644 --- a/offload/include/omptarget.h +++ b/offload/include/omptarget.h @@ -117,7 +117,7 @@ struct DeviceTy; // temporary helper from liboffload until all usage of AsyncInfo // are migrated to use liboffload queues. extern "C" __tgt_async_info * -__ol__tgt_GetAsyncInfoFromQueue(ol_queue_handle_t Queue); +__ol_tgt_GetAsyncInfoFromQueue(ol_queue_handle_t Queue); /// The libomptarget wrapper around a __tgt_async_info object directly /// associated with a libomptarget layer device. RAII semantics to avoid @@ -150,7 +150,7 @@ class AsyncInfoTy { /// Implicit conversion to the __tgt_async_info which is used in the /// plugin interface. operator __tgt_async_info *() { - return __ol__tgt_GetAsyncInfoFromQueue(Queue); + return __ol_tgt_GetAsyncInfoFromQueue(Queue); } /// Get the underlying queue handle. diff --git a/offload/liboffload/src/OffloadImpl.cpp b/offload/liboffload/src/OffloadImpl.cpp index 7132d71a7e18f3..8e4b129706b5ea 100644 --- a/offload/liboffload/src/OffloadImpl.cpp +++ b/offload/liboffload/src/OffloadImpl.cpp @@ -1535,7 +1535,7 @@ int32_t __ol_tgt_GetPluginDeviceId(ol_device_handle_t Device) { } // namespace tmp extern "C" __tgt_async_info * -__ol__tgt_GetAsyncInfoFromQueue(ol_queue_handle_t Queue) { +__ol_tgt_GetAsyncInfoFromQueue(ol_queue_handle_t Queue) { return Queue->AsyncInfo; } diff --git a/offload/libompaccsupport/PluginManager.cpp b/offload/libompaccsupport/PluginManager.cpp index 1de5c0663681d2..90d08d41382762 100644 --- a/offload/libompaccsupport/PluginManager.cpp +++ b/offload/libompaccsupport/PluginManager.cpp @@ -105,9 +105,6 @@ ol_device_handle_t PluginManager::getHostDevice() { &Backend); if (Backend == OL_PLATFORM_BACKEND_HOST) { - GenericPluginTy *HostPlugin = - __ol_tgt_GetPluginFromPlatform(Platform); - HostPlugin->set_device_identifier(omp_initial_device, 0); *(static_cast<ol_device_handle_t *>(Data)) = D; return false; } diff --git a/offload/libompaccsupport/device.cpp b/offload/libompaccsupport/device.cpp index 4dbc2351abf4f7..d0bfe383681524 100644 --- a/offload/libompaccsupport/device.cpp +++ b/offload/libompaccsupport/device.cpp @@ -907,16 +907,6 @@ bool DeviceTy::printDeviceInfo() { return true; } -// Whether data can be copied to DstDevice directly -bool DeviceTy::isDataExchangable(const DeviceTy &DstDevice) { - if (RTL != DstDevice.RTL) - return false; - - if (RTL->is_data_exchangable(RTLDeviceID, DstDevice.RTLDeviceID)) - return true; - return false; -} - int32_t DeviceTy::synchronize(AsyncInfoTy &AsyncInfo) { ol_queue_handle_t Queue = AsyncInfo.getQueue(); if (!Queue) diff --git a/offload/plugins-nextgen/common/include/PluginInterface.h b/offload/plugins-nextgen/common/include/PluginInterface.h index 60495495248dc4..f702e338441aa6 100644 --- a/offload/plugins-nextgen/common/include/PluginInterface.h +++ b/offload/plugins-nextgen/common/include/PluginInterface.h @@ -1647,9 +1647,6 @@ struct GenericPluginTy { /// Return the number of devices this plugin can support. int32_t number_of_devices(); - /// Returns non-zero if the data can be exchanged between the two devices. - int32_t is_data_exchangable(int32_t SrcDeviceId, int32_t DstDeviceId); - /// Initializes the record and replay mechanism inside the plugin. int32_t initialize_record_replay(int32_t DeviceId, int64_t MemorySize, void *VAddr, bool IsRecord, bool IsNative, diff --git a/offload/plugins-nextgen/common/src/PluginInterface.cpp b/offload/plugins-nextgen/common/src/PluginInterface.cpp index 8404f8bceacdac..f8290acab83330 100644 --- a/offload/plugins-nextgen/common/src/PluginInterface.cpp +++ b/offload/plugins-nextgen/common/src/PluginInterface.cpp @@ -1221,11 +1221,6 @@ int32_t GenericPluginTy::isDeviceCompatible(int32_t DeviceId, StringRef Image) { int32_t GenericPluginTy::number_of_devices() { return getNumDevices(); } -int32_t GenericPluginTy::is_data_exchangable(int32_t SrcDeviceId, - int32_t DstDeviceId) { - return isDataExchangable(SrcDeviceId, DstDeviceId); -} - int32_t GenericPluginTy::initialize_record_replay( int32_t DeviceId, int64_t MemorySize, void *VAddr, bool IsRecord, bool IsNative, bool SaveOutput, bool EmitReport, const char *ReportFilename, >From 772de766637892a459c5e7c3af215846169a5e67 Mon Sep 17 00:00:00 2001 From: "Duran, Alex" <[email protected]> Date: Mon, 7 Sep 2026 08:27:58 -0700 Subject: [PATCH 7/7] [offload][omp] Manage events through liboffload --- offload/include/device.h | 9 +-- offload/libompaccsupport/device.cpp | 53 +++++++++----- .../common/include/PluginInterface.h | 21 ------ .../common/src/PluginInterface.cpp | 73 ------------------- 4 files changed, 39 insertions(+), 117 deletions(-) diff --git a/offload/include/device.h b/offload/include/device.h index d848d21ae74e13..68b9c25cd9eb92 100644 --- a/offload/include/device.h +++ b/offload/include/device.h @@ -180,12 +180,11 @@ struct DeviceTy { /// Event related interfaces. /// { - /// Create an event. - int32_t createEvent(void **Event); - /// Record the event based on status in AsyncInfo->Queue at the moment the - /// function is called. - int32_t recordEvent(void *Event, AsyncInfoTy &AsyncInfo); + /// function is called. If \p Event already holds an event, it is replaced + /// with a new one representing the current queue state and the old event + /// is destroyed. + int32_t recordEvent(void **Event, AsyncInfoTy &AsyncInfo); /// Wait for an event. This function can be blocking or non-blocking, /// depending on the implementation. It is expected to set a dependence on the diff --git a/offload/libompaccsupport/device.cpp b/offload/libompaccsupport/device.cpp index d0bfe383681524..add6e1a267ac89 100644 --- a/offload/libompaccsupport/device.cpp +++ b/offload/libompaccsupport/device.cpp @@ -49,23 +49,16 @@ int HostDataToTargetTy::addEventIfNecessary(DeviceTy &Device, if (!MappingConfig::get().UseEventsForAtomicTransfers) return OFFLOAD_SUCCESS; - void *Event = getEvent(); - bool NeedNewEvent = Event == nullptr; - if (NeedNewEvent && Device.createEvent(&Event) != OFFLOAD_SUCCESS) { - REPORT() << "Failed to create event"; - return OFFLOAD_FAIL; - } - // We cannot assume the event should not be nullptr because we don't // know if the target support event. But if a target doesn't, // recordEvent should always return success. - if (Device.recordEvent(Event, AsyncInfo) != OFFLOAD_SUCCESS) { + void *Event = getEvent(); + if (Device.recordEvent(&Event, AsyncInfo) != OFFLOAD_SUCCESS) { REPORT() << "Failed to set dependence on event " << Event; return OFFLOAD_FAIL; } - if (NeedNewEvent) - setEvent(Event); + setEvent(Event); return OFFLOAD_SUCCESS; } @@ -932,24 +925,48 @@ int32_t DeviceTy::queryAsync(AsyncInfoTy &AsyncInfo) { return OFFLOAD_SUCCESS; } -int32_t DeviceTy::createEvent(void **Event) { - return RTL->create_event(RTLDeviceID, Event); -} +int32_t DeviceTy::recordEvent(void **Event, AsyncInfoTy &AsyncInfo) { + ol_event_handle_t NewEvent; + if (auto Res = + olCreateEvent(AsyncInfo.getQueue(), OL_EVENT_FLAGS_NONE, &NewEvent)) { + REPORT() << "Failure to record event: " << Res->Details; + return OFFLOAD_FAIL; + } -int32_t DeviceTy::recordEvent(void *Event, AsyncInfoTy &AsyncInfo) { - return RTL->record_event(RTLDeviceID, Event, AsyncInfo); + if (*Event) { + if (auto Res = olDestroyEvent(static_cast<ol_event_handle_t>(*Event))) + REPORT() << "Failure to destroy previous event " << *Event << ": " + << Res->Details; + } + + *Event = NewEvent; + return OFFLOAD_SUCCESS; } int32_t DeviceTy::waitEvent(void *Event, AsyncInfoTy &AsyncInfo) { - return RTL->wait_event(RTLDeviceID, Event, AsyncInfo); + ol_event_handle_t E = static_cast<ol_event_handle_t>(Event); + if (auto Res = olWaitEvents(AsyncInfo.getQueue(), &E, 1)) { + REPORT() << "Failure to wait for event " << Event << ": " << Res->Details; + return OFFLOAD_FAIL; + } + return OFFLOAD_SUCCESS; } int32_t DeviceTy::syncEvent(void *Event) { - return RTL->sync_event(RTLDeviceID, Event); + if (auto Res = olSyncEvent(static_cast<ol_event_handle_t>(Event))) { + REPORT() << "Failure to synchronize event " << Event << ": " + << Res->Details; + return OFFLOAD_FAIL; + } + return OFFLOAD_SUCCESS; } int32_t DeviceTy::destroyEvent(void *Event) { - return RTL->destroy_event(RTLDeviceID, Event); + if (auto Res = olDestroyEvent(static_cast<ol_event_handle_t>(Event))) { + REPORT() << "Failure to destroy event " << Event << ": " << Res->Details; + return OFFLOAD_FAIL; + } + return OFFLOAD_SUCCESS; } void DeviceTy::dumpOffloadEntries() { diff --git a/offload/plugins-nextgen/common/include/PluginInterface.h b/offload/plugins-nextgen/common/include/PluginInterface.h index f702e338441aa6..7176a932d1ff17 100644 --- a/offload/plugins-nextgen/common/include/PluginInterface.h +++ b/offload/plugins-nextgen/common/include/PluginInterface.h @@ -1692,27 +1692,6 @@ struct GenericPluginTy { /// Prints information about the given devices supported by the plugin. void print_device_info(int32_t DeviceId); - /// Creates an event in the given plugin if supported. - int32_t create_event(int32_t DeviceId, void **EventPtr); - - /// Records an event that has occurred. - int32_t record_event(int32_t DeviceId, void *EventPtr, - __tgt_async_info *AsyncInfoPtr); - - /// Wait until an event has occurred. - int32_t wait_event(int32_t DeviceId, void *EventPtr, - __tgt_async_info *AsyncInfoPtr); - - /// Synchronize execution until an event is done. - int32_t sync_event(int32_t DeviceId, void *EventPtr); - - /// Get the elapsed time in milliseconds between two events. - int32_t get_event_elapsed_time(int32_t DeviceId, void *StartEventPtr, - void *EndEventPtr, float *ElapsedTime); - - /// Remove the event from the plugin. - int32_t destroy_event(int32_t DeviceId, void *EventPtr); - /// Remove the event from the plugin. void set_info_flag(uint32_t NewInfoLevel); diff --git a/offload/plugins-nextgen/common/src/PluginInterface.cpp b/offload/plugins-nextgen/common/src/PluginInterface.cpp index f8290acab83330..bd8ba6a6bdc64d 100644 --- a/offload/plugins-nextgen/common/src/PluginInterface.cpp +++ b/offload/plugins-nextgen/common/src/PluginInterface.cpp @@ -1372,79 +1372,6 @@ void GenericPluginTy::print_device_info(int32_t DeviceId) { << " info: " << toString(std::move(Err)); } -int32_t GenericPluginTy::create_event(int32_t DeviceId, void **EventPtr) { - auto Err = getDevice(DeviceId).createEvent(EventPtr); - if (Err) { - REPORT() << "Failure to create event: " << toString(std::move(Err)); - return OFFLOAD_FAIL; - } - - return OFFLOAD_SUCCESS; -} - -int32_t GenericPluginTy::record_event(int32_t DeviceId, void *EventPtr, - __tgt_async_info *AsyncInfoPtr) { - auto Err = getDevice(DeviceId).recordEvent(EventPtr, AsyncInfoPtr); - if (Err) { - REPORT() << "Failure to record event " << EventPtr << ": " - << toString(std::move(Err)); - return OFFLOAD_FAIL; - } - - return OFFLOAD_SUCCESS; -} - -int32_t GenericPluginTy::wait_event(int32_t DeviceId, void *EventPtr, - __tgt_async_info *AsyncInfoPtr) { - auto Err = getDevice(DeviceId).waitEvent(EventPtr, AsyncInfoPtr); - if (Err) { - REPORT() << "Failure to wait event " << EventPtr << ": " - << toString(std::move(Err)); - return OFFLOAD_FAIL; - } - - return OFFLOAD_SUCCESS; -} - -int32_t GenericPluginTy::sync_event(int32_t DeviceId, void *EventPtr) { - auto Err = getDevice(DeviceId).syncEvent(EventPtr); - if (Err) { - REPORT() << "Failure to synchronize event " << EventPtr << ": " - << toString(std::move(Err)); - return OFFLOAD_FAIL; - } - - return OFFLOAD_SUCCESS; -} - -int32_t GenericPluginTy::get_event_elapsed_time(int32_t DeviceId, - void *StartEventPtr, - void *EndEventPtr, - float *ElapsedTime) { - auto ElapsedTimeOrErr = - getDevice(DeviceId).getEventElapsedTime(StartEventPtr, EndEventPtr); - if (!ElapsedTimeOrErr) { - REPORT() << "Failure to get elapsed time between events " << StartEventPtr - << " and " << EndEventPtr << ": " - << toString(ElapsedTimeOrErr.takeError()); - return OFFLOAD_FAIL; - } - - *ElapsedTime = *ElapsedTimeOrErr; - return OFFLOAD_SUCCESS; -} - -int32_t GenericPluginTy::destroy_event(int32_t DeviceId, void *EventPtr) { - auto Err = getDevice(DeviceId).destroyEvent(EventPtr); - if (Err) { - REPORT() << "Failure to destroy event " << EventPtr << ": " - << toString(std::move(Err)); - return OFFLOAD_FAIL; - } - - return OFFLOAD_SUCCESS; -} - void GenericPluginTy::set_info_flag(uint32_t NewInfoLevel) { std::atomic<uint32_t> &InfoLevel = getInfoLevelInternal(); InfoLevel.store(NewInfoLevel); _______________________________________________ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
