[llvm-branch-commits] [llvm] Users/adurango/plugins liboffload (PR #221275)

Alex Duran via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Fri Sep 4 09:18:02 PDT 2026


https://github.com/adurang created https://github.com/llvm/llvm-project/pull/221275

None

>From 9951e27875c24fc8a0d984f1c848bfbe5ed3c55a Mon Sep 17 00:00:00 2001
From: "Duran, Alex" <alejandro.duran at intel.com>
Date: Thu, 3 Sep 2026 10:55:00 -0700
Subject: [PATCH 1/6] [offload][omp] Load plugins through liboffload

---
 offload/include/PluginManager.h            |  3 ++-
 offload/liboffload/exports                 |  2 +-
 offload/liboffload/src/OffloadImpl.cpp     |  5 ++++
 offload/libompaccsupport/PluginManager.cpp | 29 +++++++++++++---------
 4 files changed, 25 insertions(+), 14 deletions(-)

diff --git a/offload/include/PluginManager.h b/offload/include/PluginManager.h
index 6c6fdebe76dff..eea8b62a8c39d 100644
--- a/offload/include/PluginManager.h
+++ b/offload/include/PluginManager.h
@@ -13,6 +13,7 @@
 #ifndef OMPTARGET_PLUGIN_MANAGER_H
 #define OMPTARGET_PLUGIN_MANAGER_H
 
+#include "OffloadAPI.h"
 #include "PluginInterface.h"
 
 #include "DeviceImage.h"
@@ -155,7 +156,7 @@ struct PluginManager {
   llvm::SmallVector<__tgt_bin_desc *> DelayedBinDesc;
 
   // List of all plugins, in use or not.
-  llvm::SmallVector<std::unique_ptr<GenericPluginTy>> Plugins;
+  llvm::SmallVector<GenericPluginTy *> Plugins;
 
   // Mapping of plugins to the OpenMP device identifier.
   llvm::DenseMap<std::pair<const GenericPluginTy *, int32_t>, int32_t>
diff --git a/offload/liboffload/exports b/offload/liboffload/exports
index 5487e16168681..75b1cfd049c82 100644
--- a/offload/liboffload/exports
+++ b/offload/liboffload/exports
@@ -55,9 +55,9 @@ global:
     llvm::omp::target::ompt::Initialized;
     llvm::omp::target::ompt::lookupCallbackByCode;
     llvm::omp::target::ompt::lookupCallbackByName;
-    createPlugin_*;
     # Temporary helpers to help transition of libomptarget to liboffload.
     __ol_tgt_setInfoFlag;
+    __ol_tgt_GetPluginFromPlatform;
   };
 local:
   *;
diff --git a/offload/liboffload/src/OffloadImpl.cpp b/offload/liboffload/src/OffloadImpl.cpp
index e06bd8d445bc3..6e403df9544e3 100644
--- a/offload/liboffload/src/OffloadImpl.cpp
+++ b/offload/liboffload/src/OffloadImpl.cpp
@@ -1633,5 +1633,10 @@ extern "C" void __ol_tgt_setInfoFlag(uint32_t NewInfoLevel) {
   InfoLevel.store(NewInfoLevel);
 }
 
+extern "C" GenericPluginTy *
+__ol_tgt_GetPluginFromPlatform(ol_platform_handle_t Platform) {
+  return Platform->Plugin.get();
+}
+
 } // namespace offload
 } // namespace llvm
diff --git a/offload/libompaccsupport/PluginManager.cpp b/offload/libompaccsupport/PluginManager.cpp
index 41b653a60adfd..b0cb40fb32e8d 100644
--- a/offload/libompaccsupport/PluginManager.cpp
+++ b/offload/libompaccsupport/PluginManager.cpp
@@ -26,9 +26,8 @@ using namespace llvm::omp::target::debug;
 
 PluginManager *PM = nullptr;
 
