Skip to content

Commit de56d8c

Browse files
authored
[Hotfix] Mark python-FFI handling with TVM_DLL (#15970)
* [Hotfix] Mark python-FFI handling with TVM_DLL Bugfix for builds on Windows. * Updated declarations to match other usage in c_runtime_api.h
1 parent 885fc27 commit de56d8c

File tree

2 files changed

+55
-7
lines changed

2 files changed

+55
-7
lines changed

include/tvm/runtime/c_runtime_api.h

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,18 @@ TVM_DLL void TVMAPISetLastError(const char* msg);
251251
*/
252252
TVM_DLL void TVMAPISetLastPythonError(void* py_object);
253253

254+
/*! \brief Return the previous python error, if any.
255+
*
256+
* Used to propagate the original Python exception to a python
257+
* try/except, when there are C++ stack frames between the location thro
258+
*
259+
* \return The previous argument passed during the most recent call to
260+
* TVMAPISetLastPythonError. If TVMAPISetLastPythonError has not
261+
* been called, or if TVMDropLastPythonError has been called since
262+
* the most recent to TVMAPISetLastPythonError, returns nullptr.
263+
*/
264+
TVM_DLL void* TVMGetLastPythonError();
265+
254266
/*!
255267
* \brief return str message of the last error
256268
* all function in this file will return 0 when success
@@ -261,6 +273,42 @@ TVM_DLL void TVMAPISetLastPythonError(void* py_object);
261273
* \return error info
262274
*/
263275
TVM_DLL const char* TVMGetLastError(void);
276+
277+
/*!
278+
* \brief Return the backtrace of the most recent error
279+
*
280+
* Returns the backtrace of the most recent error, if an error exists,
281+
* and the error contains a backtrace. If no error exists or the
282+
* error does not contain a backtrace, returns nullptr.
283+
*
284+
* \return The backtrace of the most recent error
285+
*/
286+
TVM_DLL const char* TVMGetLastBacktrace();
287+
288+
/*!
289+
* \brief Remove the propagated python error, if any
290+
*
291+
* Removes the TVM-held reference to a thrown python exception object.
292+
* Because these objects contain references to the stack frames from
293+
* which the exception was thrown, maintaining a reference to an
294+
* exception object prevents any local python variables from being
295+
* garbage-collected. After retrieving the object using
296+
* TVMGetLastPythonError, the Python FFI interface uses this method to
297+
* clear the TVM-held reference to the exception, to allow garbage
298+
* collection to continue.
299+
*/
300+
TVM_DLL void TVMDropLastPythonError();
301+
302+
/*! \brief Re-throw the most recent error.
303+
*
304+
* If an error was previously set using TVMAPISetLastError or
305+
* TVMAPISetLastPythonError, re-throw the error. This is similar to
306+
* `LOG(FATAL) << TVMGetLastError()`, but includes handling to
307+
* propagate a python exception across C++ stack frames, or to append
308+
* a stack trace to an error message.
309+
*/
310+
TVM_DLL void TVMThrowLastError();
311+
264312
/*!
265313
* \brief Load module from file.
266314
* \param file_name The file name to load the module from.

src/runtime/c_runtime_api.cc

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -418,7 +418,7 @@ const char* TVMGetLastError() {
418418
}
419419
}
420420

421-
extern "C" void* TVMGetLastPythonError() {
421+
void* TVMGetLastPythonError() {
422422
auto& last_error = TVMAPIRuntimeStore::Get()->last_error;
423423
if (auto* wrapped = std::get_if<WrappedPythonError>(&last_error)) {
424424
return wrapped->obj.raw_pointer();
@@ -427,7 +427,7 @@ extern "C" void* TVMGetLastPythonError() {
427427
}
428428
}
429429

430-
extern "C" const char* TVMGetLastBacktrace() {
430+
const char* TVMGetLastBacktrace() {
431431
const auto& last_error = TVMAPIRuntimeStore::Get()->last_error;
432432
if (const auto* wrapped = std::get_if<WrappedPythonError>(&last_error)) {
433433
return wrapped->cpp_backtrace.data();
@@ -438,7 +438,7 @@ extern "C" const char* TVMGetLastBacktrace() {
438438
}
439439
}
440440

441-
extern "C" void TVMDropLastPythonError() {
441+
void TVMDropLastPythonError() {
442442
auto& last_error = TVMAPIRuntimeStore::Get()->last_error;
443443
if (std::get_if<WrappedPythonError>(&last_error)) {
444444
last_error = "";
@@ -458,12 +458,12 @@ int TVMAPIHandleException(const std::exception& e) {
458458
return -1;
459459
}
460460

461-
extern "C" void TVMAPISetLastPythonError(void* obj) {
461+
void TVMAPISetLastPythonError(void* obj) {
462462
auto& last_error = TVMAPIRuntimeStore::Get()->last_error;
463463
last_error = WrappedPythonError(WrappedPythonObject(obj));
464464
}
465465

466-
void ThrowLastError() {
466+
void TVMThrowLastError() {
467467
auto& last_error = TVMAPIRuntimeStore::Get()->last_error;
468468
if (auto* wrapped = std::get_if<WrappedPythonError>(&last_error)) {
469469
WrappedPythonError wrapped_err;
@@ -611,7 +611,7 @@ int TVMFuncCreateFromCFunc(TVMPackedCFunc func, void* resource_handle, TVMPacked
611611
int ret = func(const_cast<TVMValue*>(args.values), const_cast<int*>(args.type_codes),
612612
args.num_args, rv, resource_handle);
613613
if (ret != 0) {
614-
ThrowLastError();
614+
TVMThrowLastError();
615615
}
616616
});
617617
TVMValue val;
@@ -627,7 +627,7 @@ int TVMFuncCreateFromCFunc(TVMPackedCFunc func, void* resource_handle, TVMPacked
627627
int ret = func(const_cast<TVMValue*>(args.values), const_cast<int*>(args.type_codes),
628628
args.num_args, rv, rpack.get());
629629
if (ret != 0) {
630-
ThrowLastError();
630+
TVMThrowLastError();
631631
}
632632
});
633633
TVMValue val;

0 commit comments

Comments
 (0)