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

Reply via email to