-
Notifications
You must be signed in to change notification settings - Fork 3.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[RUNTIME] Scaffold structured error handling. #2838
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
+13 −9 | include/dmlc/logging.h | |
+9 −16 | tracker/dmlc_tracker/local.py | |
+2 −0 | tracker/dmlc_tracker/opts.py |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
tvm.error | ||
--------- | ||
.. automodule:: tvm.error | ||
:members: | ||
:imported-members: |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -11,6 +11,7 @@ Python API | |
target | ||
build | ||
module | ||
error | ||
ndarray | ||
container | ||
function | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,118 @@ | ||
.. _error_guide: | ||
|
||
Error Handling Guide | ||
==================== | ||
TVM contains structured error classes to indicate specific types of error. | ||
Please raise a specific error type when possible, so that users can | ||
write code to handle a specific error category if necessary. | ||
|
||
All the error types are defined in :any:`tvm.error` namespace. | ||
You can directly raise the specific error object in python. | ||
In other languages like c++, you simply add ``<ErrorType>:`` prefix to | ||
the error message(see below). | ||
|
||
Raise a Specific Error in C++ | ||
----------------------------- | ||
You can add ``<ErrorType>:`` prefix to your error message to | ||
raise an error of the corresponding type. | ||
Note that you do not have to add a new type | ||
:any:`tvm.error.TVMError` will be raised by default when | ||
there is no error type prefix in the message. | ||
This mechanism works for both ``LOG(FATAL)`` and ``CHECK`` macros. | ||
The following code gives an example on how to do so. | ||
|
||
.. code:: c | ||
// src/api_test.cc | ||
void ErrorTest(int x, int y) { | ||
CHECK_EQ(x, y) << "ValueError: expect x and y to be equal." | ||
if (x == 1) { | ||
LOG(FATAL) << "InternalError: cannot reach here"; | ||
} | ||
} | ||
The above function is registered as PackedFunc into the python frontend, | ||
under the name ``tvm._api_internal._ErrorTest``. | ||
Here is what will happen if we call the registered function: | ||
|
||
.. code:: | ||
>>> import tvm | ||
>>> tvm._api_internal._ErrorTest(0, 1) | ||
Traceback (most recent call last): | ||
File "<stdin>", line 1, in <module> | ||
File "/path/to/tvm/python/tvm/_ffi/_ctypes/function.py", line 190, in __call__ | ||
raise get_last_ffi_error() | ||
ValueError: Traceback (most recent call last): | ||
[bt] (3) /path/to/tvm/build/libtvm.so(TVMFuncCall+0x48) [0x7fab500b8ca8] | ||
[bt] (2) /path/to/tvm/build/libtvm.so(+0x1c4126) [0x7fab4f7f5126] | ||
[bt] (1) /path/to/tvm/build/libtvm.so(+0x1ba2f8) [0x7fab4f7eb2f8] | ||
[bt] (0) /path/to/tvm/build/libtvm.so(+0x177d12) [0x7fab4f7a8d12] | ||
File "/path/to/tvm/src/api/api_test.cc", line 80 | ||
ValueError: Check failed: x == y (0 vs. 1) : expect x and y to be equal. | ||
>>> | ||
>>> tvm._api_internal._ErrorTest(1, 1) | ||
Traceback (most recent call last): | ||
File "<stdin>", line 1, in <module> | ||
File "/path/to/tvm/python/tvm/_ffi/_ctypes/function.py", line 190, in __call__ | ||
raise get_last_ffi_error() | ||
tvm.error.InternalError: Traceback (most recent call last): | ||
[bt] (3) /path/to/tvm/build/libtvm.so(TVMFuncCall+0x48) [0x7fab500b8ca8] | ||
[bt] (2) /path/to/tvm/build/libtvm.so(+0x1c4126) [0x7fab4f7f5126] | ||
[bt] (1) /path/to/tvm/build/libtvm.so(+0x1ba35c) [0x7fab4f7eb35c] | ||
[bt] (0) /path/to/tvm/build/libtvm.so(+0x177d12) [0x7fab4f7a8d12] | ||
File "/path/to/tvm/src/api/api_test.cc", line 83 | ||
InternalError: cannot reach here | ||
TVM hint: You hit an internal error. Please open a thread on https://discuss.tvm.ai/ to report it. | ||
As you can see in the above example, TVM's ffi system combines | ||
both the python and c++'s stacktrace into a single message, and generate the | ||
corresponding error class automatically. | ||
|
||
|
||
How to choose an Error Type | ||
--------------------------- | ||
You can go through the error types are listed below, try to us common | ||
sense and also refer to the choices in the existing code. | ||
We try to keep a reasonable amount of error types. | ||
If you feel there is a need to add a new error type, do the following steps: | ||
|
||
- Send a RFC proposal with a description and usage examples in the current codebase. | ||
- Add the new error type to :any:`tvm.error` with clear documents. | ||
- Update the list in this file to include the new error type. | ||
- Change the code to use the new error type. | ||
|
||
We also recommend to use less abstraction when creating the short error messages. | ||
The code is more readable in this way, and also opens path to craft specific | ||
error messages when necessary. | ||
|
||
.. code:: python | ||
def preferred(): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not completely sure about which of these are preferred. Is only the first option valid? Option 2 is not preferred, right? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. more discussions in #2279, i think this is something that maybe worth some more discussion |
||
# very clear about what is being raised and what is the error message. | ||
raise OpNotImplemented("Operator relu is not implemented in the MXNet fronend") | ||
def _op_not_implemented(op_name): | ||
return OpNotImpelemented("Operator {} is not implemented.").format(op_name) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nit: Impelemented->Implemented |
||
def not_preferred(): | ||
raise _op_not_implemented("relu") | ||
System-wide Errors | ||
------------------ | ||
|
||
.. autoclass:: tvm.error.TVMError | ||
|
||
.. autoclass:: tvm.error.InternalError | ||
|
||
|
||
Frontend Errors | ||
--------------- | ||
.. autoclass:: tvm.error.OpNotImplemented | ||
|
||
.. autoclass:: tvm.error.OpAttributeInvalid | ||
|
||
.. autoclass:: tvm.error.OpAttributeRequired | ||
|
||
.. autoclass:: tvm.error.OpAttributeNotImplemented |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: us->use