[llvm] [Offload] Check for initialization (PR #144370)

Ross Brunton via llvm-commits llvm-commits at lists.llvm.org
Fri Jun 20 06:27:45 PDT 2025


https://github.com/RossBrunton updated https://github.com/llvm/llvm-project/pull/144370

>From baf070f7a367af3f874f1b96fe8f922cb06a0684 Mon Sep 17 00:00:00 2001
From: Ross Brunton <ross at codeplay.com>
Date: Mon, 16 Jun 2025 16:20:39 +0100
Subject: [PATCH 1/3] [Offload] Check for initialization

All entry points (except olInit) now check that offload has been
initialized. If not, a new `OL_ERRC_UNINITIALIZED` error is returned.
---
 offload/liboffload/API/Common.td               |  1 +
 offload/liboffload/include/OffloadImpl.hpp     |  1 +
 offload/liboffload/src/OffloadImpl.cpp         |  3 ++-
 offload/tools/offload-tblgen/EntryPointGen.cpp | 12 ++++++++++++
 4 files changed, 16 insertions(+), 1 deletion(-)

diff --git a/offload/liboffload/API/Common.td b/offload/liboffload/API/Common.td
index 8a2ecd6c6e8f4..cd8c3c63fde81 100644
--- a/offload/liboffload/API/Common.td
+++ b/offload/liboffload/API/Common.td
@@ -106,6 +106,7 @@ def ErrorCode : Enum {
     Etor<"ASSEMBLE_FAILURE", "assembler failure while processing binary image">,
     Etor<"LINK_FAILURE", "linker failure while processing binary image">,
     Etor<"BACKEND_FAILURE", "the plugin backend is in an invalid or unsupported state">,
+    Etor<"UNINITIALIZED", "not initialized">,
 
     // Handle related errors - only makes sense for liboffload
     Etor<"INVALID_NULL_HANDLE", "a handle argument is null when it should not be">,
diff --git a/offload/liboffload/include/OffloadImpl.hpp b/offload/liboffload/include/OffloadImpl.hpp
index a12d8c47a180b..3429b2bae7a5c 100644
--- a/offload/liboffload/include/OffloadImpl.hpp
+++ b/offload/liboffload/include/OffloadImpl.hpp
@@ -26,6 +26,7 @@ namespace llvm {
 namespace offload {
 bool isTracingEnabled();
 bool isValidationEnabled();
+bool isOffloadInited();
 } // namespace offload
 } // namespace llvm
 
diff --git a/offload/liboffload/src/OffloadImpl.cpp b/offload/liboffload/src/OffloadImpl.cpp
index f02497c0a6331..59401e82f4f34 100644
--- a/offload/liboffload/src/OffloadImpl.cpp
+++ b/offload/liboffload/src/OffloadImpl.cpp
@@ -120,9 +120,10 @@ struct OffloadContext {
 
 // If the context is uninited, then we assume tracing is disabled
 bool isTracingEnabled() {
-  return OffloadContextVal && OffloadContext::get().TracingEnabled;
+  return isOffloadInited() && OffloadContext::get().TracingEnabled;
 }
 bool isValidationEnabled() { return OffloadContext::get().ValidationEnabled; }
+bool isOffloadInited() { return OffloadContextVal != nullptr; }
 
 template <typename HandleT> Error olDestroy(HandleT Handle) {
   delete Handle;
diff --git a/offload/tools/offload-tblgen/EntryPointGen.cpp b/offload/tools/offload-tblgen/EntryPointGen.cpp
index 13aa0d1f63187..59b8045972466 100644
--- a/offload/tools/offload-tblgen/EntryPointGen.cpp
+++ b/offload/tools/offload-tblgen/EntryPointGen.cpp
@@ -82,6 +82,10 @@ static void EmitEntryPointFunc(const FunctionRec &F, raw_ostream &OS) {
   }
   OS << ") {\n";
 
+  // Check offload is inited
+  if (F.getName() != "olInit")
+    OS << "if (!llvm::offload::isOffloadInited()) return &UninitError;";
+
   // Emit pre-call prints
   OS << TAB_1 "if (llvm::offload::isTracingEnabled()) {\n";
   OS << formatv(TAB_2 "llvm::errs() << \"---> {0}\";\n", F.getName());
@@ -143,6 +147,14 @@ static void EmitCodeLocWrapper(const FunctionRec &F, raw_ostream &OS) {
 
 void EmitOffloadEntryPoints(const RecordKeeper &Records, raw_ostream &OS) {
   OS << GenericHeader;
+
+  constexpr const char *UninitMessage =
+      "liboffload has not been initialized - please call olInit before using "
+      "this API";
+  OS << formatv("static {0}_error_struct_t UninitError = "
+                "{{{1}_ERRC_UNINITIALIZED, \"{2}\"};",
+                PrefixLower, PrefixUpper, UninitMessage);
+
   for (auto *R : Records.getAllDerivedDefinitions("Function")) {
     EmitValidationFunc(FunctionRec{R}, OS);
     EmitEntryPointFunc(FunctionRec{R}, OS);

>From 10293ea99c0c4bd55aa04c052e3c2559d5c664b1 Mon Sep 17 00:00:00 2001
From: Ross Brunton <ross at codeplay.com>
Date: Fri, 20 Jun 2025 10:46:24 +0100
Subject: [PATCH 2/3] Add test

---
 offload/unittests/OffloadAPI/CMakeLists.txt   |  4 ++++
 .../OffloadAPI/common/Environment.cpp         |  2 ++
 offload/unittests/OffloadAPI/init/olInit.cpp  | 22 +++++++++++++++++++
 3 files changed, 28 insertions(+)
 create mode 100644 offload/unittests/OffloadAPI/init/olInit.cpp

diff --git a/offload/unittests/OffloadAPI/CMakeLists.txt b/offload/unittests/OffloadAPI/CMakeLists.txt
index 2844b675e5de1..05e862865ed33 100644
--- a/offload/unittests/OffloadAPI/CMakeLists.txt
+++ b/offload/unittests/OffloadAPI/CMakeLists.txt
@@ -12,6 +12,10 @@ add_offload_unittest("event"
     event/olDestroyEvent.cpp
     event/olWaitEvent.cpp)
 
+add_offload_unittest("init"
+    init/olInit.cpp)
+target_compile_definitions("init.unittests" PRIVATE DISABLE_WRAPPER)
+
 add_offload_unittest("kernel"
     kernel/olGetKernel.cpp
     kernel/olLaunchKernel.cpp)
diff --git a/offload/unittests/OffloadAPI/common/Environment.cpp b/offload/unittests/OffloadAPI/common/Environment.cpp
index 943347246b6d2..ef092cd4187d3 100644
--- a/offload/unittests/OffloadAPI/common/Environment.cpp
+++ b/offload/unittests/OffloadAPI/common/Environment.cpp
@@ -17,11 +17,13 @@ using namespace llvm;
 
 // Wrapper so we don't have to constantly init and shutdown Offload in every
 // test, while having sensible lifetime for the platform environment
+#ifndef DISABLE_WRAPPER
 struct OffloadInitWrapper {
   OffloadInitWrapper() { olInit(); }
   ~OffloadInitWrapper() { olShutDown(); }
 };
 static OffloadInitWrapper Wrapper{};
+#endif
 
 static cl::opt<std::string>
     SelectedPlatform("platform", cl::desc("Only test the specified platform"),
diff --git a/offload/unittests/OffloadAPI/init/olInit.cpp b/offload/unittests/OffloadAPI/init/olInit.cpp
new file mode 100644
index 0000000000000..8e27e77cd0fb5
--- /dev/null
+++ b/offload/unittests/OffloadAPI/init/olInit.cpp
@@ -0,0 +1,22 @@
+//===------- Offload API tests - olInit -----------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// NOTE: For this test suite, the implicit olInit/olShutDown doesn't happen, so
+// tests have to do it themselves
+
+#include "../common/Fixtures.hpp"
+#include <OffloadAPI.h>
+#include <gtest/gtest.h>
+
+struct olInitTest : ::testing::Test {};
+
+TEST_F(olInitTest, Uninitialized) {
+  ASSERT_ERROR(OL_ERRC_UNINITIALIZED,
+               olIterateDevices(
+                   [](ol_device_handle_t, void *) { return false; }, nullptr));
+}

>From f0b82625f017a068f3ea28bad984019b698a2fab Mon Sep 17 00:00:00 2001
From: Ross Brunton <ross at codeplay.com>
Date: Fri, 20 Jun 2025 14:27:28 +0100
Subject: [PATCH 3/3] Uninit -> Uninitialized

---
 offload/liboffload/include/OffloadImpl.hpp     | 2 +-
 offload/liboffload/src/OffloadImpl.cpp         | 4 ++--
 offload/tools/offload-tblgen/EntryPointGen.cpp | 4 ++--
 3 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/offload/liboffload/include/OffloadImpl.hpp b/offload/liboffload/include/OffloadImpl.hpp
index 3429b2bae7a5c..f98164d5e178a 100644
--- a/offload/liboffload/include/OffloadImpl.hpp
+++ b/offload/liboffload/include/OffloadImpl.hpp
@@ -26,7 +26,7 @@ namespace llvm {
 namespace offload {
 bool isTracingEnabled();
 bool isValidationEnabled();
-bool isOffloadInited();
+bool isOffloadInitialized();
 } // namespace offload
 } // namespace llvm
 
diff --git a/offload/liboffload/src/OffloadImpl.cpp b/offload/liboffload/src/OffloadImpl.cpp
index 59401e82f4f34..8a487563f6107 100644
--- a/offload/liboffload/src/OffloadImpl.cpp
+++ b/offload/liboffload/src/OffloadImpl.cpp
@@ -120,10 +120,10 @@ struct OffloadContext {
 
 // If the context is uninited, then we assume tracing is disabled
 bool isTracingEnabled() {
-  return isOffloadInited() && OffloadContext::get().TracingEnabled;
+  return isOffloadInitialized() && OffloadContext::get().TracingEnabled;
 }
 bool isValidationEnabled() { return OffloadContext::get().ValidationEnabled; }
-bool isOffloadInited() { return OffloadContextVal != nullptr; }
+bool isOffloadInitialized() { return OffloadContextVal != nullptr; }
 
 template <typename HandleT> Error olDestroy(HandleT Handle) {
   delete Handle;
diff --git a/offload/tools/offload-tblgen/EntryPointGen.cpp b/offload/tools/offload-tblgen/EntryPointGen.cpp
index 59b8045972466..4e42e4905b993 100644
--- a/offload/tools/offload-tblgen/EntryPointGen.cpp
+++ b/offload/tools/offload-tblgen/EntryPointGen.cpp
@@ -82,9 +82,9 @@ static void EmitEntryPointFunc(const FunctionRec &F, raw_ostream &OS) {
   }
   OS << ") {\n";
 
-  // Check offload is inited
+  // Check offload is initialized
   if (F.getName() != "olInit")
-    OS << "if (!llvm::offload::isOffloadInited()) return &UninitError;";
+    OS << "if (!llvm::offload::isOffloadInitialized()) return &UninitError;";
 
   // Emit pre-call prints
   OS << TAB_1 "if (llvm::offload::isTracingEnabled()) {\n";



More information about the llvm-commits mailing list