Skip to content

Commit e0633d5

Browse files
authored
[Offload] Check for initialization (#144370)
All entry points (except olInit) now check that offload has been initialized. If not, a new `OL_ERRC_UNINITIALIZED` error is returned.
1 parent bd36f73 commit e0633d5

File tree

7 files changed

+44
-1
lines changed

7 files changed

+44
-1
lines changed

offload/liboffload/API/Common.td

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ def ErrorCode : Enum {
106106
Etor<"ASSEMBLE_FAILURE", "assembler failure while processing binary image">,
107107
Etor<"LINK_FAILURE", "linker failure while processing binary image">,
108108
Etor<"BACKEND_FAILURE", "the plugin backend is in an invalid or unsupported state">,
109+
Etor<"UNINITIALIZED", "not initialized">,
109110

110111
// Handle related errors - only makes sense for liboffload
111112
Etor<"INVALID_NULL_HANDLE", "a handle argument is null when it should not be">,

offload/liboffload/include/OffloadImpl.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ namespace llvm {
2626
namespace offload {
2727
bool isTracingEnabled();
2828
bool isValidationEnabled();
29+
bool isOffloadInitialized();
2930
} // namespace offload
3031
} // namespace llvm
3132

offload/liboffload/src/OffloadImpl.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,9 +120,10 @@ struct OffloadContext {
120120

121121
// If the context is uninited, then we assume tracing is disabled
122122
bool isTracingEnabled() {
123-
return OffloadContextVal && OffloadContext::get().TracingEnabled;
123+
return isOffloadInitialized() && OffloadContext::get().TracingEnabled;
124124
}
125125
bool isValidationEnabled() { return OffloadContext::get().ValidationEnabled; }
126+
bool isOffloadInitialized() { return OffloadContextVal != nullptr; }
126127

127128
template <typename HandleT> Error olDestroy(HandleT Handle) {
128129
delete Handle;

offload/tools/offload-tblgen/EntryPointGen.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,10 @@ static void EmitEntryPointFunc(const FunctionRec &F, raw_ostream &OS) {
8282
}
8383
OS << ") {\n";
8484

85+
// Check offload is initialized
86+
if (F.getName() != "olInit")
87+
OS << "if (!llvm::offload::isOffloadInitialized()) return &UninitError;";
88+
8589
// Emit pre-call prints
8690
OS << TAB_1 "if (llvm::offload::isTracingEnabled()) {\n";
8791
OS << formatv(TAB_2 "llvm::errs() << \"---> {0}\";\n", F.getName());
@@ -143,6 +147,14 @@ static void EmitCodeLocWrapper(const FunctionRec &F, raw_ostream &OS) {
143147

144148
void EmitOffloadEntryPoints(const RecordKeeper &Records, raw_ostream &OS) {
145149
OS << GenericHeader;
150+
151+
constexpr const char *UninitMessage =
152+
"liboffload has not been initialized - please call olInit before using "
153+
"this API";
154+
OS << formatv("static {0}_error_struct_t UninitError = "
155+
"{{{1}_ERRC_UNINITIALIZED, \"{2}\"};",
156+
PrefixLower, PrefixUpper, UninitMessage);
157+
146158
for (auto *R : Records.getAllDerivedDefinitions("Function")) {
147159
EmitValidationFunc(FunctionRec{R}, OS);
148160
EmitEntryPointFunc(FunctionRec{R}, OS);

offload/unittests/OffloadAPI/CMakeLists.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@ add_offload_unittest("event"
1212
event/olDestroyEvent.cpp
1313
event/olWaitEvent.cpp)
1414

15+
add_offload_unittest("init"
16+
init/olInit.cpp)
17+
target_compile_definitions("init.unittests" PRIVATE DISABLE_WRAPPER)
18+
1519
add_offload_unittest("kernel"
1620
kernel/olGetKernel.cpp
1721
kernel/olLaunchKernel.cpp)

offload/unittests/OffloadAPI/common/Environment.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,13 @@ using namespace llvm;
1717

1818
// Wrapper so we don't have to constantly init and shutdown Offload in every
1919
// test, while having sensible lifetime for the platform environment
20+
#ifndef DISABLE_WRAPPER
2021
struct OffloadInitWrapper {
2122
OffloadInitWrapper() { olInit(); }
2223
~OffloadInitWrapper() { olShutDown(); }
2324
};
2425
static OffloadInitWrapper Wrapper{};
26+
#endif
2527

2628
static cl::opt<std::string>
2729
SelectedPlatform("platform", cl::desc("Only test the specified platform"),
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
//===------- Offload API tests - olInit -----------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
// NOTE: For this test suite, the implicit olInit/olShutDown doesn't happen, so
10+
// tests have to do it themselves
11+
12+
#include "../common/Fixtures.hpp"
13+
#include <OffloadAPI.h>
14+
#include <gtest/gtest.h>
15+
16+
struct olInitTest : ::testing::Test {};
17+
18+
TEST_F(olInitTest, Uninitialized) {
19+
ASSERT_ERROR(OL_ERRC_UNINITIALIZED,
20+
olIterateDevices(
21+
[](ol_device_handle_t, void *) { return false; }, nullptr));
22+
}

0 commit comments

Comments
 (0)