[llvm] [OFFLOAD] Add missing API for libomptarget migration (PR #171009)

via llvm-commits llvm-commits at lists.llvm.org
Sat Dec 6 20:20:08 PST 2025


https://github.com/fineg74 updated https://github.com/llvm/llvm-project/pull/171009

>From 6b718b239a051ae8791c074b5c499b0f7ec1ea7d Mon Sep 17 00:00:00 2001
From: "Fine, Gregory" <gregory.fine at intel.com>
Date: Thu, 20 Nov 2025 23:10:45 -0800
Subject: [PATCH] Add missing API for libomptarget migration

---
 offload/liboffload/API/Device.td       |  77 ++++++++++++++++
 offload/liboffload/API/Memory.td       |  47 ++++++++++
 offload/liboffload/API/Platform.td     |   4 +-
 offload/liboffload/API/Queue.td        |  18 ++++
 offload/liboffload/src/OffloadImpl.cpp | 119 +++++++++++++++++++++++++
 5 files changed, 264 insertions(+), 1 deletion(-)

diff --git a/offload/liboffload/API/Device.td b/offload/liboffload/API/Device.td
index 6ada191089674..6d15f5c633a41 100644
--- a/offload/liboffload/API/Device.td
+++ b/offload/liboffload/API/Device.td
@@ -44,6 +44,8 @@ def ol_device_info_t : Enum {
     TaggedEtor<"MAX_MEM_ALLOC_SIZE", "uint64_t", "The maximum size of memory object allocation in bytes">,
     TaggedEtor<"GLOBAL_MEM_SIZE", "uint64_t", "The size of global device memory in bytes">,
     TaggedEtor<"WORK_GROUP_LOCAL_MEM_SIZE", "uint64_t", "The maximum size of local shared memory per work group in bytes">,
+    TaggedEtor<"ID", "int32_t", "Device ID">,
+    TaggedEtor<"USE_AUTO_ZERO_COPY", "bool", "Use Auto Zero Copy">,
   ];
   list<TaggedEtor> fp_configs = !foreach(type, ["Single", "Double", "Half"], TaggedEtor<type # "_FP_CONFIG", "ol_device_fp_capability_flags_t", type # " precision floating point capability">);
   list<TaggedEtor> native_vec_widths = !foreach(type, ["char","short","int","long","float","double","half"], TaggedEtor<"NATIVE_VECTOR_WIDTH_" # type, "uint32_t", "Native vector width for " # type>);
@@ -131,3 +133,78 @@ def olGetDeviceInfoSize : Function {
     Return<"OL_ERRC_INVALID_DEVICE">
   ];
 }
+
+def olCreateInterop : Function {
+  let desc = "Create OpenMP interop with the given interop context.";
+  let params = [
+    Param<"ol_device_handle_t", "Device", "handle of the device", PARAM_IN>,
+    Param<"int32_t", "InteropContext", "Interop Context", PARAM_IN>,
+    Param<"void *", "InteropSpec", "Interop Spec", PARAM_IN>,
+    Param<"void**", "Interop", "output for the interop", PARAM_OUT>
+  ];
+  let returns = [];
+}
+
+def olReleaseInterop : Function {
+  let desc = "Release OpenMP interop object.";
+  let params = [
+    Param<"ol_device_handle_t", "Device", "handle of the device", PARAM_IN>,
+    Param<"void *", "InteropSpec", "Interop Context", PARAM_IN>
+  ];
+  let returns = [];
+}
+
+def olSelectInterop : Function {
+  let desc = "Return OpenMP interop object that the device supports";
+  let params = [
+    Param<"ol_device_handle_t", "Device", "handle of the device", PARAM_IN>,
+    Param<"int32_t", "InteropType", "Interop Context", PARAM_IN>,
+    Param<"int32_t", "InteropPreferencesSize", "Interop Context", PARAM_IN>,
+    Param<"void*", "InteropPreferences", "Interop Context", PARAM_IN>,
+    Param<"void*", "InteropSpec", "output for the interop", PARAM_OUT>
+  ];
+  let returns = [];
+}
+
+def olFlushQueueInterop : Function {
+    let desc = "Flush the queue associated with the interop object if necessary.";
+    let details = [];
+    let params = [
+      Param<"ol_device_handle_t", "Device", "handle of the device", PARAM_IN>,
+      Param<"void *", "Interop", "Interop", PARAM_IN>
+    ];
+    let returns = [];
+}
+
+def olSyncBarrierInterop : Function {
+    let desc = "Perform a host synchronization with the queue associated with the interop object and wait for it to complete.";
+    let details = [];
+    let params = [
+      Param<"ol_device_handle_t", "Device", "handle of the device", PARAM_IN>,
+      Param<"void *", "Interop", "Interop", PARAM_IN>
+    ];
+    let returns = [];
+}
+
+def olAsyncBarrierInterop : Function {
+    let desc = "Queue an asynchronous barrier in the queue associated with the interop object and return immediately.";
+    let details = [];
+    let params = [
+      Param<"ol_device_handle_t", "Device", "handle of the device", PARAM_IN>,
+      Param<"void *", "Interop", "Interop", PARAM_IN>
+    ];
+    let returns = [];
+}
+
+def olInitializeRecordReplay : Function {
+  let desc = "Initializes the record and replay mechanism.";
+  let params = [
+    Param<"ol_device_handle_t", "Device", "handle of the device", PARAM_IN>,
+    Param<"uint64_t", "MemorySize", " The number of bytes to be (pre-)allocated by the bump allocator", PARAM_IN>,
+    Param<"void *", "VAddr", "handle of the destination device", PARAM_IN>,
+    Param<"bool", "IsRecord", "Activates the record replay mechanism in 'record' mode or 'replay' mode", PARAM_IN>,
+    Param<"bool", "SaveOutput", "Store the device memory after kernel execution on persistent storage", PARAM_IN>,
+    Param<"uint64_t *", "ReqPtrArgOffset", "handle of the destination device", PARAM_OUT>,
+  ];
+  let returns = [];
+}
diff --git a/offload/liboffload/API/Memory.td b/offload/liboffload/API/Memory.td
index 79e8038330048..9c0a84304bf9a 100644
--- a/offload/liboffload/API/Memory.td
+++ b/offload/liboffload/API/Memory.td
@@ -131,3 +131,50 @@ def olMemFill : Function {
     Return<"OL_ERRC_INVALID_SIZE", ["`FillSize % PatternSize != 0`"]>
   ];
 }
+
+def olMemDataMappedNotify : Function {
+  let desc = "Notifies device about mapping of memory block.";
+  let params = [
+    Param<"ol_device_handle_t", "Device", "handle of the device to allocate on", PARAM_IN>,
+    Param<"void *", "Ptr", "Host Pointer", PARAM_IN>,
+    Param<"size_t", "Size", "size of the allocation in bytes", PARAM_IN>
+  ];
+  let returns = [
+    Return<"OL_ERRC_INVALID_SIZE", [
+      "`Size == 0`"
+    ]>
+  ];
+}
+
+def olMemDataUnMappedNotify : Function {
+  let desc = "Notifies device about unmapping of memory block.";
+  let params = [
+    Param<"ol_device_handle_t", "Device", "handle of the device to allocate on", PARAM_IN>,
+    Param<"void *", "Ptr", "Host Pointer", PARAM_IN>
+  ];
+  let returns = [];
+}
+
+def olMemDataLock : Function {
+  let desc = "Locks / pins host memory using the plugin runtime.";
+  let params = [
+    Param<"ol_device_handle_t", "Device", "handle of the device to allocate on", PARAM_IN>,
+    Param<"void *", "Ptr", "Host Pointer", PARAM_IN>,
+    Param<"size_t", "Size", "size of the allocation in bytes", PARAM_IN>,
+    Param<"void**", "LockedPtr", "output for the allocated pointer", PARAM_OUT>
+  ];
+  let returns = [
+    Return<"OL_ERRC_INVALID_SIZE", [
+      "`Size == 0`"
+    ]>
+  ];
+}
+
+def olMemDataUnLock : Function {
+  let desc = "Unlocks / unpins host memory using the plugin runtime.";
+  let params = [
+    Param<"ol_device_handle_t", "Device", "handle of the device to allocate on", PARAM_IN>,
+    Param<"void *", "Ptr", "Host Pointer", PARAM_IN>
+  ];
+  let returns = [];
+}
diff --git a/offload/liboffload/API/Platform.td b/offload/liboffload/API/Platform.td
index 906f899076a80..ef0b9e680fb0d 100644
--- a/offload/liboffload/API/Platform.td
+++ b/offload/liboffload/API/Platform.td
@@ -17,7 +17,9 @@ def ol_platform_info_t : Enum {
     TaggedEtor<"NAME", "char[]", "The string denoting name of the platform. The size of the info needs to be dynamically queried.">,
     TaggedEtor<"VENDOR_NAME", "char[]", "The string denoting name of the vendor of the platform. The size of the info needs to be dynamically queried.">,
     TaggedEtor<"VERSION", "char[]", "The string denoting the version of the platform. The size of the info needs to be dynamically queried.">,
-    TaggedEtor<"BACKEND", "ol_platform_backend_t", "The native backend of the platform.">
+    TaggedEtor<"BACKEND", "ol_platform_backend_t", "The native backend of the platform.">,
+    TaggedEtor<"IS_INITIALIZED", "bool", "Is platform initialized.">,
+    TaggedEtor<"NUMBER_OF_DEVICES", "int32_t", "Number of devices.">
   ];
 }
 