-// Every plugin exports this method to create an instance of the plugin type.
-#define PLUGIN_TARGET(Name) extern "C" GenericPluginTy *createPlugin_##Name();
-#include "Shared/Targets.def"
+extern "C" GenericPluginTy *
+__ol_tgt_GetPluginFromPlatform(ol_platform_handle_t Platform);
 
 void PluginManager::init() {
   TIMESCOPE();
@@ -38,14 +37,21 @@ void PluginManager::init() {
   }
 
   ODBG(ODT_Init) << "Loading RTLs";
-
-  // Attempt to create an instance of each supported plugin.
-#define PLUGIN_TARGET(Name)                                                    \
-  do {                                                                         \
-    Plugins.emplace_back(                                                      \
-        std::unique_ptr<GenericPluginTy>(createPlugin_##Name()));              \
-  } while (false);
-#include "Shared/Targets.def"
+  if (ol_result_t Res = olInit(nullptr))
+    REPORT() << "Failed to initialize liboffload: " << Res->Details;
+
+  
+  if (ol_result_t Res = olIteratePlatforms(
+          [](ol_platform_handle_t Platform, void *Data) {
+                  auto *PM = static_cast<PluginManager *>(Data);
+                  auto *Plugin = __ol_tgt_GetPluginFromPlatform(Platform);
+                  ODBG(ODT_Init) << "Adding plugin " << Plugin->getName()
+                           << " from liboffload";
+                  PM->Plugins.push_back(Plugin);
+                  return true;
+                },
+                this))
+    REPORT() << "Failed to iterate platforms: " << Res->Details;
 
   ODBG(ODT_Init) << "RTLs loaded!";
 }
@@ -62,7 +68,6 @@ void PluginManager::deinit() {
       std::string InfoMsg = toString(std::move(Err));
       ODBG(ODT_Deinit) << "Failed to deinit plugin: " << InfoMsg;
     }
-    Plugin.release();
   }
 
   ODBG(ODT_Deinit) << "RTLs unloaded!";

>From 2fb211366d56097e84b5eb4f7349771246489c6c Mon Sep 17 00:00:00 2001
From: "Duran, Alex" <alejandro.duran at intel.com>
Date: Thu, 3 Sep 2026 10:55:00 -0700
Subject: [PATCH 2/6] [offload][omp] Load plugins through liboffload

---
 offload/include/PluginManager.h            |  3 ++-
 offload/liboffload/exports                 |  2 +-
 offload/liboffload/src/OffloadImpl.cpp     |  5 ++++
 offload/libompaccsupport/PluginManager.cpp | 29 +++++++++++++---------
 4 files changed, 25 insertions(+), 14 deletions(-)

diff --git a/offload/include/PluginManager.h b/offload/include/PluginManager.h
index 6c6fdebe76dff..eea8b62a8c39d 100644
--- a/offload/include/PluginManager.h
+++ b/offload/include/PluginManager.h
@@ -13,6 +13,7 @@
 #ifndef OMPTARGET_PLUGIN_MANAGER_H
 #define OMPTARGET_PLUGIN_MANAGER_H
 
+#include "OffloadAPI.h"
 #include "PluginInterface.h"
 
 #include "DeviceImage.h"
@@ -155,7 +156,7 @@ struct PluginManager {
   llvm::SmallVector<__tgt_bin_desc *> DelayedBinDesc;
 
   // List of all plugins, in use or not.
-  llvm::SmallVector<std::unique_ptr<GenericPluginTy>> Plugins;
+  llvm::SmallVector<GenericPluginTy *> Plugins;
 
   // Mapping of plugins to the OpenMP device identifier.
   llvm::DenseMap<std::pair<const GenericPluginTy *, int32_t>, int32_t>
diff --git a/offload/liboffload/exports b/offload/liboffload/exports
index 5487e16168681..75b1cfd049c82 100644
--- a/offload/liboffload/exports
+++ b/offload/liboffload/exports
@@ -55,9 +55,9 @@ global:
     llvm::omp::target::ompt::Initialized;
     llvm::omp::target::ompt::lookupCallbackByCode;
     llvm::omp::target::ompt::lookupCallbackByName;
-    createPlugin_*;
     # Temporary helpers to help transition of libomptarget to liboffload.
     __ol_tgt_setInfoFlag;
+    __ol_tgt_GetPluginFromPlatform;
   };
 local:
   *;
diff --git a/offload/liboffload/src/OffloadImpl.cpp b/offload/liboffload/src/OffloadImpl.cpp
index e06bd8d445bc3..6e403df9544e3 100644
--- a/offload/liboffload/src/OffloadImpl.cpp
+++ b/offload/liboffload/src/OffloadImpl.cpp
@@ -1633,5 +1633,10 @@ extern "C" void __ol_tgt_setInfoFlag(uint32_t NewInfoLevel) {
   InfoLevel.store(NewInfoLevel);
 }
 
+extern "C" GenericPluginTy *
+__ol_tgt_GetPluginFromPlatform(ol_platform_handle_t Platform) {
+  return Platform->Plugin.get();
+}
+
 } // namespace offload
 } // namespace llvm
