Skip to content

Commit 8acfa0f

Browse files
committed
[Offload] Add Error Codes to PluginInterface
A new ErrorCode enumeration is present in PluginInterface which can be used when returning an llvm::Error from offload and PluginInterface functions. This enum must be kept up to sync with liboffload's ol_errc_t enum, so both are automatically generated from liboffload's enum definition. Some error codes have also been shuffled around to allow for future work. Note that this patch only adds the machinery; actual error codes will be added in a future patch.
1 parent 18d1426 commit 8acfa0f

File tree

15 files changed

+207
-78
lines changed

15 files changed

+207
-78
lines changed

offload/liboffload/API/APIDefs.td

+2-1
Original file line numberDiff line numberDiff line change
@@ -152,9 +152,10 @@ class Function : APIObject {
152152
AddHandleChecksToReturns<params, returns_with_def>.returns_out>.returns_out;
153153
}
154154

155-
class Etor<string Name, string Desc> {
155+
class Etor<string Name, string Desc, int Value=-1> {
156156
string name = Name;
157157
string desc = Desc;
158+
int value = Value;
158159
string tagged_type;
159160
}
160161

offload/liboffload/API/CMakeLists.txt

+7-3
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,17 @@ if (CLANG_FORMAT)
1111
tablegen(OFFLOAD OffloadFuncs.inc -gen-func-names)
1212
tablegen(OFFLOAD OffloadImplFuncDecls.inc -gen-impl-func-decls)
1313
tablegen(OFFLOAD OffloadPrint.hpp -gen-print-header)
14+
tablegen(OFFLOAD OffloadErrcodes.inc -gen-errcodes)
1415

15-
set(OFFLOAD_GENERATED_FILES ${TABLEGEN_OUTPUT})
16+
set(FILES_TO_COPY "OffloadAPI.h;OffloadEntryPoints.inc;OffloadFuncs.inc;OffloadImplFuncDecls.inc;OffloadPrint.hpp")
17+
set(GEN_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../include/generated)
1618
add_public_tablegen_target(OffloadGenerate)
1719
add_custom_command(TARGET OffloadGenerate POST_BUILD COMMAND ${CLANG_FORMAT}
18-
-i ${OFFLOAD_GENERATED_FILES})
20+
-i ${TABLEGEN_OUTPUT})
1921
add_custom_command(TARGET OffloadGenerate POST_BUILD COMMAND ${CMAKE_COMMAND}
20-
-E copy_if_different ${OFFLOAD_GENERATED_FILES} "${CMAKE_CURRENT_SOURCE_DIR}/../include/generated")
22+
-E copy_if_different ${FILES_TO_COPY} ${GEN_DIR})
23+
add_custom_command(TARGET OffloadGenerate POST_BUILD COMMAND ${CMAKE_COMMAND}
24+
-E copy_if_different OffloadErrcodes.inc "${LIBOFFLOAD_ROOT}/../plugins-nextgen/common/include/OffloadErrcodes.inc")
2125
else()
2226
message(WARNING "clang-format was not found, so the OffloadGenerate target\
2327
will not be available. Offload will still build, but you will not be\

offload/liboffload/API/Common.td

+13-9
Original file line numberDiff line numberDiff line change
@@ -83,26 +83,30 @@ def : Typedef {
8383
let value = "void *";
8484
}
8585

86-
def : Enum {
86+
def ErrorCode : Enum {
8787
let name = "ol_errc_t";
8888
let desc = "Defines Return/Error codes";
8989
let etors =[
90-
Etor<"SUCCESS", "Success">,
91-
Etor<"INVALID_VALUE", "Invalid Value">,
90+
Etor<"SUCCESS", "Success", 0>,
91+
92+
// Universal errors
93+
Etor<"INVALID_NULL_POINTER", "A pointer argument is null when it should not be">,
94+
Etor<"INVALID_ARGUMENT", "An argument is invalid">,
95+
Etor<"OUT_OF_RESOURCES", "Out of resources">,
96+
Etor<"UNSUPPORTED", "generic error code for unsupported features and enums">,
97+
98+
// Liboffload specific errors
99+
Etor<"INVALID_VALUE", "Invalid Value", 0x1000>,
92100
Etor<"INVALID_PLATFORM", "Invalid platform">,
93101
Etor<"INVALID_DEVICE", "Invalid device">,
94102
Etor<"INVALID_QUEUE", "Invalid queue">,
95103
Etor<"INVALID_EVENT", "Invalid event">,
96104
Etor<"INVALID_KERNEL_NAME", "Named kernel not found in the program binary">,
97-
Etor<"OUT_OF_RESOURCES", "Out of resources">,
98-
Etor<"UNSUPPORTED_FEATURE", "generic error code for unsupported features">,
99-
Etor<"INVALID_ARGUMENT", "generic error code for invalid arguments">,
100105
Etor<"INVALID_NULL_HANDLE", "handle argument is not valid">,
101-
Etor<"INVALID_NULL_POINTER", "pointer argument may not be nullptr">,
102106
Etor<"INVALID_SIZE", "invalid size or dimensions (e.g., must not be zero, or is out of bounds)">,
103107
Etor<"INVALID_ENUMERATION", "enumerator argument is not valid">,
104-
Etor<"UNSUPPORTED_ENUMERATION", "enumerator argument is not supported by the device">,
105-
Etor<"UNKNOWN", "Unknown or internal error">
108+
109+
Etor<"UNKNOWN", "Unknown or internal error", 0x10000>
106110
];
107111
}
108112

offload/liboffload/CMakeLists.txt

+2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
set(LIBOFFLOAD_ROOT "${CMAKE_CURRENT_SOURCE_DIR}")
2+
13
add_subdirectory(API)
24

35
add_llvm_library(

offload/liboffload/include/OffloadImpl.hpp

+11-3
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
//===----------------------------------------------------------------------===//
88
#pragma once
99

10+
#include "PluginInterface.h"
1011
#include <OffloadAPI.h>
1112
#include <iostream>
1213
#include <memory>
@@ -93,9 +94,7 @@ struct ol_impl_result_t {
9394
ol_errc_t ErrCode;
9495
llvm::StringRef Details;
9596
llvm::handleAllErrors(std::move(Error), [&](llvm::StringError &Err) {
96-
// TODO: PluginInterface doesn't yet have a way to communicate offload
97-
// error codes
98-
ErrCode = OL_ERRC_UNKNOWN;
97+
ErrCode = GetErrorCode(Err.convertToErrorCode());
9998
Details = errorStrs().insert(Err.getMessage()).first->getKeyData();
10099
});
101100

@@ -105,5 +104,14 @@ struct ol_impl_result_t {
105104
operator ol_result_t() { return Result; }
106105

107106
private:
107+
static ol_errc_t GetErrorCode(std::error_code Code) {
108+
if (Code.category() == llvm::omp::target::plugin::make_error_code(
109+
llvm::omp::target::plugin::ErrorCode::SUCCESS)
110+
.category()) {
111+
return static_cast<ol_errc_t>(Code.value());
112+
}
113+
return OL_ERRC_UNKNOWN;
114+
}
115+
108116
ol_result_t Result;
109117
};

offload/liboffload/include/generated/OffloadAPI.h

+41-42
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,45 @@
1717
extern "C" {
1818
#endif
1919

20+
///////////////////////////////////////////////////////////////////////////////
21+
/// @brief Defines Return/Error codes
22+
typedef enum ol_errc_t {
23+
/// Success
24+
OL_ERRC_SUCCESS = 0,
25+
/// A pointer argument is null when it should not be
26+
OL_ERRC_INVALID_NULL_POINTER = 1,
27+
/// An argument is invalid
28+
OL_ERRC_INVALID_ARGUMENT = 2,
29+
/// Out of resources
30+
OL_ERRC_OUT_OF_RESOURCES = 3,
31+
/// generic error code for unsupported features and enums
32+
OL_ERRC_UNSUPPORTED = 4,
33+
/// Invalid Value
34+
OL_ERRC_INVALID_VALUE = 4096,
35+
/// Invalid platform
36+
OL_ERRC_INVALID_PLATFORM = 4097,
37+
/// Invalid device
38+
OL_ERRC_INVALID_DEVICE = 4098,
39+
/// Invalid queue
40+
OL_ERRC_INVALID_QUEUE = 4099,
41+
/// Invalid event
42+
OL_ERRC_INVALID_EVENT = 4100,
43+
/// Named kernel not found in the program binary
44+
OL_ERRC_INVALID_KERNEL_NAME = 4101,
45+
/// handle argument is not valid
46+
OL_ERRC_INVALID_NULL_HANDLE = 4102,
47+
/// invalid size or dimensions (e.g., must not be zero, or is out of bounds)
48+
OL_ERRC_INVALID_SIZE = 4103,
49+
/// enumerator argument is not valid
50+
OL_ERRC_INVALID_ENUMERATION = 4104,
51+
/// Unknown or internal error
52+
OL_ERRC_UNKNOWN = 65536,
53+
/// @cond
54+
OL_ERRC_FORCE_UINT32 = 0x7fffffff
55+
/// @endcond
56+
57+
} ol_errc_t;
58+
2059
///////////////////////////////////////////////////////////////////////////////
2160
#ifndef OL_VERSION_MAJOR
2261
/// @brief Major version of the Offload API
@@ -101,47 +140,6 @@ typedef struct ol_program_impl_t *ol_program_handle_t;
101140
/// @brief Handle of kernel object
102141
typedef void *ol_kernel_handle_t;
103142

104-
///////////////////////////////////////////////////////////////////////////////
105-
/// @brief Defines Return/Error codes
106-
typedef enum ol_errc_t {
107-
/// Success
108-
OL_ERRC_SUCCESS = 0,
109-
/// Invalid Value
110-
OL_ERRC_INVALID_VALUE = 1,
111-
/// Invalid platform
112-
OL_ERRC_INVALID_PLATFORM = 2,
113-
/// Invalid device
114-
OL_ERRC_INVALID_DEVICE = 3,
115-
/// Invalid queue
116-
OL_ERRC_INVALID_QUEUE = 4,
117-
/// Invalid event
118-
OL_ERRC_INVALID_EVENT = 5,
119-
/// Named kernel not found in the program binary
120-
OL_ERRC_INVALID_KERNEL_NAME = 6,
121-
/// Out of resources
122-
OL_ERRC_OUT_OF_RESOURCES = 7,
123-
/// generic error code for unsupported features
124-
OL_ERRC_UNSUPPORTED_FEATURE = 8,
125-
/// generic error code for invalid arguments
126-
OL_ERRC_INVALID_ARGUMENT = 9,
127-
/// handle argument is not valid
128-
OL_ERRC_INVALID_NULL_HANDLE = 10,
129-
/// pointer argument may not be nullptr
130-
OL_ERRC_INVALID_NULL_POINTER = 11,
131-
/// invalid size or dimensions (e.g., must not be zero, or is out of bounds)
132-
OL_ERRC_INVALID_SIZE = 12,
133-
/// enumerator argument is not valid
134-
OL_ERRC_INVALID_ENUMERATION = 13,
135-
/// enumerator argument is not supported by the device
136-
OL_ERRC_UNSUPPORTED_ENUMERATION = 14,
137-
/// Unknown or internal error
138-
OL_ERRC_UNKNOWN = 15,
139-
/// @cond
140-
OL_ERRC_FORCE_UINT32 = 0x7fffffff
141-
/// @endcond
142-
143-
} ol_errc_t;
144-
145143
///////////////////////////////////////////////////////////////////////////////
146144
/// @brief Details of the error condition returned by an API call
147145
typedef struct ol_error_struct_t {
@@ -477,7 +475,8 @@ OL_APIEXPORT ol_result_t OL_APICALL olMemFree(
477475
/// @brief Enqueue a memcpy operation.
478476
///
479477
/// @details
480-
/// - For host pointers, use the device returned by olGetHostDevice
478+
/// - For host pointers, use the host device belonging to the
479+
/// OL_PLATFORM_BACKEND_HOST platform.
481480
/// - If a queue is specified, at least one device must be a non-host device
482481
/// - If a queue is not specified, the memcpy happens synchronously
483482
///

offload/liboffload/include/generated/OffloadPrint.hpp

+12-15
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,18 @@ inline llvm::raw_ostream &operator<<(llvm::raw_ostream &os,
4949
case OL_ERRC_SUCCESS:
5050
os << "OL_ERRC_SUCCESS";
5151
break;
52+
case OL_ERRC_INVALID_NULL_POINTER:
53+
os << "OL_ERRC_INVALID_NULL_POINTER";
54+
break;
55+
case OL_ERRC_INVALID_ARGUMENT:
56+
os << "OL_ERRC_INVALID_ARGUMENT";
57+
break;
58+
case OL_ERRC_OUT_OF_RESOURCES:
59+
os << "OL_ERRC_OUT_OF_RESOURCES";
60+
break;
61+
case OL_ERRC_UNSUPPORTED:
62+
os << "OL_ERRC_UNSUPPORTED";
63+
break;
5264
case OL_ERRC_INVALID_VALUE:
5365
os << "OL_ERRC_INVALID_VALUE";
5466
break;
@@ -67,30 +79,15 @@ inline llvm::raw_ostream &operator<<(llvm::raw_ostream &os,
6779
case OL_ERRC_INVALID_KERNEL_NAME:
6880
os << "OL_ERRC_INVALID_KERNEL_NAME";
6981
break;
70-
case OL_ERRC_OUT_OF_RESOURCES:
71-
os << "OL_ERRC_OUT_OF_RESOURCES";
72-
break;
73-
case OL_ERRC_UNSUPPORTED_FEATURE:
74-
os << "OL_ERRC_UNSUPPORTED_FEATURE";
75-
break;
76-
case OL_ERRC_INVALID_ARGUMENT:
77-
os << "OL_ERRC_INVALID_ARGUMENT";
78-
break;
7982
case OL_ERRC_INVALID_NULL_HANDLE:
8083
os << "OL_ERRC_INVALID_NULL_HANDLE";
8184
break;
82-
case OL_ERRC_INVALID_NULL_POINTER:
83-
os << "OL_ERRC_INVALID_NULL_POINTER";
84-
break;
8585
case OL_ERRC_INVALID_SIZE:
8686
os << "OL_ERRC_INVALID_SIZE";
8787
break;
8888
case OL_ERRC_INVALID_ENUMERATION:
8989
os << "OL_ERRC_INVALID_ENUMERATION";
9090
break;
91-
case OL_ERRC_UNSUPPORTED_ENUMERATION:
92-
os << "OL_ERRC_UNSUPPORTED_ENUMERATION";
93-
break;
9491
case OL_ERRC_UNKNOWN:
9592
os << "OL_ERRC_UNKNOWN";
9693
break;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
//===- Auto-generated file, part of the LLVM/Offload project --------------===//
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+
#ifndef OFFLOAD_ERRC
10+
#error Please define the macro OFFLOAD_ERRCODE(Name, Desc, Value)
11+
#endif
12+
13+
// Error codes are shared between PluginInterface and liboffload.
14+
// To add new error codes, add them to offload/liboffload/API/Common.td and run
15+
// the GenerateOffload target.
16+
17+
OFFLOAD_ERRC(SUCCESS, "Success", 0)
18+
OFFLOAD_ERRC(INVALID_NULL_POINTER,
19+
"A pointer argument is null when it should not be", 1)
20+
OFFLOAD_ERRC(INVALID_ARGUMENT, "An argument is invalid", 2)
21+
OFFLOAD_ERRC(OUT_OF_RESOURCES, "Out of resources", 3)
22+
OFFLOAD_ERRC(UNSUPPORTED,
23+
"generic error code for unsupported features and enums", 4)
24+
OFFLOAD_ERRC(INVALID_VALUE, "Invalid Value", 4096)
25+
OFFLOAD_ERRC(INVALID_PLATFORM, "Invalid platform", 4097)
26+
OFFLOAD_ERRC(INVALID_DEVICE, "Invalid device", 4098)
27+
OFFLOAD_ERRC(INVALID_QUEUE, "Invalid queue", 4099)
28+
OFFLOAD_ERRC(INVALID_EVENT, "Invalid event", 4100)
29+
OFFLOAD_ERRC(INVALID_KERNEL_NAME,
30+
"Named kernel not found in the program binary", 4101)
31+
OFFLOAD_ERRC(INVALID_NULL_HANDLE, "handle argument is not valid", 4102)
32+
OFFLOAD_ERRC(
33+
INVALID_SIZE,
34+
"invalid size or dimensions (e.g., must not be zero, or is out of bounds)",
35+
4103)
36+
OFFLOAD_ERRC(INVALID_ENUMERATION, "enumerator argument is not valid", 4104)
37+
OFFLOAD_ERRC(UNKNOWN, "Unknown or internal error", 65536)

offload/plugins-nextgen/common/include/PluginInterface.h

+37-1
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,30 @@ struct GenericKernelTy;
5858
struct GenericDeviceTy;
5959
struct RecordReplayTy;
6060

61+
enum class ErrorCode {
62+
#define OFFLOAD_ERRC(Name, _, Value) Name = Value,
63+
#include "OffloadErrcodes.inc"
64+
#undef OFFLOAD_ERRC
65+
};
66+
67+
class OffloadErrorCategory : public std::error_category {
68+
const char *name() const noexcept override { return "Offload Error"; }
69+
std::string message(int ev) const override {
70+
switch (static_cast<ErrorCode>(ev)) {
71+
#define OFFLOAD_ERRC(Name, Desc, Value) \
72+
case ErrorCode::Name: \
73+
return #Desc;
74+
#include "OffloadErrcodes.inc"
75+
#undef OFFLOAD_ERRC
76+
}
77+
}
78+
};
79+
80+
inline std::error_code make_error_code(ErrorCode EC) {
81+
static OffloadErrorCategory Cat{};
82+
return {static_cast<int>(EC), Cat};
83+
}
84+
6185
/// Class that wraps the __tgt_async_info to simply its usage. In case the
6286
/// object is constructed without a valid __tgt_async_info, the object will use
6387
/// an internal one and will synchronize the current thread with the pending
@@ -1385,7 +1409,13 @@ static inline Error success() { return Error::success(); }
13851409
/// Create a string error.
13861410
template <typename... ArgsTy>
13871411
static Error error(const char *ErrFmt, ArgsTy... Args) {
1388-
return createStringError(inconvertibleErrorCode(), ErrFmt, Args...);
1412+
return createStringError(ErrorCode::UNKNOWN, ErrFmt, Args...);
1413+
}
1414+
1415+
/// Create a string error.
1416+
template <typename... ArgsTy>
1417+
static Error error(ErrorCode Code, const char *ErrFmt, ArgsTy... Args) {
1418+
return createStringError(Code, ErrFmt, Args...);
13891419
}
13901420

13911421
/// Check the plugin-specific error code and return an error or success
@@ -1596,4 +1626,10 @@ template <typename ResourceRef> class GenericDeviceResourceManagerTy {
15961626
} // namespace omp
15971627
} // namespace llvm
15981628

1629+
namespace std {
1630+
template <>
1631+
struct is_error_code_enum<llvm::omp::target::plugin::ErrorCode>
1632+
: std::true_type {};
1633+
} // namespace std
1634+
15991635
#endif // OPENMP_LIBOMPTARGET_PLUGINS_COMMON_PLUGININTERFACE_H

offload/tools/offload-tblgen/APIGen.cpp

+3
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,9 @@ static void ProcessEnum(const EnumRec &Enum, raw_ostream &OS) {
132132

133133
uint32_t EtorVal = 0;
134134
for (const auto &EnumVal : Enum.getValues()) {
135+
if (auto NewVal = EnumVal.getEnumValue()) {
136+
EtorVal = *NewVal;
137+
}
135138
if (Enum.isTyped()) {
136139
OS << MakeComment(
137140
formatv("[{0}] {1}", EnumVal.getTaggedType(), EnumVal.getDesc())

offload/tools/offload-tblgen/CMakeLists.txt

+1-2
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ add_tablegen(offload-tblgen OFFLOAD
1313
EXPORT OFFLOAD
1414
APIGen.cpp
1515
EntryPointGen.cpp
16-
FuncsGen.cpp
16+
MiscGen.cpp
1717
GenCommon.hpp
1818
Generators.hpp
1919
offload-tblgen.cpp
@@ -23,4 +23,3 @@ add_tablegen(offload-tblgen OFFLOAD
2323

2424
set(OFFLOAD_TABLEGEN_EXE "${OFFLOAD_TABLEGEN_EXE}" CACHE INTERNAL "")
2525
set(OFFLOAD_TABLEGEN_TARGET "${OFFLOAD_TABLEGEN_TARGET}" CACHE INTERNAL "")
26-

offload/tools/offload-tblgen/Generators.hpp

+2
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,5 @@ void EmitOffloadPrintHeader(const llvm::RecordKeeper &Records,
2121
llvm::raw_ostream &OS);
2222
void EmitOffloadExports(const llvm::RecordKeeper &Records,
2323
llvm::raw_ostream &OS);
24+
void EmitOffloadErrcodes(const llvm::RecordKeeper &Records,
25+
llvm::raw_ostream &OS);

0 commit comments

Comments
 (0)