diff --git a/offload/liboffload/API/Queue.td b/offload/liboffload/API/Queue.td
index ededa9cc92fef..bb557cfa635e6 100644
--- a/offload/liboffload/API/Queue.td
+++ b/offload/liboffload/API/Queue.td
@@ -125,3 +125,21 @@ def olLaunchHostFunction : Function {
   ];
   let returns = [];
 }
+
+def olDataFence : Function {
+    let desc = "Insert a data fence between previous data operations and the following operations if necessary for the device.";
+    let details = [];
+    let params = [
+        Param<"ol_queue_handle_t", "Queue", "handle of the queue", PARAM_IN>
+    ];
+    let returns = [];
+}
+
+def olQueryAsync : Function {
+    let desc = "Query for device/queue/event based completion on in a non-blocking manner.";
+    let details = [];
+    let params = [
+        Param<"ol_queue_handle_t", "Queue", "handle of the queue", PARAM_IN>
+    ];
+    let returns = [];
+}
\ No newline at end of file
diff --git a/offload/liboffload/src/OffloadImpl.cpp b/offload/liboffload/src/OffloadImpl.cpp
index eab9627217ca8..27c57232b3bd0 100644
--- a/offload/liboffload/src/OffloadImpl.cpp
+++ b/offload/liboffload/src/OffloadImpl.cpp
@@ -367,6 +367,12 @@ Error olGetPlatformInfoImplDetail(ol_platform_handle_t Platform,
   case OL_PLATFORM_INFO_BACKEND: {
     return Info.write<ol_platform_backend_t>(Platform->BackendType);
   }
+  case OL_PLATFORM_INFO_IS_INITIALIZED: {
+    return Info.write<bool>(Platform->Plugin->is_initialized());
+  }
+  case OL_PLATFORM_INFO_NUMBER_OF_DEVICES: {
+    return Info.write<int32_t>(Platform->Plugin->number_of_devices());
+  }
   default:
     return createOffloadError(ErrorCode::INVALID_ENUMERATION,
                               "getPlatformInfo enum '%i' is invalid", PropName);
@@ -449,6 +455,11 @@ Error olGetDeviceInfoImplDetail(ol_device_handle_t Device,
     return Info.write<uint64_t>(Mem);
   } break;
 
+  case OL_DEVICE_INFO_ID:
+    return Info.write<int32_t>(Device->DeviceNum);
+  case OL_DEVICE_INFO_USE_AUTO_ZERO_COPY:
+    return Info.write<bool>(Device->Device->useAutoZeroCopy());
+
   default:
     break;
   }