diff --git a/offload/libompaccsupport/PluginManager.cpp b/offload/libompaccsupport/PluginManager.cpp
index 41b653a60adfd..b0cb40fb32e8d 100644
--- a/offload/libompaccsupport/PluginManager.cpp
+++ b/offload/libompaccsupport/PluginManager.cpp
@@ -26,9 +26,8 @@ using namespace llvm::omp::target::debug;
 
 PluginManager *PM = nullptr;
 
-// Every plugin exports this method to create an instance of the plugin type.
-#define PLUGIN_TARGET(Name) extern "C" GenericPluginTy *createPlugin_##Name();
-#include "Shared/Targets.def"
+extern "C" GenericPluginTy *
+__ol_tgt_GetPluginFromPlatform(ol_platform_handle_t Platform);
 
 void PluginManager::init() {
   TIMESCOPE();
@@ -38,14 +37,21 @@ void PluginManager::init() {
   }
 
   ODBG(ODT_Init) << "Loading RTLs";
-
-  // Attempt to create an instance of each supported plugin.
-#define PLUGIN_TARGET(Name)                                                    \
-  do {                                                                         \
-    Plugins.emplace_back(                                                      \
-        std::unique_ptr<GenericPluginTy>(createPlugin_##Name()));              \
-  } while (false);
-#include "Shared/Targets.def"
+  if (ol_result_t Res = olInit(nullptr))
+    REPORT() << "Failed to initialize liboffload: " << Res->Details;
+
+  
+  if (ol_result_t Res = olIteratePlatforms(
+          [](ol_platform_handle_t Platform, void *Data) {
+                  auto *PM = static_cast<PluginManager *>(Data);
+                  auto *Plugin = __ol_tgt_GetPluginFromPlatform(Platform);
+                  ODBG(ODT_Init) << "Adding plugin " << Plugin->getName()
+                           << " from liboffload";
+                  PM->Plugins.push_back(Plugin);
+                  return true;
+                },
+                this))
+    REPORT() << "Failed to iterate platforms: " << Res->Details;
 
   ODBG(ODT_Init) << "RTLs loaded!";
 }
@@ -62,7 +68,6 @@ void PluginManager::deinit() {
       std::string InfoMsg = toString(std::move(Err));
       ODBG(ODT_Deinit) << "Failed to deinit plugin: " << InfoMsg;
     }
-    Plugin.release();
   }
 
   ODBG(ODT_Deinit) << "RTLs unloaded!";

>From 5310f78f51e7d3f7ca593608ff487cbaa125f2b0 Mon Sep 17 00:00:00 2001
From: "Duran, Alex" <alejandro.duran at intel.com>
Date: Fri, 4 Sep 2026 08:59:52 -0700
Subject: [PATCH 3/6] don't initialize devices when validating the image

---
 offload/liboffload/src/OffloadImpl.cpp | 6 +-----
 1 file changed, 1 insertion(+), 5 deletions(-)

diff --git a/offload/liboffload/src/OffloadImpl.cpp b/offload/liboffload/src/OffloadImpl.cpp
index 670179c21f054..62f9878e7cd2b 100644
--- a/offload/liboffload/src/OffloadImpl.cpp
+++ b/offload/liboffload/src/OffloadImpl.cpp
@@ -1295,12 +1295,8 @@ Error olCreateProgram_impl(ol_context_handle_t Context,
 Error olIsValidBinary_impl(ol_device_handle_t Device, const void *ProgData,
                            size_t ProgDataSize, bool *IsValid) {
   StringRef Buffer(reinterpret_cast<const char *>(ProgData), ProgDataSize);
-  auto DeviceOrErr = Device->getDevice();
-  if (!DeviceOrErr)
-    return DeviceOrErr.takeError();
-  auto *DeviceImpl = *DeviceOrErr;
   *IsValid =
-      DeviceImpl->Plugin.isDeviceCompatible(DeviceImpl->getDeviceId(), Buffer);
+      Device->Platform.Plugin->isDeviceCompatible(Device->DeviceNum, Buffer);
   return Error::success();
 }
 

>From 80ab4cdb51a82a703bbbe792082013805a712586 Mon Sep 17 00:00:00 2001
From: "Duran, Alex" <alejandro.duran at intel.com>
Date: Thu, 3 Sep 2026 10:39:20 -0700
Subject: [PATCH 4/6] [OFFLOAD]add olIteratePlatforms

---
 offload/liboffload/API/Platform.td     | 23 +++++++++++++++++++++++
 offload/liboffload/src/OffloadImpl.cpp | 11 +++++++++++
 2 files changed, 34 insertions(+)

diff --git a/offload/liboffload/API/Platform.td b/offload/liboffload/API/Platform.td
index 62810e8fdb7ca..65efec2b8af4a 100644
--- a/offload/liboffload/API/Platform.td
+++ b/offload/liboffload/API/Platform.td
@@ -97,3 +97,26 @@ def olPlatformRegisterRPCCallback : Function {
                       "RPC callback function pointer", PARAM_IN>];
   let returns = [Return<"OL_ERRC_INVALID_PLATFORM">, Return<"OL_ERRC_SUCCESS">];
 }
+
+def ol_platform_iterate_cb_t : FptrTypedef {
+  let desc = "User-provided function to be used with `olIteratePlatforms`";
+  let params = [
+    Param<"ol_platform_handle_t", "Platform", "the platform handle of the current iteration", PARAM_IN>,
+    Param<"void*", "UserData", "optional user data", PARAM_IN_OPTIONAL>
+  ];
+  let return = "bool";
+}
+
+def olIteratePlatforms : Function {
+  let desc = "Iterates over all available platforms, calling the callback for each platform.";
+  let details = [
+    "If the user-provided callback returns `false`, the iteration is stopped."
+  ];
+  let params = [
+    Param<"ol_platform_iterate_cb_t", "Callback", "User-provided function called for each available platform", PARAM_IN>,
+    Param<"void*", "UserData", "Optional user data to pass to the callback", PARAM_IN_OPTIONAL>
+  ];
+  let returns = [
+    Return<"OL_ERRC_INVALID_PLATFORM">
+  ];
+}
diff --git a/offload/liboffload/src/OffloadImpl.cpp b/offload/liboffload/src/OffloadImpl.cpp
index 62f9878e7cd2b..775b4b9ac2f95 100644
--- a/offload/liboffload/src/OffloadImpl.cpp
+++ b/offload/liboffload/src/OffloadImpl.cpp
@@ -468,6 +468,17 @@ Error olPlatformRegisterRPCCallback_impl(ol_platform_handle_t Platform,
   return Error::success();
 }
 
+Error olIteratePlatforms_impl(ol_platform_iterate_cb_t Callback,
+                              void *UserData) {
+  for (auto &Platform : OffloadContext::get().Platforms) {
+    if (!Callback(Platform.get(), UserData)) {
+      return Error::success();
+    }
+  }
+
+  return Error::success();
+}
+
 Error olGetDeviceInfoImplDetail(ol_device_handle_t Device,
                                 ol_device_info_t PropName, size_t PropSize,
                                 void *PropValue, size_t *PropSizeRet) {

>From ed5966525f7e71dad216fb585c89a0b93ae51b0c Mon Sep 17 00:00:00 2001
From: "Duran, Alex" <alejandro.duran at intel.com>
Date: Thu, 3 Sep 2026 10:56:25 -0700
Subject: [PATCH 5/6] add test

---
 .../platform/olIteratePlatforms.cpp           | 45 +++++++++++++++++++
 1 file changed, 45 insertions(+)
 create mode 100644 offload/unittests/OffloadAPI/platform/olIteratePlatforms.cpp

diff --git a/offload/unittests/OffloadAPI/platform/olIteratePlatforms.cpp b/offload/unittests/OffloadAPI/platform/olIteratePlatforms.cpp
new file mode 100644
index 0000000000000..4f8f4e35df23b
--- /dev/null
+++ b/offload/unittests/OffloadAPI/platform/olIteratePlatforms.cpp
@@ -0,0 +1,45 @@
+//===------- Offload API tests - olIteratePlatforms -----------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "../common/Fixtures.hpp"
+#include <OffloadAPI.h>
+#include <gtest/gtest.h>
+
+using olIteratePlatformsTest = OffloadTest;
+
+TEST_F(olIteratePlatformsTest, SuccessEmptyCallback) {
+  ASSERT_SUCCESS(olIteratePlatforms(
+      [](ol_platform_handle_t, void *) { return false; }, nullptr));
+}
+
+TEST_F(olIteratePlatformsTest, SuccessGetPlatform) {
+  uint32_t PlatformCount = 0;
+  ol_platform_handle_t Platform = nullptr;
+
+  ASSERT_SUCCESS(olIteratePlatforms(
+      [](ol_platform_handle_t, void *Data) {
+        auto Count = static_cast<uint32_t *>(Data);
+        *Count += 1;
+        return true;
+      },
+      &PlatformCount));
+
+  if (PlatformCount == 0) {
+    GTEST_SKIP() << "No available platforms.";
+  }
+
+  ASSERT_SUCCESS(olIteratePlatforms(
+      [](ol_platform_handle_t P, void *Data) {
+        auto PlatformPtr = static_cast<ol_platform_handle_t *>(Data);
+        *PlatformPtr = P;
+        return true;
+      },
+      &Platform));
+
+  ASSERT_NE(Platform, nullptr);
+}

>From cf68ec1391130fa116ec4016cc712e3ad810309f Mon Sep 17 00:00:00 2001
From: "Duran, Alex" <alejandro.duran at intel.com>
Date: Thu, 3 Sep 2026 10:55:00 -0700
Subject: [PATCH 6/6] [offload][omp] Load plugins through liboffload

---
 offload/include/PluginManager.h            |  3 ++-
 offload/liboffload/exports                 |  2 +-
 offload/liboffload/src/OffloadImpl.cpp     |  5 ++++
 offload/libompaccsupport/PluginManager.cpp | 29 +++++++++++++---------
 4 files changed, 25 insertions(+), 14 deletions(-)

diff --git a/offload/include/PluginManager.h b/offload/include/PluginManager.h
index 6c6fdebe76dff..eea8b62a8c39d 100644
--- a/offload/include/PluginManager.h
+++ b/offload/include/PluginManager.h
@@ -13,6 +13,7 @@
 #ifndef OMPTARGET_PLUGIN_MANAGER_H
 #define OMPTARGET_PLUGIN_MANAGER_H
 
+#include "OffloadAPI.h"
 #include "PluginInterface.h"
 
 #include "DeviceImage.h"
@@ -155,7 +156,7 @@ struct PluginManager {
   llvm::SmallVector<__tgt_bin_desc *> DelayedBinDesc;
 
   // List of all plugins, in use or not.
-  llvm::SmallVector<std::unique_ptr<GenericPluginTy>> Plugins;
+  llvm::SmallVector<GenericPluginTy *> Plugins;
 
   // Mapping of plugins to the OpenMP device identifier.
   llvm::DenseMap<std::pair<const GenericPluginTy *, int32_t>, int32_t>
diff --git a/offload/liboffload/exports b/offload/liboffload/exports
index 5487e16168681..75b1cfd049c82 100644
--- a/offload/liboffload/exports
+++ b/offload/liboffload/exports
@@ -55,9 +55,9 @@ global:
     llvm::omp::target::ompt::Initialized;
     llvm::omp::target::ompt::lookupCallbackByCode;
     llvm::omp::target::ompt::lookupCallbackByName;
-    createPlugin_*;
     # Temporary helpers to help transition of libomptarget to liboffload.
     __ol_tgt_setInfoFlag;
+    __ol_tgt_GetPluginFromPlatform;
   };
 local:
   *;
diff --git a/offload/liboffload/src/OffloadImpl.cpp b/offload/liboffload/src/OffloadImpl.cpp
index 775b4b9ac2f95..b5cc82a764806 100644
--- a/offload/liboffload/src/OffloadImpl.cpp
+++ b/offload/liboffload/src/OffloadImpl.cpp
@@ -1629,5 +1629,10 @@ extern "C" void __ol_tgt_setInfoFlag(uint32_t NewInfoLevel) {
   InfoLevel.store(NewInfoLevel);
 }
 
+extern "C" GenericPluginTy *
+__ol_tgt_GetPluginFromPlatform(ol_platform_handle_t Platform) {
+  return Platform->Plugin.get();
+}
+
 } // namespace offload
 } // namespace llvm
