This is an automated email from the ASF dual-hosted git repository.
lunderberg pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/tvm.git
The following commit(s) were added to refs/heads/main by this push:
new de56d8c950 [Hotfix] Mark python-FFI handling with TVM_DLL (#15970)
de56d8c950 is described below
commit de56d8c9508eeee417d85d413b7f3f7b3c9bd04f
Author: Eric Lunderberg <[email protected]>
AuthorDate: Wed Oct 25 09:26:45 2023 -0500
[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
---
include/tvm/runtime/c_runtime_api.h | 48 +++++++++++++++++++++++++++++++++++++
src/runtime/c_runtime_api.cc | 14 +++++------
2 files changed, 55 insertions(+), 7 deletions(-)
diff --git a/include/tvm/runtime/c_runtime_api.h
b/include/tvm/runtime/c_runtime_api.h
index d678003ee8..b7474cbbae 100644
--- a/include/tvm/runtime/c_runtime_api.h
+++ b/include/tvm/runtime/c_runtime_api.h
@@ -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
@@ -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.
diff --git a/src/runtime/c_runtime_api.cc b/src/runtime/c_runtime_api.cc
index 9f2ea8e2ff..0881eaf704 100644
--- a/src/runtime/c_runtime_api.cc
+++ b/src/runtime/c_runtime_api.cc
@@ -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();
@@ -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();
@@ -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 = "";
@@ -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;
@@ -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;
@@ -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;