Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 48 additions & 0 deletions include/tvm/runtime/c_runtime_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,18 @@ TVM_DLL void TVMAPISetLastError(const char* msg);
*/
TVM_DLL void TVMAPISetLastPythonError(void* py_object);

/*! \brief Return the previous python error, if any.
*
* Used to propagate the original Python exception to a python
* try/except, when there are C++ stack frames between the location thro
*
* \return The previous argument passed during the most recent call to
* TVMAPISetLastPythonError. If TVMAPISetLastPythonError has not
* been called, or if TVMDropLastPythonError has been called since
* the most recent to TVMAPISetLastPythonError, returns nullptr.
*/
TVM_DLL void* TVMGetLastPythonError();

/*!
* \brief return str message of the last error
* all function in this file will return 0 when success
Expand All @@ -261,6 +273,42 @@ TVM_DLL void TVMAPISetLastPythonError(void* py_object);
* \return error info
*/
TVM_DLL const char* TVMGetLastError(void);

/*!
* \brief Return the backtrace of the most recent error
*
* Returns the backtrace of the most recent error, if an error exists,
* and the error contains a backtrace. If no error exists or the
* error does not contain a backtrace, returns nullptr.
*
* \return The backtrace of the most recent error
*/
TVM_DLL const char* TVMGetLastBacktrace();

/*!
* \brief Remove the propagated python error, if any
*
* Removes the TVM-held reference to a thrown python exception object.
* Because these objects contain references to the stack frames from
* which the exception was thrown, maintaining a reference to an
* exception object prevents any local python variables from being
* garbage-collected. After retrieving the object using
* TVMGetLastPythonError, the Python FFI interface uses this method to
* clear the TVM-held reference to the exception, to allow garbage
* collection to continue.
*/
TVM_DLL void TVMDropLastPythonError();

/*! \brief Re-throw the most recent error.
*
* If an error was previously set using TVMAPISetLastError or
* TVMAPISetLastPythonError, re-throw the error. This is similar to
* `LOG(FATAL) << TVMGetLastError()`, but includes handling to
* propagate a python exception across C++ stack frames, or to append
* a stack trace to an error message.
*/
TVM_DLL void TVMThrowLastError();

/*!
* \brief Load module from file.
* \param file_name The file name to load the module from.
Expand Down
14 changes: 7 additions & 7 deletions src/runtime/c_runtime_api.cc
Original file line number Diff line number Diff line change
Expand Up @@ -418,7 +418,7 @@ const char* TVMGetLastError() {
}
}

extern "C" void* TVMGetLastPythonError() {
void* TVMGetLastPythonError() {
auto& last_error = TVMAPIRuntimeStore::Get()->last_error;
if (auto* wrapped = std::get_if<WrappedPythonError>(&last_error)) {
return wrapped->obj.raw_pointer();
Expand All @@ -427,7 +427,7 @@ extern "C" void* TVMGetLastPythonError() {
}
}

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

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

extern "C" void TVMAPISetLastPythonError(void* obj) {
void TVMAPISetLastPythonError(void* obj) {
auto& last_error = TVMAPIRuntimeStore::Get()->last_error;
last_error = WrappedPythonError(WrappedPythonObject(obj));
}

void ThrowLastError() {
void TVMThrowLastError() {
auto& last_error = TVMAPIRuntimeStore::Get()->last_error;
if (auto* wrapped = std::get_if<WrappedPythonError>(&last_error)) {
WrappedPythonError wrapped_err;
Expand Down Expand Up @@ -611,7 +611,7 @@ int TVMFuncCreateFromCFunc(TVMPackedCFunc func, void* resource_handle, TVMPacked
int ret = func(const_cast<TVMValue*>(args.values), const_cast<int*>(args.type_codes),
args.num_args, rv, resource_handle);
if (ret != 0) {
ThrowLastError();
TVMThrowLastError();
}
});
TVMValue val;
Expand All @@ -627,7 +627,7 @@ int TVMFuncCreateFromCFunc(TVMPackedCFunc func, void* resource_handle, TVMPacked
int ret = func(const_cast<TVMValue*>(args.values), const_cast<int*>(args.type_codes),
args.num_args, rv, rpack.get());
if (ret != 0) {
ThrowLastError();
TVMThrowLastError();
}
});
TVMValue val;
Expand Down