@@ -599,6 +610,10 @@ Error olGetDeviceInfoImplDetailHost(ol_device_handle_t Device,
   case OL_DEVICE_INFO_GLOBAL_MEM_SIZE:
   case OL_DEVICE_INFO_WORK_GROUP_LOCAL_MEM_SIZE:
     return Info.write<uint64_t>(0);
+  case OL_DEVICE_INFO_ID:
+    return Info.write<int32_t>(Device->DeviceNum);
+  case OL_DEVICE_INFO_USE_AUTO_ZERO_COPY:
+    return Info.write<bool>(Device->Device->useAutoZeroCopy());
   default:
     return createOffloadError(ErrorCode::INVALID_ENUMERATION,
                               "getDeviceInfo enum '%i' is invalid", PropName);
@@ -1214,5 +1229,109 @@ Error olLaunchHostFunction_impl(ol_queue_handle_t Queue,
                                                 Queue->AsyncInfo);
 }
 
+Error olDataFence_impl(ol_queue_handle_t Queue) {
+  if (Queue->AsyncInfo->Queue) {
+    if (auto Err = Queue->Device->Device->dataFence(Queue->AsyncInfo))
+      return Err; 
+  }
+
+  return Error::success();
+}
+
+Error olQueryAsync_impl(ol_queue_handle_t Queue) {
+  if (Queue->AsyncInfo->Queue) {
+    if (auto Err = Queue->Device->Device->queryAsync(Queue->AsyncInfo))
+      return Err; 
+  }
+
+  return Error::success();
+}
+
+Error olMemDataMappedNotify_impl(ol_device_handle_t Device, void *Ptr, size_t Size) {
+  return Device->Device->notifyDataMapped(Ptr, Size);
+}
+
+Error olMemDataUnMappedNotify_impl(ol_device_handle_t Device, void *Ptr) {
+  return Device->Device->notifyDataUnmapped(Ptr);
+}
+
+Error olMemDataLock_impl(ol_device_handle_t Device, void *Ptr, size_t Size, void** LockedPtr) {
+  Expected<void*> LockedPtrOrErr = Device->Device->dataLock(Ptr, Size);
+  if (!LockedPtrOrErr)
+    return LockedPtrOrErr.takeError();
+
+  *LockedPtr = *LockedPtrOrErr;
+
+  return Error::success();
+}
+
+Error olMemDataUnLock_impl(ol_device_handle_t Device, void *Ptr) {
+  return Device->Device->dataUnlock(Ptr);
+}
+
+Error olCreateInterop_impl(ol_device_handle_t Device, int32_t InteropContext, void* InteropSpec, void **Interop) {
+  auto Rc = Device->Device->createInterop(InteropContext, *(interop_spec_t *)InteropSpec);
+  if (!Rc)
+    return Rc.takeError();
+  *Interop = *Rc;
+  return Error::success();
+}
+
+Error olReleaseInterop_impl(ol_device_handle_t Device, void* InteropSpec) {
+  auto Rc = Device->Device->releaseInterop((omp_interop_val_t *)InteropSpec);
+  if (Rc)
+    return Rc;
+  return Error::success();
+}
+
+Error olSelectInterop_impl(ol_device_handle_t Device, int32_t InteropType, int32_t InteropPreferencesSize, 
+        void *InteropPreferences, void* InteropSpec) {
+  *(interop_spec_t*)InteropSpec = Device->Device->selectInteropPreference(
+      InteropType, InteropPreferencesSize, (interop_spec_t *)InteropPreferences);
+  return Error::success();
+}
+
+Error olFlushQueueInterop_impl(ol_device_handle_t Device, void *Interop) {
+
+  Expected<int32_t> Rc = Device->Device->Plugin.flush_queue((omp_interop_val_t *)Interop);
+  if (Rc){
+    return Rc.takeError();
+  }
+  return Error::success();
+}
+
+Error olSyncBarrierInterop_impl(ol_device_handle_t Device, void *Interop) {
+
+  Expected<int32_t> Rc = Device->Device->Plugin.sync_barrier((omp_interop_val_t *)Interop);
+  if (Rc){
+    return Rc.takeError();
+  }
+  return Error::success();
+}
+
+Error olAsyncBarrierInterop_impl(ol_device_handle_t Device, void *Interop) {
+
+  Expected<int32_t> Rc = Device->Device->Plugin.async_barrier((omp_interop_val_t *)Interop);
+  if (Rc){
+    return Rc.takeError();
+  }
+  return Error::success();
+}
+
+Error olInitializeRecordReplay_impl(ol_device_handle_t Device, uint64_t MemorySize,
+                                        void *VAddr, bool IsRecord,
+                                        bool SaveOutput,
+                                        uint64_t *ReqPtrArgOffset){
+  uint64_t ReqPtrArgOffsetOut = 0;
+  Expected<int> Rc = Device->Device->Plugin.initialize_record_replay(Device->DeviceNum, MemorySize,
+                                              VAddr, IsRecord, SaveOutput,
+                                              ReqPtrArgOffsetOut);
+  if (Rc){
+    return Rc.takeError();
+  }
+  *ReqPtrArgOffset = ReqPtrArgOffsetOut;
+  return Error::success();
+}
+
 } // namespace offload
 } // namespace llvm



More information about the llvm-commits mailing list