[llvm-branch-commits] [llvm] [offload][omp] Route data memory operations through liboffload (PR #226443)

Alex Duran via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Fri Sep 25 07:59:49 PDT 2026


https://github.com/adurang updated https://github.com/llvm/llvm-project/pull/226443

>From 2fdaa72961ab4f946f29df8915ad7ac455cef9c6 Mon Sep 17 00:00:00 2001
From: "Duran, Alex" <alejandro.duran at intel.com>
Date: Mon, 7 Sep 2026 03:26:53 -0700
Subject: [PATCH 1/2] [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           | 84 +++++++++++++----
 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, 179 insertions(+), 175 deletions(-)

diff --git a/offload/include/PluginManager.h b/offload/include/PluginManager.h
index 36b8f7d3c914ba..75c7b5e9f70eda 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;
@@ -179,6 +181,10 @@ 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);
+
+  // Platform and device handles for host device operations.
+  ol_platform_handle_t HostPlatform = nullptr;
+  ol_device_handle_t HostDevice = nullptr;
 };
 
 /// Initialize the plugin manager and OpenMP runtime.
diff --git a/offload/include/device.h b/offload/include/device.h
index ff6e18d66f335c..a7293013e0dafc 100644
--- a/offload/include/device.h
+++ b/offload/include/device.h
@@ -50,6 +50,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);
@@ -62,6 +63,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 a39b9c68a73256..5ce87f3db88c1e 100644
--- a/offload/liboffload/src/OffloadImpl.cpp
+++ b/offload/liboffload/src/OffloadImpl.cpp
@@ -1527,5 +1527,10 @@ extern "C" int32_t __ol_tgt_GetPluginDeviceId(ol_device_handle_t Device) {
   return Device->DeviceNum;
 }
 
+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 c5d06bce8a654f..796fc8d39e42f6 100644
--- a/offload/libompaccsupport/PluginManager.cpp
+++ b/offload/libompaccsupport/PluginManager.cpp
@@ -53,6 +53,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))
@@ -65,11 +70,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 Res = olShutDown())
@@ -78,6 +87,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();
@@ -472,11 +508,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) != OFFLOAD_SUCCESS)
diff --git a/offload/libompaccsupport/device.cpp b/offload/libompaccsupport/device.cpp
index 2c2fd60e261274..bb25750de8e050 100644
--- a/offload/libompaccsupport/device.cpp
+++ b/offload/libompaccsupport/device.cpp
@@ -82,11 +82,11 @@ 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);
+  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);
@@ -128,6 +128,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
@@ -308,8 +317,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
@@ -328,8 +347,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
@@ -346,12 +374,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) {
@@ -479,11 +514,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 e20f381b9d5d54..f19aad621f153b 100644
--- a/offload/plugins-nextgen/common/include/PluginInterface.h
+++ b/offload/plugins-nextgen/common/include/PluginInterface.h
@@ -1777,31 +1777,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);
@@ -1811,12 +1786,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 03ddf73ec3aaac..95d5e304051574 100644
--- a/offload/plugins-nextgen/common/src/PluginInterface.cpp
+++ b/offload/plugins-nextgen/common/src/PluginInterface.cpp
@@ -1652,72 +1652,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) {
@@ -1732,30 +1666,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 66c4b2159822ad..d3825ed6801f27 100644
--- a/offload/tools/kernelreplay/CMakeLists.txt
+++ b/offload/tools/kernelreplay/CMakeLists.txt
@@ -6,6 +6,7 @@ llvm_update_compile_flags(llvm-omp-kernel-replay)
 
 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
   LLVMSupport

>From ad48164a114f7a7b488b8143e5e2f159c7a83e09 Mon Sep 17 00:00:00 2001
From: "Duran, Alex" <alejandro.duran at intel.com>
Date: Tue, 8 Sep 2026 03:13:36 -0700
Subject: [PATCH 2/2] 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 a7293013e0dafc..8b656dd681f8a1 100644
--- a/offload/include/device.h
+++ b/offload/include/device.h
@@ -102,9 +102,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 5ce87f3db88c1e..5021ac21227b7c 100644
--- a/offload/liboffload/src/OffloadImpl.cpp
+++ b/offload/liboffload/src/OffloadImpl.cpp
@@ -1528,7 +1528,7 @@ extern "C" int32_t __ol_tgt_GetPluginDeviceId(ol_device_handle_t Device) {
 }
 
 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 796fc8d39e42f6..a820f9f2d9517a 100644
--- a/offload/libompaccsupport/PluginManager.cpp
+++ b/offload/libompaccsupport/PluginManager.cpp
@@ -99,9 +99,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 bb25750de8e050..e4a9ec10d5e3a6 100644
--- a/offload/libompaccsupport/device.cpp
+++ b/offload/libompaccsupport/device.cpp
@@ -503,16 +503,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 f19aad621f153b..5815e2c39f033f 100644
--- a/offload/plugins-nextgen/common/include/PluginInterface.h
+++ b/offload/plugins-nextgen/common/include/PluginInterface.h
@@ -1744,9 +1744,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 95d5e304051574..64cb559cca2469 100644
--- a/offload/plugins-nextgen/common/src/PluginInterface.cpp
+++ b/offload/plugins-nextgen/common/src/PluginInterface.cpp
@@ -1526,11 +1526,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,



More information about the llvm-branch-commits mailing list