This is an automated email from the ASF dual-hosted git repository.
junrushao pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/tvm-ffi.git
The following commit(s) were added to refs/heads/main by this push:
new e7c42f6 doc: Standalone Exception Handling (#428)
e7c42f6 is described below
commit e7c42f61a430f97d5977c1a5da6ae7adc66c8edd
Author: Junru Shao <[email protected]>
AuthorDate: Thu Feb 5 11:57:16 2026 -0800
doc: Standalone Exception Handling (#428)
---
docs/concepts/abi_overview.rst | 17 ++-
docs/concepts/any.rst | 11 +-
docs/concepts/exception_handling.rst | 194 +++++++++++++++++++++++++++++++++++
docs/concepts/func_module.rst | 76 ++------------
docs/concepts/object_and_class.rst | 8 +-
docs/concepts/tensor.rst | 11 +-
docs/index.rst | 1 +
7 files changed, 233 insertions(+), 85 deletions(-)
diff --git a/docs/concepts/abi_overview.rst b/docs/concepts/abi_overview.rst
index 89848cc..b2e1777 100644
--- a/docs/concepts/abi_overview.rst
+++ b/docs/concepts/abi_overview.rst
@@ -59,7 +59,8 @@ recognized by the FFI system. It enables type-erased value
passing across langua
**Ownership.** :cpp:class:`TVMFFIAny` struct can represent either an owning or
a borrowing reference.
These two ownership patterns are formalized by the C++ wrapper classes
:cpp:class:`~tvm::ffi::Any` and :cpp:class:`~tvm::ffi::AnyView`,
-which have identical memory layouts but different :ref:`ownership semantics
<any-ownership>`:
+which have identical memory layouts but different :ref:`ownership semantics
<any-ownership>`.
+See :doc:`any` for high-level C++ usage patterns:
- **Owning:** :cpp:class:`tvm::ffi::Any` - reference-counted, manages object
lifetime
- **Borrowing:** :cpp:class:`tvm::ffi::AnyView` - non-owning view, caller must
ensure validity
@@ -176,7 +177,8 @@ All TVM-FFI objects share these characteristics:
- Type index >= :cpp:enumerator:`kTVMFFIStaticObjectBegin
<TVMFFITypeIndex::kTVMFFIStaticObjectBegin>`
**Dynamic Type System.** Classes can be registered at runtime via
:cpp:func:`TVMFFITypeGetOrAllocIndex`,
-with support for single inheritance. See :ref:`type-checking-and-casting` for
usage details.
+with support for single inheritance. See :doc:`object_and_class` for the full
object system
+and :ref:`type-checking-and-casting` for usage details.
A small **static section** between :cpp:enumerator:`kTVMFFIStaticObjectBegin
<TVMFFITypeIndex::kTVMFFIStaticObjectBegin>`
and :cpp:enumerator:`kTVMFFIDynObjectBegin
<TVMFFITypeIndex::kTVMFFIDynObjectBegin>`
@@ -345,7 +347,7 @@ type-erased, and cross-language function calls, defined by
:cpp:type:`TVMFFISafe
- ``handle`` (``void*``): Optional resource handle passed to the callee;
typically ``NULL`` for exported symbols
- ``args`` (``TVMFFIAny*``) and ``num_args`` (``int``): Array of non-owning
:cpp:class:`~tvm::ffi::AnyView` input arguments
- ``result`` (``TVMFFIAny*``): Owning :cpp:class:`~tvm::ffi::Any` output value
-- Return value: ``0`` for success; ``-1`` or ``-2`` for errors (see
:ref:`sec:exception`)
+- Return value: ``0`` for success; ``-1`` for errors (see
:doc:`exception_handling` and :ref:`sec-exception`)
See :ref:`sec:function-calling-convention` for more details.
@@ -418,7 +420,7 @@ Exception
.. seealso::
- :ref:`sec:exception` for detailed exception handling patterns.
+ :doc:`exception_handling` for detailed exception handling patterns.
Exceptions are a central part of TVM-FFI's ABI and calling convention.
When errors occur, they are stored as objects with a
:cpp:class:`TVMFFIErrorCell` payload.
@@ -450,10 +452,6 @@ Retrieve it with :cpp:func:`TVMFFIErrorMoveFromRaised`,
which returns a :cpp:cla
This function transfers ownership to the caller and clears the TLS slot.
Call :cpp:func:`TVMFFIObjectDecRef` when done to avoid memory leaks.
-**Frontend errors (-2).** Error code ``-2`` is reserved for frontend errors.
-It is returned when :cpp:func:`TVMFFIEnvCheckSignals` detects a pending Python
signal.
-In this case, do not retrieve the error from TLS; instead, consult the
frontend's error mechanism.
-
.. admonition:: Print Error Message
:class: hint
@@ -547,5 +545,6 @@ Further Reading
- :doc:`any`: High-level C++ usage of :cpp:class:`~tvm::ffi::Any` and
:cpp:class:`~tvm::ffi::AnyView`
- :doc:`object_and_class`: The object system and reflection
- :doc:`tensor`: Tensor classes and DLPack interoperability
-- :doc:`func_module`: Functions, exceptions, and modules
+- :doc:`func_module`: Functions and modules
+- :doc:`exception_handling`: Exception handling across language boundaries
- :doc:`../get_started/stable_c_abi`: Quick introduction to the stable C ABI
diff --git a/docs/concepts/any.rst b/docs/concepts/any.rst
index 7f234ce..601e448 100644
--- a/docs/concepts/any.rst
+++ b/docs/concepts/any.rst
@@ -103,7 +103,8 @@ and :cpp:class:`~tvm::ffi::AnyView`, each with different
levels of strictness:
.. dropdown:: Example of :cpp:func:`cast\<T\>() <tvm::ffi::Any::cast>`
- :cpp:func:`cast\<T\>() <tvm::ffi::Any::cast>` is the workhorse. It returns
the value or throws:
+ :cpp:func:`cast\<T\>() <tvm::ffi::Any::cast>` is the workhorse. It returns
the value or throws
+ a :cpp:class:`tvm::ffi::Error` (see :doc:`exception_handling`):
.. code-block:: cpp
@@ -206,7 +207,8 @@ copies 16 bytes with no reference count updates, making it
ideal for passing arg
void process(ffi::AnyView value) {}
:cpp:class:`~tvm::ffi::Any` is an owning container. Copying an
:cpp:class:`~tvm::ffi::Any` that holds an object
-increments the reference count; destroying it decrements the count:
+increments the reference count; destroying it decrements the count
+(see :ref:`object-reference-counting` for details on how reference counting
works):
.. code-block:: cpp
@@ -362,6 +364,10 @@ the :cpp:class:`~tvm::ffi::AnyView` or
:cpp:class:`~tvm::ffi::Any`.
Heap-Allocated Objects
~~~~~~~~~~~~~~~~~~~~~~
+TVM-FFI objects are heap-allocated, reference-counted containers that inherit
from :cpp:class:`tvm::ffi::Object`.
+See :doc:`object_and_class` for details on the object system, and
:ref:`object-reference-counting` for
+how reference counting works.
+
.. list-table:: Figure 3. Common TVM-FFI object types stored as pointers in
:cpp:member:`TVMFFIAny::v_obj`.
:header-rows: 1
:widths: 40 40 30
@@ -422,4 +428,5 @@ Further Reading
- :doc:`object_and_class`: How TVM-FFI objects work, including reference
counting and type checking
- :doc:`func_module`: Function calling conventions and the global registry
- :doc:`tensor`: How tensors flow through :cpp:class:`~tvm::ffi::Any` and
:cpp:class:`~tvm::ffi::AnyView`
+- :doc:`exception_handling`: How :cpp:func:`~tvm::ffi::Any::cast` throws
exceptions on type mismatch
- :doc:`abi_overview`: Low-level C ABI details for working with
:cpp:class:`TVMFFIAny` directly
diff --git a/docs/concepts/exception_handling.rst
b/docs/concepts/exception_handling.rst
new file mode 100644
index 0000000..a10ae2a
--- /dev/null
+++ b/docs/concepts/exception_handling.rst
@@ -0,0 +1,194 @@
+.. Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+.. http://www.apache.org/licenses/LICENSE-2.0
+
+.. Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+
+.. _sec-exception-handling:
+
+Exception Handling
+==================
+
+TVM-FFI gracefully handles exceptions across language boundaries without
requiring manual
+error code management. This document covers throwing, catching, and
propagating exceptions
+in TVM-FFI functions.
+
+.. important::
+ Stack traces from all languages are properly preserved and concatenated in
the TVM-FFI Stable C ABI.
+
+
+Cross-language exceptions are **first-class citizens** in TVM-FFI.
+TVM-FFI provides a stable C ABI for propagating exceptions across language
boundaries,
+and wraps this ABI to provide language-native exception handling without
exposing the underlying C machinery.
+
+**Error in C**. :cpp:class:`tvm::ffi::Error` is a TVM-FFI :doc:`object
<object_and_class>` with a :cpp:class:`TVMFFIErrorCell` payload containing:
+
+- ``kind``: Error type name (e.g., ``"ValueError"``, ``"RuntimeError"``)
+- ``message``: Human-readable error message
+- ``backtrace``: Stack trace from the point of error
+
+**Propagating Errors in C**. For call chains, simply propagate return
codes—TLS carries the error details:
+
+.. code-block:: cpp
+
+ int my_function(...) {
+ int rc = some_ffi_call(...);
+ if (rc != 0) return rc; // Propagate error
+ // Continue on success
+ return 0;
+ }
+
+The following sections describe how to throw and catch exceptions across ABI
and language boundaries.
+
+Throwing Exceptions
+-------------------
+
+Python
+~~~~~~
+
+Raise native :py:class:`Exception <Exception>` instances or derived classes.
+TVM-FFI catches these at the ABI boundary and converts them to
:cpp:class:`tvm::ffi::Error` objects.
+When C++ code calls into Python and a Python exception occurs, it propagates
back to C++ as a
+:cpp:class:`tvm::ffi::Error`, which C++ code can handle appropriately.
+
+.. code-block:: python
+
+ def my_function(x: int) -> int:
+ if x < 0:
+ raise ValueError(f"x must be non-negative, got {x}")
+ return x + 1
+
+TVM-FFI automatically maps common Python exception types to their
corresponding error kinds:
+``RuntimeError``, ``ValueError``, ``TypeError``, ``AttributeError``,
``KeyError``,
+``IndexError``, ``AssertionError``, and ``MemoryError``. Custom exception
types can be
+registered using :py:func:`tvm_ffi.register_error`.
+
+C++
+~~~
+
+Use :cpp:class:`tvm::ffi::Error` or the :c:macro:`TVM_FFI_THROW` macro:
+
+.. code-block:: cpp
+
+ #include <tvm/ffi/error.h>
+
+ void ThrowError(int x) {
+ if (x < 0) {
+ TVM_FFI_THROW(ValueError) << "x must be non-negative, got " << x;
+ }
+ }
+
+The :c:macro:`TVM_FFI_THROW` macro captures the current file name, line
number, stack trace,
+and error message, then constructs a :cpp:class:`tvm::ffi::Error` object. At
the ABI boundary,
+this error is stored in TLS and the function returns ``-1`` per the
:cpp:type:`TVMFFISafeCallType`
+calling convention (see :ref:`sec:function-calling-convention`).
+
+Additional check macros are available for common validation patterns:
+
+.. code-block:: cpp
+
+ TVM_FFI_CHECK(condition, ErrorKind) << "message"; // Custom error kind
+ TVM_FFI_ICHECK(condition) << "message"; // InternalError
+ TVM_FFI_ICHECK_EQ(x, y) << "message"; // Check equality
+ TVM_FFI_ICHECK_LT(x, y) << "message"; // Check less than
+ // Also: TVM_FFI_ICHECK_GT, TVM_FFI_ICHECK_LE, TVM_FFI_ICHECK_GE,
TVM_FFI_ICHECK_NE
+
+.. hint::
+ A detailed implementation of such graceful handling behavior can be found
+ in :c:macro:`TVM_FFI_SAFE_CALL_BEGIN` / :c:macro:`TVM_FFI_SAFE_CALL_END`
macros.
+
+ANSI C
+~~~~~~
+
+For LLVM code generation and other C-based environments, use
:cpp:func:`TVMFFIErrorSetRaisedFromCStr`
+to set the TLS error and return ``-1``:
+
+.. literalinclude:: ../../examples/abi_overview/example_code.c
+ :language: c
+ :start-after: [Error.RaiseException.begin]
+ :end-before: [Error.RaiseException.end]
+
+For constructing error messages from multiple parts (useful in code
generators),
+use :cpp:func:`TVMFFIErrorSetRaisedFromCStrParts`:
+
+.. code-block:: cpp
+
+ const char* parts[] = {"Expected ", "2", " arguments, got ", "1"};
+ TVMFFIErrorSetRaisedFromCStrParts("ValueError", parts, 4);
+ return -1;
+
+.. _sec-exception:
+
+Catching Exceptions in C
+------------------------
+
+In C++, Python, and many other languages, TVM-FFI exceptions are **first-class
citizens**,
+meaning they can be caught and handled like native exceptions:
+
+.. code-block:: cpp
+
+ try {
+ // Calls a TVM-FFI function that throws an exception
+ } catch (const tvm::ffi::Error& e) {
+ // Handle the exception
+ std::cout << e.kind() << ": " << e.message() << "\n" << e.backtrace() <<
"\n";
+ }
+
+.. important::
+
+ This section covers the **pure C** low-level details of exception handling.
+ For C++ and other languages, the example above is sufficient.
+
+
+Checking Return Codes
+~~~~~~~~~~~~~~~~~~~~~
+
+When a TVM-FFI function returns a non-zero code, an error occurred.
+The error object is stored in thread-local storage (TLS) and can be retrieved
+with :cpp:func:`TVMFFIErrorMoveFromRaised`:
+
+.. literalinclude:: ../../examples/abi_overview/example_code.c
+ :language: c
+ :start-after: [Error.HandleReturnCode.begin]
+ :end-before: [Error.HandleReturnCode.end]
+
+.. important::
+ The caller must release the error object via :cpp:func:`TVMFFIObjectDecRef`
to avoid memory leaks.
+
+Accessing Error Details
+~~~~~~~~~~~~~~~~~~~~~~~
+
+The error payload is a :cpp:type:`TVMFFIErrorCell` structure containing the
error kind, message,
+and backtrace. Access it by skipping the :cpp:type:`TVMFFIObject` header:
+
+.. literalinclude:: ../../examples/abi_overview/example_code.c
+ :language: c
+ :start-after: [Error.Print.begin]
+ :end-before: [Error.Print.end]
+
+Return Code Reference
+~~~~~~~~~~~~~~~~~~~~~
+
+- **Error code 0:** Success
+- **Error code -1:** Error occurred, retrieve via
:cpp:func:`TVMFFIErrorMoveFromRaised`
+
+Further Reading
+---------------
+
+- :doc:`func_module`: Functions and modules that use this exception handling
mechanism
+- :doc:`object_and_class`: The object system that backs
:cpp:class:`~tvm::ffi::Error`
+- :doc:`any`: How errors are stored and transported in
:cpp:class:`~tvm::ffi::Any` containers
+- :doc:`abi_overview`: Low-level C ABI details for exceptions
+- `tvm/ffi/error.h
<https://github.com/apache/tvm-ffi/blob/main/include/tvm/ffi/error.h>`_: C++
error handling API
+- `tvm/ffi/c_api.h
<https://github.com/apache/tvm-ffi/blob/main/include/tvm/ffi/c_api.h>`_: C ABI
error functions
diff --git a/docs/concepts/func_module.rst b/docs/concepts/func_module.rst
index 878819e..300110a 100644
--- a/docs/concepts/func_module.rst
+++ b/docs/concepts/func_module.rst
@@ -35,7 +35,7 @@ TVM-FFI ABI, or "Packed Function".
:cpp:type:`TVMFFISafeCallType`
See :ref:`Stable C ABI <tvm_ffi_c_abi>` for a quick introduction.
TVM-FFI Function. :py:class:`tvm_ffi.Function`,
:cpp:class:`tvm::ffi::FunctionObj`, :cpp:class:`tvm::ffi::Function`
- A reference-counted function object and its managed reference, which wraps
any callable,
+ A reference-counted :doc:`function object <object_and_class>` and its
managed reference, which wraps any callable,
including language-agnostic functions and lambdas (C++, Python, Rust, etc.),
member functions, external C symbols, and other callable objects,
all sharing the same calling convention.
@@ -212,8 +212,8 @@ which provides a stable C ABI for cross-language calls. The
C calling convention
TVMFFIAny* result // Output argument (owning, zero-initialized)
);
-**Input arguments**. The input arguments are passed as an array of
:cpp:class:`tvm::ffi::AnyView` values,
-specified by ``args`` and ``num_args``.
+**Input arguments**. The input arguments are passed as an array of
:cpp:class:`tvm::ffi::AnyView` values
+(see :ref:`any-ownership` for ownership semantics), specified by ``args`` and
``num_args``.
**Output argument**. The output argument ``result`` is an owning
:cpp:type:`tvm::ffi::Any`
that the caller must zero-initialize before the call.
@@ -269,77 +269,16 @@ See :ref:`abi-function` for the C struct definition.
conversion rules as any other TVM-FFI object. See :ref:`Object Conversion with
Any <object-conversion-with-any>` for details.
-Throw and Catch Errors
-~~~~~~~~~~~~~~~~~~~~~~
-
-TVM-FFI gracefully handles exceptions across language boundaries without
requiring manual
-error code management.
-
-.. important::
- Stack traces from all languages are properly preserved and concatenated in
the TVM-FFI Stable C ABI.
-
-**Python**. In Python, raise native :py:class:`Exception <Exception>`
instances or derived classes.
-TVM-FFI catches these at the ABI boundary and converts them to
:cpp:class:`tvm::ffi::Error` objects.
-When C++ code calls into Python and a Python exception occurs, it propagates
back to C++ as a
-:cpp:class:`tvm::ffi::Error`, which C++ code can handle appropriately.
-
-**C++**. In C++, use :cpp:class:`tvm::ffi::Error` or the
:c:macro:`TVM_FFI_THROW` macro:
-
-.. code-block:: cpp
-
- #include <tvm/ffi/error.h>
-
- void ThrowError(int x) {
- if (x < 0) {
- TVM_FFI_THROW(ValueError) << "x must be non-negative, got " << x;
- }
- }
-
-The :c:macro:`TVM_FFI_THROW` macro captures the current file name, line
number, stack trace,
-and error message, then constructs a :cpp:class:`tvm::ffi::Error` object. At
the ABI boundary,
-this error is stored in TLS and the function returns ``-1`` per the
:cpp:type:`TVMFFISafeCallType`
-calling convention.
-
-.. hint::
- A detailed implementation of such graceful handling behavior can be found
- in :c:macro:`TVM_FFI_SAFE_CALL_BEGIN` / :c:macro:`TVM_FFI_SAFE_CALL_END`
macros.
+Exception Handling
+~~~~~~~~~~~~~~~~~~
+See :doc:`exception_handling` for details on throwing, catching, and
propagating exceptions
+across language boundaries.
Compiler developers commonly need to look up global functions in generated
code.
Use :cpp:func:`TVMFFIFunctionGetGlobal` to retrieve a function by name, then
call it with :cpp:func:`TVMFFIFunctionCall`.
See :ref:`abi-function` for C code examples.
-.. _sec:exception:
-
-Exception
-~~~~~~~~~
-
-This section describes the exception handling contract in the TVM-FFI Stable C
ABI.
-Exceptions are first-class citizens in TVM-FFI, and this section specifies:
-
-- How to properly throw exceptions from a TVM-FFI ABI function
-- How to check for and propagate exceptions from a TVM-FFI ABI function
-
-When a TVM-FFI function returns a non-zero code, an error occurred.
-An :cpp:class:`~tvm::ffi::ErrorObj` is stored in thread-local storage (TLS)
and can be retrieved
-with :cpp:func:`TVMFFIErrorMoveFromRaised`.
-
-- **Error code -1:** Retrieve the error from TLS, print it, and release via
:cpp:func:`TVMFFIObjectDecRef`.
-
-To raise an error, use :cpp:func:`TVMFFIErrorSetRaisedFromCStr` to set the TLS
error and return ``-1``.
-For chains of calls, simply propagate return codes - TLS carries the error
details.
-
-
-.. note::
-
- In the very rare case, the error kind can be ``EnvErrorAlreadySet``,
- which indicates that an error has already been set in the frontend
environment.
- In this case, the caller (python binding) should raise the error stored in
the
- frontend environment. This is handled by the our python package so
- you generally do not need to handle this case explicitly.
-
-See :ref:`abi-exception` for C code examples.
-
.. _sec:module:
@@ -459,6 +398,7 @@ a symbol during static initialization:
Further Reading
---------------
+- :doc:`exception_handling`: Throwing, catching, and propagating exceptions
across language boundaries
- :doc:`any`: How functions are stored in :cpp:class:`~tvm::ffi::Any`
containers
- :doc:`object_and_class`: The object system that backs
:cpp:class:`~tvm::ffi::FunctionObj`
- :doc:`abi_overview`: Low-level C ABI details for functions and exceptions
diff --git a/docs/concepts/object_and_class.rst
b/docs/concepts/object_and_class.rst
index 91ce14b..4bd90d8 100644
--- a/docs/concepts/object_and_class.rst
+++ b/docs/concepts/object_and_class.rst
@@ -44,7 +44,8 @@ Glossary
Type index and type key
Type index is an integer that uniquely identifies each object type.
- Built-in types have statically assigned indices defined in
:cpp:enum:`TVMFFITypeIndex`,
+ Built-in types have statically assigned indices defined in
:cpp:enum:`TVMFFITypeIndex`
+ (see :ref:`any-atomic-types` and :ref:`any-heap-allocated-objects` for the
complete list),
while user-defined types receive indices at startup when first accessed.
Type key is a unique string identifier (e.g., ``"my_ext.MyClass"``) that
names an object type.
It is used for registration, serialization, and cross-language mapping.
@@ -193,7 +194,9 @@ for runtime type checking:
return false;
}
-**Type casting**. Use :cpp:func:`ObjectRef::as\<T\>()
<tvm::ffi::ObjectRef::as>` for safe downcasting:
+**Type casting**. Use :cpp:func:`ObjectRef::as\<T\>()
<tvm::ffi::ObjectRef::as>` for safe downcasting.
+For strict conversion that throws on mismatch, use
:cpp:func:`~tvm::ffi::Any::cast`
+(see :doc:`exception_handling` for error handling details):
.. code-block:: cpp
@@ -417,5 +420,6 @@ Further Reading
- :doc:`any`: How objects are stored in :cpp:class:`~tvm::ffi::Any` containers
- :doc:`func_module`: Function objects and the global registry
- :doc:`tensor`: Tensor objects and DLPack interoperability
+- :doc:`exception_handling`: Error objects and cross-language exception
propagation
- :doc:`abi_overview`: Low-level C ABI details for the object system
- :doc:`../packaging/python_packaging`: Packaging C++ objects for Python wheels
diff --git a/docs/concepts/tensor.rst b/docs/concepts/tensor.rst
index 2669f71..26a806b 100644
--- a/docs/concepts/tensor.rst
+++ b/docs/concepts/tensor.rst
@@ -68,7 +68,8 @@ Kernel Signatures
~~~~~~~~~~~~~~~~~
A typical kernel implementation accepts :cpp:class:`TensorView
<tvm::ffi::TensorView>` parameters,
-validates metadata (dtype, shape, device), and then accesses the data pointer
for computation:
+validates metadata (dtype, shape, device), and then accesses the data pointer
for computation.
+Use :c:macro:`TVM_FFI_THROW` to report validation errors (see
:doc:`exception_handling`):
.. code-block:: cpp
@@ -89,7 +90,7 @@ validates metadata (dtype, shape, device), and then accesses
the data pointer fo
On the C++ side, the following APIs are available to query a tensor's metadata:
:cpp:func:`TensorView::shape() <tvm::ffi::TensorView::shape>` and
:cpp:func:`Tensor::shape() <tvm::ffi::Tensor::shape>`
- shape array
+ Shape array. For kernels exported as TVM-FFI functions, see
:doc:`func_module`.
:cpp:func:`TensorView::dtype() <tvm::ffi::TensorView::dtype>` and
:cpp:func:`Tensor::dtype() <tvm::ffi::Tensor::dtype>`
element data type
@@ -276,8 +277,8 @@ Similarly, TVM-FFI defines two main tensor types in C++:
*Owning* object, :cpp:class:`tvm::ffi::TensorObj` and
:cpp:class:`tvm::ffi::Tensor`
:cpp:class:`Tensor <tvm::ffi::Tensor>`, similar to
``std::shared_ptr<TensorObj>``, is the managed class to hold heap-allocated
- :cpp:class:`TensorObj <tvm::ffi::TensorObj>`. Once the reference count drops
to zero, the cleanup logic deallocates the descriptor
- and releases ownership of the underlying data buffer.
+ :cpp:class:`TensorObj <tvm::ffi::TensorObj>`. Once the reference count drops
to zero (see :ref:`object-reference-counting`),
+ the cleanup logic deallocates the descriptor and releases ownership of the
underlying data buffer.
.. note::
@@ -371,6 +372,8 @@ Further Reading
- :doc:`object_and_class`: The object system that backs
:cpp:class:`~tvm::ffi::TensorObj`
- :doc:`any`: How tensors are stored in :cpp:class:`~tvm::ffi::Any` containers
+- :doc:`func_module`: How tensors are passed through TVM-FFI function calls
+- :doc:`exception_handling`: Throwing errors during tensor validation
- :doc:`abi_overview`: Low-level C ABI details for tensor conversion
- :doc:`../guides/kernel_library_guide`: Best practices for building kernel
libraries with TVM-FFI
- :external+dlpack:doc:`DLPack C API <c_api>`: The underlying tensor
interchange standard
diff --git a/docs/index.rst b/docs/index.rst
index 530c2ac..a3570ef 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -63,6 +63,7 @@ Table of Contents
concepts/object_and_class.rst
concepts/tensor.rst
concepts/func_module.rst
+ concepts/exception_handling.rst
.. toctree::
:maxdepth: 1