Skip to content

Commit cfe601c

Browse files
committed
Implement optional error details
1 parent e3b8ea8 commit cfe601c

File tree

7 files changed

+107
-16
lines changed

7 files changed

+107
-16
lines changed

offload/new-api/API/Common.td

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,4 +72,20 @@ def : Enum {
7272
Etor<"ERROR_UNSUPPORTED_ENUMERATION", "[Validation] enumerator argument is not supported by the device">,
7373
Etor<"ERROR_UNKNOWN", "Unknown or internal error">
7474
];
75-
}
75+
}
76+
77+
def : Function {
78+
let name = "offloadGetErrorDetails";
79+
let desc = "Get a detailed error message for the last error that occurred on this thread, if it exists";
80+
let details = [
81+
"When an Offload API call returns a return value other than OFFLOAD_RESULT_SUCCESS, the implementation *may* set an additional error message.",
82+
"If a further Offload call (excluding this function) is made on the same thread without checking "
83+
"its detailed error message with this function, that message should be considered lost.",
84+
"The returned char* is only valid until the next Offload function call on the same thread (excluding further calls to this function.)"
85+
];
86+
let params = [
87+
Param<"size_t*", "SizeRet", "Pointer to return the size of the available error message. A size of 0 indicates no message.", PARAM_OUT_OPTIONAL>,
88+
Param<"const char**", "DetailStringRet", "Pointer to return the error message string.", PARAM_OUT_OPTIONAL>
89+
];
90+
let returns = []; // Only SUCCESS is expected
91+
}

offload/new-api/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ endif()
2626
target_include_directories(offload_new PUBLIC
2727
${CMAKE_CURRENT_BINARY_DIR}
2828
${CMAKE_CURRENT_BINARY_DIR}/../include
29+
${CMAKE_CURRENT_SOURCE_DIR}/include
2930
${CMAKE_CURRENT_SOURCE_DIR}/../include
3031
${CMAKE_CURRENT_SOURCE_DIR}/../plugins-nextgen/common/include)
3132

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
//===- offload_impl.hpp- Implementation helpers for the Offload library ---===//
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+
#include <offload_api.h>
10+
#include <optional>
11+
#include <string>
12+
13+
#include "llvm/ADT/StringRef.h"
14+
15+
std::optional<std::string> &LastErrorDetails();
16+
17+
struct offload_impl_result_t {
18+
offload_impl_result_t() = delete;
19+
offload_impl_result_t(offload_result_t Result) : Result(Result) {
20+
LastErrorDetails() = std::nullopt;
21+
}
22+
23+
offload_impl_result_t(offload_result_t Result, std::string Details)
24+
: Result(Result) {
25+
assert(Result != OFFLOAD_RESULT_SUCCESS);
26+
LastErrorDetails() = Details;
27+
}
28+
29+
operator offload_result_t() { return Result; }
30+
31+
private:
32+
offload_result_t Result;
33+
};

offload/new-api/src/offload_impl.cpp

Lines changed: 36 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
#include "PluginManager.h"
1515
#include "helpers.hpp"
16+
#include "offload_impl.hpp"
1617
#include "llvm/Support/FormatVariadic.h"
1718
#include <offload_api.h>
1819

@@ -66,17 +67,37 @@ void initPlugins() {
6667
}
6768
}
6869

