[llvm] [offload] Add `dlwrap::loaded` function to check for optional symbols (PR #210737)
via llvm-commits
llvm-commits at lists.llvm.org
Wed Jul 29 06:26:55 PDT 2026
https://github.com/blazej-smorawski updated https://github.com/llvm/llvm-project/pull/210737
>From b56f231c699b16a59a35035b020a5dbcdd257b30 Mon Sep 17 00:00:00 2001
From: blazej-smorawski <blazej.smorawski at intel.com>
Date: Fri, 3 Jul 2026 13:48:27 +0200
Subject: [PATCH 1/9] [offload] Add `dlwrap::loaded` function to check for
optional symbols
---
offload/plugins-nextgen/common/include/DLWrap.h | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/offload/plugins-nextgen/common/include/DLWrap.h b/offload/plugins-nextgen/common/include/DLWrap.h
index 95ce86e123cd3..116cd4afe37a6 100644
--- a/offload/plugins-nextgen/common/include/DLWrap.h
+++ b/offload/plugins-nextgen/common/include/DLWrap.h
@@ -135,6 +135,8 @@ template <size_t Requested, size_t Required> constexpr void verboseAssert() {
static_assert(Requested == Required, "Arity Error");
}
+template <auto Fn> bool loaded();
+
} // namespace dlwrap
#define DLWRAP_INSTANTIATE(SYM_DEF, SYM_USE, ARITY) \
@@ -167,6 +169,9 @@ template <size_t Requested, size_t Required> constexpr void verboseAssert() {
return reinterpret_cast<T::FunctionType>(P); \
} \
}; \
+ template <> bool loaded<&(::SYMBOL)>() { \
+ return SYMBOL##_Trait::get() != nullptr; \
+ } \
}
#define DLWRAP_IMPL(SYMBOL, ARITY) \
>From 69f70b7216f6e233c43b5247af631771944bcd10 Mon Sep 17 00:00:00 2001
From: blazej-smorawski <blazej.smorawski at intel.com>
Date: Wed, 22 Jul 2026 12:53:47 +0200
Subject: [PATCH 2/9] [offload] Add helpers to enable optional symbols from
external APIs
---
.../common/include/APIHelpers.h | 41 +++++++++++++++++++
.../plugins-nextgen/common/include/DLWrap.h | 12 +++++-
.../level_zero/include/L0CmdListManager.h | 10 +++++
.../level_zero/include/L0Compat.h | 28 +++++++++++++
4 files changed, 89 insertions(+), 2 deletions(-)
create mode 100644 offload/plugins-nextgen/common/include/APIHelpers.h
create mode 100644 offload/plugins-nextgen/level_zero/include/L0Compat.h
diff --git a/offload/plugins-nextgen/common/include/APIHelpers.h b/offload/plugins-nextgen/common/include/APIHelpers.h
new file mode 100644
index 0000000000000..7c0e283ab5805
--- /dev/null
+++ b/offload/plugins-nextgen/common/include/APIHelpers.h
@@ -0,0 +1,41 @@
+//===-- Shared/APIHelpers.h - helpers for external APIs --*- C++ -*-===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+// The header contains helper functions to make interactions with external APIs
+// such as CUDA or level zero easier
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef OPENMP_LIBOMPTARGET_PLUGINS_NEXTGEN_COMMON_APIHELPERS_H
+#define OPENMP_LIBOMPTARGET_PLUGINS_NEXTGEN_COMMON_APIHELPERS_H
+
+#include "DLWrap.h"
+
+// Macro to mark external symbol as weak, so linker will be okay
+// if the symbol is missing. For direct linking (dlwrap::IsDlOpened<&name> ==
+// false), we need to check if linker could find the symbol. For symbols loaded
+// using dlsym we use dlwrap::loaded<name>().
+#define API_HELPER_OPTIONAL(return_type, name, ...) \
+ extern "C" return_type name(__VA_ARGS__) __attribute__((weak)); \
+ template <> inline bool api_helper::canCall<name>() { \
+ if constexpr (dlwrap::IsDlOpened<&name>) \
+ return dlwrap::loaded<name>(); \
+ return name != nullptr; \
+ }
+
+namespace api_helper {
+
+// Default template specialization for extra safety
+template <auto Fn>
+bool canCall() {
+ static_assert(false, "api_helper::canCall() should only be called on symbols decorated with API_HELPER_OPTIONAL!");
+}
+
+} // namespace api_helper
+
+#endif // OPENMP_LIBOMPTARGET_PLUGINS_NEXTGEN_COMMON_APIHELPERS_H
\ No newline at end of file
diff --git a/offload/plugins-nextgen/common/include/DLWrap.h b/offload/plugins-nextgen/common/include/DLWrap.h
index 116cd4afe37a6..863d8006f246a 100644
--- a/offload/plugins-nextgen/common/include/DLWrap.h
+++ b/offload/plugins-nextgen/common/include/DLWrap.h
@@ -78,7 +78,7 @@
static size_t size(); \
static const char *symbol(size_t); /* get symbol name in [0, size()) */ \
static void ** \
- pointer(size_t); /* get pointer to function pointer in [0, size()) */ \
+ pointer(size_t); /* get pointer to function pointer in [0, size()) */ \
}
// DLWRAP_FINALIZE() implements the functions from DLWRAP_INITIALIZE
@@ -107,7 +107,9 @@ template <size_t S> struct count {
static constexpr size_t N = count<S - 1>::N;
};
-template <> struct count<0> { static constexpr size_t N = 0; };
+template <> struct count<0> {
+ static constexpr size_t N = 0;
+};
// Get a constexpr size_t ID, starts at zero
#define DLWRAP_ID() (dlwrap::type::count<__LINE__>::N)
@@ -135,8 +137,13 @@ template <size_t Requested, size_t Required> constexpr void verboseAssert() {
static_assert(Requested == Required, "Arity Error");
}
+// Template to check if a symbol was loaded successfully
template <auto Fn> bool loaded();
+// Template to check if a symbol is provided by dlwrap
+// By default all symbols resolve to false
+template <auto Fn> constexpr bool IsDlOpened = false;
+
} // namespace dlwrap
#define DLWRAP_INSTANTIATE(SYM_DEF, SYM_USE, ARITY) \
@@ -160,6 +167,7 @@ template <auto Fn> bool loaded();
DLWRAP_INC(); \
DLWRAP_SYMBOL(SYMBOL, DLWRAP_ID() - 1); \
namespace dlwrap { \
+ template <> inline constexpr bool IsDlOpened<&::SYMBOL> = true; \
struct SYMBOL##_Trait : public dlwrap::trait<decltype(&SYMBOL)> { \
using T = dlwrap::trait<decltype(&SYMBOL)>; \
static T::FunctionType get() { \
diff --git a/offload/plugins-nextgen/level_zero/include/L0CmdListManager.h b/offload/plugins-nextgen/level_zero/include/L0CmdListManager.h
index 94ddef231ff11..1f86006b30a0b 100644
--- a/offload/plugins-nextgen/level_zero/include/L0CmdListManager.h
+++ b/offload/plugins-nextgen/level_zero/include/L0CmdListManager.h
@@ -13,9 +13,11 @@
#ifndef OPENMP_LIBOMPTARGET_PLUGINS_NEXTGEN_LEVEL_ZERO_L0CMDLISTMANAGER_H
#define OPENMP_LIBOMPTARGET_PLUGINS_NEXTGEN_LEVEL_ZERO_L0CMDLISTMANAGER_H
+#include "L0Compat.h"
#include "L0Context.h"
#include "L0Defs.h"
#include "L0Trace.h"
+#include "PluginInterface.h"
#include <mutex>
namespace llvm::omp::target::plugin {
@@ -126,10 +128,18 @@ class L0CmdListManagerTy {
const ze_group_size_t *GroupSizes, void **ArgPtrs,
ze_event_handle_t SignalEvent = nullptr, uint32_t NumWaitEvents = 0,
ze_event_handle_t *WaitEvents = nullptr, bool IsCooperative = false) {
+
+ if (!api_helper::canCall<zeCommandListAppendLaunchKernelWithArguments>())
+ return Plugin::error(
+ ErrorCode::UNSUPPORTED,
+ "zeCommandListAppendLaunchKernelWithArguments is not "
+ "available on this driver");
+
ze_command_list_append_launch_kernel_param_cooperative_desc_t CoopDesc = {
ZE_STRUCTURE_TYPE_COMMAND_LIST_APPEND_PARAM_COOPERATIVE_DESC, nullptr,
static_cast<ze_bool_t>(IsCooperative)};
std::lock_guard<std::mutex> Lock(Mtx);
+
CALL_ZE_RET_ERROR(zeCommandListAppendLaunchKernelWithArguments, CmdList,
Kernel, *GroupCounts, *GroupSizes, ArgPtrs,
IsCooperative ? &CoopDesc : nullptr, SignalEvent,
diff --git a/offload/plugins-nextgen/level_zero/include/L0Compat.h b/offload/plugins-nextgen/level_zero/include/L0Compat.h
new file mode 100644
index 0000000000000..2062c9624ad20
--- /dev/null
+++ b/offload/plugins-nextgen/level_zero/include/L0Compat.h
@@ -0,0 +1,28 @@
+//===--- Level Zero Target RTL Implementation -----------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+// Level Zero compatibility layer enabling us to compile using new APIs.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef OPENMP_LIBOMPTARGET_PLUGINS_NEXTGEN_LEVEL_ZERO_L0COMPAT_H
+#define OPENMP_LIBOMPTARGET_PLUGINS_NEXTGEN_LEVEL_ZERO_L0COMPAT_H
+
+#include "APIHelpers.h"
+
+#include <level_zero/ze_api.h>
+
+API_HELPER_OPTIONAL(ze_result_t, zeCommandListAppendLaunchKernelWithArguments,
+ ze_command_list_handle_t hCommandList,
+ ze_kernel_handle_t hKernel,
+ const ze_group_count_t groupCounts,
+ const ze_group_size_t groupSizes, void **pArguments,
+ const void *pNext, ze_event_handle_t hSignalEvent,
+ uint32_t numWaitEvents, ze_event_handle_t *phWaitEvents);
+
+#endif // OPENMP_LIBOMPTARGET_PLUGINS_NEXTGEN_LEVEL_ZERO_L0COMPAT_H
>From a84b4d7104618abd075eac95520de690c5a1088f Mon Sep 17 00:00:00 2001
From: blazej-smorawski <blazej.smorawski at intel.com>
Date: Wed, 22 Jul 2026 14:43:45 +0200
Subject: [PATCH 3/9] [offload] Make `canCall` work on older compilers
---
offload/plugins-nextgen/common/include/APIHelpers.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/offload/plugins-nextgen/common/include/APIHelpers.h b/offload/plugins-nextgen/common/include/APIHelpers.h
index 7c0e283ab5805..2bf331507ec8d 100644
--- a/offload/plugins-nextgen/common/include/APIHelpers.h
+++ b/offload/plugins-nextgen/common/include/APIHelpers.h
@@ -33,7 +33,7 @@ namespace api_helper {
// Default template specialization for extra safety
template <auto Fn>
bool canCall() {
- static_assert(false, "api_helper::canCall() should only be called on symbols decorated with API_HELPER_OPTIONAL!");
+ static_assert(sizeof(decltype(Fn)*) == 0, "api_helper::canCall() should only be called on symbols decorated with API_HELPER_OPTIONAL!");
}
} // namespace api_helper
>From 434a91e2088fc810bbe39f979c944bae076562d2 Mon Sep 17 00:00:00 2001
From: blazej-smorawski <blazej.smorawski at intel.com>
Date: Wed, 22 Jul 2026 14:50:00 +0200
Subject: [PATCH 4/9] [offload] Fix format
---
offload/plugins-nextgen/common/include/APIHelpers.h | 9 +++++----
offload/plugins-nextgen/common/include/DLWrap.h | 2 +-
2 files changed, 6 insertions(+), 5 deletions(-)
diff --git a/offload/plugins-nextgen/common/include/APIHelpers.h b/offload/plugins-nextgen/common/include/APIHelpers.h
index 2bf331507ec8d..88a430bdb4839 100644
--- a/offload/plugins-nextgen/common/include/APIHelpers.h
+++ b/offload/plugins-nextgen/common/include/APIHelpers.h
@@ -22,7 +22,7 @@
// using dlsym we use dlwrap::loaded<name>().
#define API_HELPER_OPTIONAL(return_type, name, ...) \
extern "C" return_type name(__VA_ARGS__) __attribute__((weak)); \
- template <> inline bool api_helper::canCall<name>() { \
+ template <> inline bool api_helper::canCall<name>() { \
if constexpr (dlwrap::IsDlOpened<&name>) \
return dlwrap::loaded<name>(); \
return name != nullptr; \
@@ -31,9 +31,10 @@
namespace api_helper {
// Default template specialization for extra safety
-template <auto Fn>
-bool canCall() {
- static_assert(sizeof(decltype(Fn)*) == 0, "api_helper::canCall() should only be called on symbols decorated with API_HELPER_OPTIONAL!");
+template <auto Fn> bool canCall() {
+ static_assert(sizeof(decltype(Fn) *) == 0,
+ "api_helper::canCall() should only be called on symbols "
+ "decorated with API_HELPER_OPTIONAL!");
}
} // namespace api_helper
diff --git a/offload/plugins-nextgen/common/include/DLWrap.h b/offload/plugins-nextgen/common/include/DLWrap.h
index 863d8006f246a..160731a176d6d 100644
--- a/offload/plugins-nextgen/common/include/DLWrap.h
+++ b/offload/plugins-nextgen/common/include/DLWrap.h
@@ -78,7 +78,7 @@
static size_t size(); \
static const char *symbol(size_t); /* get symbol name in [0, size()) */ \
static void ** \
- pointer(size_t); /* get pointer to function pointer in [0, size()) */ \
+ pointer(size_t); /* get pointer to function pointer in [0, size()) */ \
}
// DLWRAP_FINALIZE() implements the functions from DLWRAP_INITIALIZE
>From a0667a9133959aa50c004b1f230722441cb5185f Mon Sep 17 00:00:00 2001
From: blazej-smorawski <blazej.smorawski at intel.com>
Date: Thu, 23 Jul 2026 16:16:08 +0200
Subject: [PATCH 5/9] [offload] Fix incorrect constexpr in
`API_HELPER_OPTIONAL`
---
offload/plugins-nextgen/common/include/APIHelpers.h | 11 +++++++----
offload/plugins-nextgen/common/include/DLWrap.h | 12 +++++-------
2 files changed, 12 insertions(+), 11 deletions(-)
diff --git a/offload/plugins-nextgen/common/include/APIHelpers.h b/offload/plugins-nextgen/common/include/APIHelpers.h
index 88a430bdb4839..85bdfb8f640e1 100644
--- a/offload/plugins-nextgen/common/include/APIHelpers.h
+++ b/offload/plugins-nextgen/common/include/APIHelpers.h
@@ -20,12 +20,15 @@
// if the symbol is missing. For direct linking (dlwrap::IsDlOpened<&name> ==
// false), we need to check if linker could find the symbol. For symbols loaded
// using dlsym we use dlwrap::loaded<name>().
-#define API_HELPER_OPTIONAL(return_type, name, ...) \
+#define API_HELPER_OPTIONAL(return_type, name, ...) \
extern "C" return_type name(__VA_ARGS__) __attribute__((weak)); \
template <> inline bool api_helper::canCall<name>() { \
- if constexpr (dlwrap::IsDlOpened<&name>) \
- return dlwrap::loaded<name>(); \
- return name != nullptr; \
+ if (name == nullptr) \
+ /* Not loaded weak symbol */ \
+ return false; \
+ /* Symbols from dlwrap are never nullptr, but `loaded` might return false \
+ */ \
+ return dlwrap::loaded<name>(); \
}
namespace api_helper {
diff --git a/offload/plugins-nextgen/common/include/DLWrap.h b/offload/plugins-nextgen/common/include/DLWrap.h
index 160731a176d6d..394891abded9d 100644
--- a/offload/plugins-nextgen/common/include/DLWrap.h
+++ b/offload/plugins-nextgen/common/include/DLWrap.h
@@ -137,12 +137,11 @@ template <size_t Requested, size_t Required> constexpr void verboseAssert() {
static_assert(Requested == Required, "Arity Error");
}
-// Template to check if a symbol was loaded successfully
-template <auto Fn> bool loaded();
-
-// Template to check if a symbol is provided by dlwrap
-// By default all symbols resolve to false
-template <auto Fn> constexpr bool IsDlOpened = false;
+// Template to check if a symbol was loaded successfully.
+// Returns true for symbols that were not wrapped by dlwrap.
+template <auto Fn> bool loaded() {
+ return true;
+}
} // namespace dlwrap
@@ -167,7 +166,6 @@ template <auto Fn> constexpr bool IsDlOpened = false;
DLWRAP_INC(); \
DLWRAP_SYMBOL(SYMBOL, DLWRAP_ID() - 1); \
namespace dlwrap { \
- template <> inline constexpr bool IsDlOpened<&::SYMBOL> = true; \
struct SYMBOL##_Trait : public dlwrap::trait<decltype(&SYMBOL)> { \
using T = dlwrap::trait<decltype(&SYMBOL)>; \
static T::FunctionType get() { \
>From 07c151b7bf58cde95d5c66538f78dc67a2c62946 Mon Sep 17 00:00:00 2001
From: blazej-smorawski <blazej.smorawski at intel.com>
Date: Thu, 23 Jul 2026 16:22:08 +0200
Subject: [PATCH 6/9] [offload] Fix format
---
offload/plugins-nextgen/common/include/APIHelpers.h | 4 ++--
offload/plugins-nextgen/common/include/DLWrap.h | 4 +---
2 files changed, 3 insertions(+), 5 deletions(-)
diff --git a/offload/plugins-nextgen/common/include/APIHelpers.h b/offload/plugins-nextgen/common/include/APIHelpers.h
index 85bdfb8f640e1..182f11fc4bc3a 100644
--- a/offload/plugins-nextgen/common/include/APIHelpers.h
+++ b/offload/plugins-nextgen/common/include/APIHelpers.h
@@ -20,12 +20,12 @@
// if the symbol is missing. For direct linking (dlwrap::IsDlOpened<&name> ==
// false), we need to check if linker could find the symbol. For symbols loaded
// using dlsym we use dlwrap::loaded<name>().
-#define API_HELPER_OPTIONAL(return_type, name, ...) \
+#define API_HELPER_OPTIONAL(return_type, name, ...) \
extern "C" return_type name(__VA_ARGS__) __attribute__((weak)); \
template <> inline bool api_helper::canCall<name>() { \
if (name == nullptr) \
/* Not loaded weak symbol */ \
- return false; \
+ return false; \
/* Symbols from dlwrap are never nullptr, but `loaded` might return false \
*/ \
return dlwrap::loaded<name>(); \
diff --git a/offload/plugins-nextgen/common/include/DLWrap.h b/offload/plugins-nextgen/common/include/DLWrap.h
index 394891abded9d..16f5a86911da3 100644
--- a/offload/plugins-nextgen/common/include/DLWrap.h
+++ b/offload/plugins-nextgen/common/include/DLWrap.h
@@ -139,9 +139,7 @@ template <size_t Requested, size_t Required> constexpr void verboseAssert() {
// Template to check if a symbol was loaded successfully.
// Returns true for symbols that were not wrapped by dlwrap.
-template <auto Fn> bool loaded() {
- return true;
-}
+template <auto Fn> bool loaded() { return true; }
} // namespace dlwrap
>From 6d10d147bc020b23d5d54f4dc031f1d1951198c1 Mon Sep 17 00:00:00 2001
From: blazej-smorawski <blazej.smorawski at intel.com>
Date: Fri, 24 Jul 2026 10:34:31 +0200
Subject: [PATCH 7/9] [offload] Disable direct linking on Windows
---
offload/plugins-nextgen/amdgpu/CMakeLists.txt | 8 +++++++-
offload/plugins-nextgen/cuda/CMakeLists.txt | 8 +++++++-
offload/plugins-nextgen/level_zero/CMakeLists.txt | 8 +++++++-
3 files changed, 21 insertions(+), 3 deletions(-)
diff --git a/offload/plugins-nextgen/amdgpu/CMakeLists.txt b/offload/plugins-nextgen/amdgpu/CMakeLists.txt
index af2db85f74c64..4f680087e3fcf 100644
--- a/offload/plugins-nextgen/amdgpu/CMakeLists.txt
+++ b/offload/plugins-nextgen/amdgpu/CMakeLists.txt
@@ -8,7 +8,13 @@ target_sources(omptarget.rtl.amdgpu PRIVATE src/rtl.cpp)
target_include_directories(omptarget.rtl.amdgpu PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/utils)
-if(hsa-runtime64_FOUND AND NOT "amdgpu" IN_LIST LIBOMPTARGET_DLOPEN_PLUGINS)
+if (WIN32 AND NOT "amdgpu" IN_LIST LIBOMPTARGET_DLOPEN_PLUGINS)
+ message(WARNING "Direct linking against libhsa is not supported on Windows; "
+ "falling back to dlopen. Add 'amdgpu' to "
+ "LIBOMPTARGET_DLOPEN_PLUGINS to silence this warning.")
+endif()
+
+if(hsa-runtime64_FOUND AND NOT "amdgpu" IN_LIST LIBOMPTARGET_DLOPEN_PLUGINS AND NOT WIN32)
message(STATUS "Building AMDGPU plugin linked against libhsa")
target_link_libraries(omptarget.rtl.amdgpu PRIVATE hsa-runtime64::hsa-runtime64)
else()
diff --git a/offload/plugins-nextgen/cuda/CMakeLists.txt b/offload/plugins-nextgen/cuda/CMakeLists.txt
index b96e25e3dc517..b3e7b7eeaa10a 100644
--- a/offload/plugins-nextgen/cuda/CMakeLists.txt
+++ b/offload/plugins-nextgen/cuda/CMakeLists.txt
@@ -8,7 +8,13 @@ target_compile_definitions(omptarget.rtl.cuda PRIVATE OFFLOAD_MIN_CUDA_VERSION=$
find_package(CUDAToolkit QUIET ${OFFLOAD_MIN_CUDA_VERSION})
-if(CUDAToolkit_FOUND AND NOT "cuda" IN_LIST LIBOMPTARGET_DLOPEN_PLUGINS)
+if (WIN32 AND NOT "cuda" IN_LIST LIBOMPTARGET_DLOPEN_PLUGINS)
+ message(WARNING "Direct linking against libcuda is not supported on Windows; "
+ "falling back to dlopen. Add 'cuda' to "
+ "LIBOMPTARGET_DLOPEN_PLUGINS to silence this warning.")
+endif()
+
+if(CUDAToolkit_FOUND AND NOT "cuda" IN_LIST LIBOMPTARGET_DLOPEN_PLUGINS AND NOT WIN32)
message(STATUS "Building CUDA plugin linked against libcuda")
target_link_libraries(omptarget.rtl.cuda PRIVATE CUDA::cuda_driver)
else()
diff --git a/offload/plugins-nextgen/level_zero/CMakeLists.txt b/offload/plugins-nextgen/level_zero/CMakeLists.txt
index c40a375166f8b..15ca8d90ba714 100644
--- a/offload/plugins-nextgen/level_zero/CMakeLists.txt
+++ b/offload/plugins-nextgen/level_zero/CMakeLists.txt
@@ -34,7 +34,13 @@ target_include_directories(omptarget.rtl.level_zero PRIVATE
${LIBOMPTARGET_LLVM_INCLUDE_DIRS}
)
-if (LIBOMPTARGET_DEP_LEVEL_ZERO_LIBRARY AND NOT "level_zero" IN_LIST LIBOMPTARGET_DLOPEN_PLUGINS)
+if (WIN32 AND NOT "level_zero" IN_LIST LIBOMPTARGET_DLOPEN_PLUGINS)
+ message(WARNING "Direct linking against level_zero library is not supported on "
+ "Windows; falling back to dlopen. Add 'level_zero' to "
+ "LIBOMPTARGET_DLOPEN_PLUGINS to silence this warning.")
+endif()
+
+if (LIBOMPTARGET_DEP_LEVEL_ZERO_LIBRARY AND NOT "level_zero" IN_LIST LIBOMPTARGET_DLOPEN_PLUGINS AND NOT WIN32)
message(STATUS "Building Level Zero NG plugin linked against level_zero library")
target_include_directories(omptarget.rtl.level_zero PRIVATE
${LIBOMPTARGET_DEP_LEVEL_ZERO_INCLUDE_DIR}
>From 578ce61ef8f38542936b42cc2cdc6e52afe136f5 Mon Sep 17 00:00:00 2001
From: blazej-smorawski <blazej.smorawski at intel.com>
Date: Mon, 27 Jul 2026 16:29:52 +0200
Subject: [PATCH 8/9] [offload] fix missing endline
---
offload/plugins-nextgen/common/include/APIHelpers.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/offload/plugins-nextgen/common/include/APIHelpers.h b/offload/plugins-nextgen/common/include/APIHelpers.h
index 182f11fc4bc3a..6e52e34793ef4 100644
--- a/offload/plugins-nextgen/common/include/APIHelpers.h
+++ b/offload/plugins-nextgen/common/include/APIHelpers.h
@@ -42,4 +42,4 @@ template <auto Fn> bool canCall() {
} // namespace api_helper
-#endif // OPENMP_LIBOMPTARGET_PLUGINS_NEXTGEN_COMMON_APIHELPERS_H
\ No newline at end of file
+#endif // OPENMP_LIBOMPTARGET_PLUGINS_NEXTGEN_COMMON_APIHELPERS_H
>From 4cee5d21e4200ccb4707003ffa88790e5235f009 Mon Sep 17 00:00:00 2001
From: blazej-smorawski <blazej.smorawski at intel.com>
Date: Wed, 29 Jul 2026 15:24:43 +0200
Subject: [PATCH 9/9] [offload] Rework `API_HELPER_OPTIONAL` so it no longer
uses UB templates
---
.../common/include/APIHelpers.h | 22 +++++++++++++------
.../plugins-nextgen/common/include/DLWrap.h | 8 +------
2 files changed, 16 insertions(+), 14 deletions(-)
diff --git a/offload/plugins-nextgen/common/include/APIHelpers.h b/offload/plugins-nextgen/common/include/APIHelpers.h
index 6e52e34793ef4..ef59442f1604c 100644
--- a/offload/plugins-nextgen/common/include/APIHelpers.h
+++ b/offload/plugins-nextgen/common/include/APIHelpers.h
@@ -17,18 +17,26 @@
#include "DLWrap.h"
// Macro to mark external symbol as weak, so linker will be okay
-// if the symbol is missing. For direct linking (dlwrap::IsDlOpened<&name> ==
-// false), we need to check if linker could find the symbol. For symbols loaded
-// using dlsym we use dlwrap::loaded<name>().
+// if the symbol is missing. For direct linking only available on Linux, we need
+// to check if linker could find the symbol. For symbols loaded using dlsym we
+// call name##_loaded function. The name##_loaded function will be nullptr if
+// external library was linked directly.
#define API_HELPER_OPTIONAL(return_type, name, ...) \
+ namespace dlwrap { \
+ bool name##_loaded() __attribute__((weak)); \
+ } \
extern "C" return_type name(__VA_ARGS__) __attribute__((weak)); \
template <> inline bool api_helper::canCall<name>() { \
if (name == nullptr) \
- /* Not loaded weak symbol */ \
+ /* Not loaded weak symbol, only possible on Linux */ \
return false; \
- /* Symbols from dlwrap are never nullptr, but `loaded` might return false \
- */ \
- return dlwrap::loaded<name>(); \
+ /* If symbol wasn't dlwrapped, i.e name##_loaded == nullptr and is not \
+ * nullptr, it means the symbol was linked directly, so we can call it */ \
+ if (dlwrap::name##_loaded == nullptr) \
+ return true; \
+ /* Symbol is not nullptr and it was dlwrapped, all symbols on Windows go \
+ * here*/ \
+ return dlwrap::name##_loaded(); \
}
namespace api_helper {
diff --git a/offload/plugins-nextgen/common/include/DLWrap.h b/offload/plugins-nextgen/common/include/DLWrap.h
index 16f5a86911da3..0a33e8ef97db7 100644
--- a/offload/plugins-nextgen/common/include/DLWrap.h
+++ b/offload/plugins-nextgen/common/include/DLWrap.h
@@ -137,10 +137,6 @@ template <size_t Requested, size_t Required> constexpr void verboseAssert() {
static_assert(Requested == Required, "Arity Error");
}
-// Template to check if a symbol was loaded successfully.
-// Returns true for symbols that were not wrapped by dlwrap.
-template <auto Fn> bool loaded() { return true; }
-
} // namespace dlwrap
#define DLWRAP_INSTANTIATE(SYM_DEF, SYM_USE, ARITY) \
@@ -173,9 +169,7 @@ template <auto Fn> bool loaded() { return true; }
return reinterpret_cast<T::FunctionType>(P); \
} \
}; \
- template <> bool loaded<&(::SYMBOL)>() { \
- return SYMBOL##_Trait::get() != nullptr; \
- } \
+ bool SYMBOL##_loaded() { return SYMBOL##_Trait::get() != nullptr; } \
}
#define DLWRAP_IMPL(SYMBOL, ARITY) \
More information about the llvm-commits
mailing list