diff --git a/offload/libompaccsupport/PluginManager.cpp b/offload/libompaccsupport/PluginManager.cpp
index 41b653a60adfd..b0cb40fb32e8d 100644
--- a/offload/libompaccsupport/PluginManager.cpp
+++ b/offload/libompaccsupport/PluginManager.cpp
@@ -26,9 +26,8 @@ using namespace llvm::omp::target::debug;
 
 PluginManager *PM = nullptr;
 
-// Every plugin exports this method to create an instance of the plugin type.
-#define PLUGIN_TARGET(Name) extern "C" GenericPluginTy *createPlugin_##Name();
-#include "Shared/Targets.def"
+extern "C" GenericPluginTy *
+__ol_tgt_GetPluginFromPlatform(ol_platform_handle_t Platform);
 
 void PluginManager::init() {
   TIMESCOPE();
@@ -38,14 +37,21 @@ void PluginManager::init() {
   }
 
   ODBG(ODT_Init) << "Loading RTLs";
-
-  // Attempt to create an instance of each supported plugin.
-#define PLUGIN_TARGET(Name)                                                    \
-  do {                                                                         \
-    Plugins.emplace_back(                                                      \
-        std::unique_ptr<GenericPluginTy>(createPlugin_##Name()));              \
-  } while (false);
-#include "Shared/Targets.def"
+  if (ol_result_t Res = olInit(nullptr))
+    REPORT() << "Failed to initialize liboffload: " << Res->Details;
+
+  
+  if (ol_result_t Res = olIteratePlatforms(
+          [](ol_platform_handle_t Platform, void *Data) {
+                  auto *PM = static_cast<PluginManager *>(Data);
+                  auto *Plugin = __ol_tgt_GetPluginFromPlatform(Platform);
+                  ODBG(ODT_Init) << "Adding plugin " << Plugin->getName()
+                           << " from liboffload";
+                  PM->Plugins.push_back(Plugin);
+                  return true;
+                },
+                this))
+    REPORT() << "Failed to iterate platforms: " << Res->Details;
 
   ODBG(ODT_Init) << "RTLs loaded!";
 }
@@ -62,7 +68,6 @@ void PluginManager::deinit() {
       std::string InfoMsg = toString(std::move(Err));
       ODBG(ODT_Deinit) << "Failed to deinit plugin: " << InfoMsg;
     }
-    Plugin.release();
   }
 
   ODBG(ODT_Deinit) << "RTLs unloaded!";



More information about the llvm-branch-commits mailing list