69-
offload_result_t offloadPlatformGet_impl(uint32_t NumEntries,
70-
offload_platform_handle_t *phPlatforms,
71-
uint32_t *pNumPlatforms) {
70+
offload_result_t offloadGetErrorDetails_impl(size_t *SizeRet,
71+
const char **DetailStringRet) {
72+
if (auto Details = LastErrorDetails()) {
73+
if (SizeRet) {
74+
*SizeRet = Details->size();
75+
}
76+
if (DetailStringRet) {
77+
*DetailStringRet = Details->c_str();
78+
}
79+
} else {
80+
if (SizeRet) {
81+
*SizeRet = 0;
82+
}
83+
}
84+
return OFFLOAD_RESULT_SUCCESS;
85+
}
86+
87+
offload_impl_result_t
88+
offloadPlatformGet_impl(uint32_t NumEntries,
89+
offload_platform_handle_t *phPlatforms,
90+
uint32_t *pNumPlatforms) {
7291
// It is expected that offloadPlatformGet is the first function to be called.
7392
// In future it may make sense to have a specific entry point for Offload
7493
// initialization, or expose explicit initialization of plugins.
7594
static std::once_flag InitFlag;
7695
std::call_once(InitFlag, initPlugins);
7796

7897
if (NumEntries > Platforms().size()) {
79-
return OFFLOAD_RESULT_ERROR_INVALID_SIZE;
98+
return {OFFLOAD_RESULT_ERROR_INVALID_SIZE,
99+
formatv("{0} platform(s) available but {1} requested.",
100+
Platforms().size(), NumEntries)};
80101
}
81102

82103
if (phPlatforms) {
@@ -93,7 +114,7 @@ offload_result_t offloadPlatformGet_impl(uint32_t NumEntries,
93114
return OFFLOAD_RESULT_SUCCESS;
94115
}
95116

96-
offload_result_t
117+
offload_impl_result_t
97118
offloadPlatformGetInfo_impl(offload_platform_handle_t hPlatform,
98119
offload_platform_info_t propName, size_t propSize,
99120
void *pPropValue, size_t *pPropSizeRet) {
@@ -126,11 +147,11 @@ offloadPlatformGetInfo_impl(offload_platform_handle_t hPlatform,
126147
return OFFLOAD_RESULT_SUCCESS;
127148
}
128149

129-
offload_result_t offloadDeviceGet_impl(offload_platform_handle_t hPlatform,
130-
offload_device_type_t,
131-
uint32_t NumEntries,
132-
offload_device_handle_t *phDevices,
133-
uint32_t *pNumDevices) {
150+
offload_impl_result_t offloadDeviceGet_impl(offload_platform_handle_t hPlatform,
151+
offload_device_type_t,
152+
uint32_t NumEntries,
153+
offload_device_handle_t *phDevices,
154+
uint32_t *pNumDevices) {
134155

135156
if (phDevices) {
136157
for (uint32_t DeviceIndex = 0; DeviceIndex < NumEntries; DeviceIndex++) {
@@ -145,10 +166,11 @@ offload_result_t offloadDeviceGet_impl(offload_platform_handle_t hPlatform,
145166
return OFFLOAD_RESULT_SUCCESS;
146167
}
147168

148-
offload_result_t offloadDeviceGetInfo_impl(offload_device_handle_t hDevice,
149-
offload_device_info_t propName,
150-
size_t propSize, void *pPropValue,
151-
size_t *pPropSizeRet) {
169+
offload_impl_result_t offloadDeviceGetInfo_impl(offload_device_handle_t hDevice,
170+
offload_device_info_t propName,
171+
size_t propSize,
172+
void *pPropValue,
173+
size_t *pPropSizeRet) {
152174

153175
ReturnHelper ReturnValue(propSize, pPropValue, pPropSizeRet);
154176

offload/new-api/src/offload_lib.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,20 @@
1010
//
1111
//===----------------------------------------------------------------------===//
1212

13+
#include "offload_impl.hpp"
1314
#include <offload_api.h>
1415
#include <offload_print.hpp>
1516

1617
#include <iostream>
1718

19+
// Store details for the last error that occurred on this thread. It MAY be set
20+
// when an implementation function returns a result other than
21+
// OFFLOAD_RESULT_SUCCESS.
22+
std::optional<std::string> &LastErrorDetails() {
23+
thread_local std::optional<std::string> Details;
24+
return Details;
25+
}
26+
1827
// Pull in the declarations for the implementation funtions. The actual entry
1928
// points in this file wrap these.
2029
#include "offload_impl_func_decls.inc"

offload/tools/offload-tblgen/EntryPointGen.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,10 @@ static void EmitEntryPointFunc(const FunctionRec &F, raw_ostream &OS) {
9292
OS << formatv("};\n");
9393
OS << TAB_2 "std::cout << \"(\" << &Params << \")\";\n";
9494
OS << TAB_2 "std::cout << \"-> \" << result << \"\\n\";\n";
95+
OS << TAB_2 "if (result != OFFLOAD_RESULT_SUCCESS && LastErrorDetails()) {\n";
96+
OS << TAB_3 "std::cout << \" *Error Details* \" << *LastErrorDetails() "
97+
"<< \" \\n\";\n";
98+
OS << TAB_2 "}\n";
9599
OS << TAB_1 "}\n";
96100

97101
OS << TAB_1 "return result;\n";

offload/tools/offload-tblgen/FuncsGen.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,13 @@ void EmitOffloadExports(RecordKeeper &Records, raw_ostream &OS) {
5252
void EmitOffloadImplFuncDecls(RecordKeeper &Records, raw_ostream &OS) {
5353
for (auto *R : Records.getAllDerivedDefinitions("Function")) {
5454
FunctionRec F{R};
55-
OS << formatv("{0}_result_t {1}_impl(", PrefixLower, F.getName());
55+
// The error details function does not set error details itself, so don't
56+
// use the impl result type
57+
if (F.getName() == "offloadGetErrorDetails") {
58+
OS << formatv("{0}_result_t {1}_impl(", PrefixLower, F.getName());
59+
} else {
60+
OS << formatv("{0}_impl_result_t {1}_impl(", PrefixLower, F.getName());
61+
}
5662
auto Params = F.getParams();
5763
for (auto &Param : Params) {
5864
OS << Param.getType() << " " << Param.getName();

0 commit comments

Comments
 (0)