This is an automated email from the ASF dual-hosted git repository.

tqchen 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 1cb00e0651 [REFACTOR][IR] Promote TensorRegionType to shared IR 
(#20600)
1cb00e0651 is described below

commit 1cb00e0651afd297b269aaa5a94cf7a43da5e131
Author: Tianqi Chen <[email protected]>
AuthorDate: Thu Oct 8 11:16:50 2026 -0400

    [REFACTOR][IR] Promote TensorRegionType to shared IR (#20600)
    
    Move the tensor-region type from TIRx into shared IR as
    `TensorRegionType`, alongside `TensorRegion`. Update C++ and Python
    APIs, reflection keys, constructors and script printing while retaining
    TIRx-owned buffer slicing.
    
    Preserve legacy JSON loading through `tvm.ir.load_json` by translating
    the former `BufferRegionType` key.
---
 docs/reference/api/python/script/ir_builder.rst |  2 +-
 docs/tirx/api/tirx.rst                          |  5 ++--
 include/tvm/ir/type.h                           | 19 ++++++++++++++
 include/tvm/tirx/expr.h                         |  2 +-
 include/tvm/tirx/type.h                         | 19 --------------
 python/tvm/ir/__init__.py                       |  1 +
 python/tvm/ir/json_compact.py                   | 11 ++++----
 python/tvm/ir/type.py                           |  8 ++++++
 python/tvm/script/ir_builder/__init__.py        |  2 ++
 python/tvm/tirx/__init__.py                     |  2 +-
 python/tvm/tirx/stmt.py                         | 10 +------
 src/ir/type.cc                                  | 16 +++++++++++
 src/script/printer/ir/prim_type.cc              | 10 +++++++
 src/script/printer/script_printer.cc            |  1 +
 src/tirx/ir/buffer.cc                           |  4 +--
 src/tirx/ir/type.cc                             | 35 -------------------------
 src/tirx/script/printer/buffer.cc               |  9 -------
 17 files changed, 72 insertions(+), 84 deletions(-)

diff --git a/docs/reference/api/python/script/ir_builder.rst 
b/docs/reference/api/python/script/ir_builder.rst
index 805f69c695..58d29f9ddd 100644
--- a/docs/reference/api/python/script/ir_builder.rst
+++ b/docs/reference/api/python/script/ir_builder.rst
@@ -23,7 +23,7 @@ tvm.script.ir_builder
 .. automodule:: tvm.script.ir_builder
    :members:
    :imported-members:
-   :exclude-members: Call, DataTypeImm, FuncType, GenericConst, MissingType, 
Op, PrimType, Range, StringImm, StringType, TensorRegion, Tuple, Type
+   :exclude-members: Call, DataTypeImm, FuncType, GenericConst, MissingType, 
Op, PrimType, Range, StringImm, StringType, TensorRegion, TensorRegionType, 
Tuple, Type
 
 tvm.relax.script.ir_builder.distributed
 ***************************************
diff --git a/docs/tirx/api/tirx.rst b/docs/tirx/api/tirx.rst
index 8edffc8496..d427c660c9 100644
--- a/docs/tirx/api/tirx.rst
+++ b/docs/tirx/api/tirx.rst
@@ -25,8 +25,9 @@ here so the same objects are not expanded twice.
 
 For C++ construction, include ``tvm/tirx/expr.h`` for ``TensorVar``, buffer
 loads, and buffer-region constructors. Include ``tvm/tirx/type.h`` for
-``TensorType``, ``BufferRegionType``, and ``TensorMapType``. Buffer regions
-use the shared ``TensorRegion`` expression from ``tvm/ir/expr.h``.
+``TensorType`` and ``TensorMapType``. Buffer regions use the shared
+``TensorRegion`` expression from ``tvm/ir/expr.h`` and ``TensorRegionType``
+from ``tvm/ir/type.h``.
 
 .. automodule:: tvm.tirx
    :members:
diff --git a/include/tvm/ir/type.h b/include/tvm/ir/type.h
index 21132604c4..e3821058ed 100644
--- a/include/tvm/ir/type.h
+++ b/include/tvm/ir/type.h
@@ -57,6 +57,25 @@ class AnyType : public Type {
   TVM_FFI_DEFINE_OBJECT_REF_METHODS_NOTNULLABLE(AnyType, Type, AnyTypeNode);
 };
 
+/*! \brief The type of a multi-dimensional tensor region expression. */
+class TensorRegionTypeNode : public TypeNode {
+ public:
+  static void RegisterReflection() {
+    namespace refl = tvm::ffi::reflection;
+    refl::ObjectDef<TensorRegionTypeNode>();
+  }
+
+  TVM_FFI_DECLARE_OBJECT_INFO_FINAL("ir.TensorRegionType", 
TensorRegionTypeNode, TypeNode);
+};
+
+/*! \brief Managed reference to TensorRegionTypeNode. */
+class TensorRegionType : public Type {
+ public:
+  TVM_DLL TensorRegionType();
+
+  TVM_FFI_DEFINE_OBJECT_REF_METHODS_NOTNULLABLE(TensorRegionType, Type, 
TensorRegionTypeNode);
+};
+
 /*! \brief Semantic string type; its physical representation is context 
dependent. */
 class StringTypeNode : public TypeNode {
  public:
diff --git a/include/tvm/tirx/expr.h b/include/tvm/tirx/expr.h
index e5c5a3ab22..6d8ce878d0 100644
--- a/include/tvm/tirx/expr.h
+++ b/include/tvm/tirx/expr.h
@@ -242,7 +242,7 @@ TVM_DLL tirx::TensorVar 
TensorWithOffsetAlignment(ffi::Array<PrimExpr> shape, Pr
 TVM_DLL TensorLoad MakeTensorLoad(TensorVar buffer, ffi::Array<PrimExpr> 
indices,
                                   Span span = Span());
 
-/*! \brief Construct a region with buffer rank validation and 
BufferRegionType. */
+/*! \brief Construct a region with buffer rank validation and 
TensorRegionType. */
 TVM_DLL TensorRegion BufferRegion(TensorVar buffer, ffi::Array<Range> region, 
Span span = Span());
 /*! \brief Select the entire buffer. */
 TVM_DLL TensorRegion FullBufferRegion(TensorVar buffer);
diff --git a/include/tvm/tirx/type.h b/include/tvm/tirx/type.h
index c2208d5f2a..a84dc6c21c 100644
--- a/include/tvm/tirx/type.h
+++ b/include/tvm/tirx/type.h
@@ -169,25 +169,6 @@ class TensorType : public Type {
   }
 };
 
-/*! \brief The type of a multi-dimensional buffer region expression. */
-class BufferRegionTypeNode : public TypeNode {
- public:
-  static void RegisterReflection() {
-    namespace refl = tvm::ffi::reflection;
-    refl::ObjectDef<BufferRegionTypeNode>();
-  }
-
-  TVM_FFI_DECLARE_OBJECT_INFO_FINAL("tirx.BufferRegionType", 
BufferRegionTypeNode, TypeNode);
-};
-
-/*! \brief Managed reference to BufferRegionTypeNode. */
-class BufferRegionType : public Type {
- public:
-  TVM_DLL BufferRegionType();
-
-  TVM_FFI_DEFINE_OBJECT_REF_METHODS_NOTNULLABLE(BufferRegionType, Type, 
BufferRegionTypeNode);
-};
-
 /*!
  * \brief The type of tensor map.
  * \sa TensorMapType
diff --git a/python/tvm/ir/__init__.py b/python/tvm/ir/__init__.py
index 7151ef6f1e..345b294468 100644
--- a/python/tvm/ir/__init__.py
+++ b/python/tvm/ir/__init__.py
@@ -41,6 +41,7 @@ from .type import (
     PointerType,
     PrimType,
     StringType,
+    TensorRegionType,
     TupleType,
     Type,
 )
diff --git a/python/tvm/ir/json_compact.py b/python/tvm/ir/json_compact.py
index 085dc52ec6..34107c469e 100644
--- a/python/tvm/ir/json_compact.py
+++ b/python/tvm/ir/json_compact.py
@@ -34,6 +34,7 @@ _PRIM_TYPE_KEY_RENAMES = {
     "arith.SplitExpr": "sym.SplitExpr",
     "arith.SumExpr": "sym.SumExpr",
     "tirx.BufferRegion": "ir.TensorRegion",
+    "tirx.BufferRegionType": "ir.TensorRegionType",
     "tirx.IterVar": "s_tir.IterVar",
     "tirx.SBlock": "s_tir.SBlock",
     "tirx.SBlockRealize": "s_tir.SBlockRealize",
@@ -139,7 +140,7 @@ def upgrade_json(json_str):
     # written before the canonical Var field was renamed to `name`.  Rewriting
     # nodes in place preserves node indices and shared references.
     nodes = data.get("nodes", [])
-    buffer_region_type = None
+    tensor_region_type = None
     for node in nodes:
         if node.get("type") == "tirx.BufferRegion":
             fields = node.get("data")
@@ -150,10 +151,10 @@ def upgrade_json(json_str):
             # an Expr, it had only buffer/region; supply that form's defaults
             # by appending a type node so existing graph indices stay intact.
             if "ty" not in fields:
-                if buffer_region_type is None:
-                    buffer_region_type = len(nodes)
-                    nodes.append({"type": "tirx.BufferRegionType", "data": 
{"span": 0}})
-                fields["ty"] = buffer_region_type
+                if tensor_region_type is None:
+                    tensor_region_type = len(nodes)
+                    nodes.append({"type": "ir.TensorRegionType", "data": 
{"span": 0}})
+                fields["ty"] = tensor_region_type
             fields.setdefault("span", 0)
         node["type"] = _PRIM_TYPE_KEY_RENAMES.get(node.get("type"), 
node.get("type"))
         if node.get("type") == "relax.expr.Var":
diff --git a/python/tvm/ir/type.py b/python/tvm/ir/type.py
index 54172b637f..dfaf28623e 100644
--- a/python/tvm/ir/type.py
+++ b/python/tvm/ir/type.py
@@ -70,6 +70,14 @@ class AnyType(Type):
         self.__init_handle_by_constructor__(_ffi_api.AnyType, span)
 
 
+@tvm_ffi.register_object("ir.TensorRegionType")
+class TensorRegionType(Type):
+    """The type of a multi-dimensional :class:`tvm.ir.TensorRegion`."""
+
+    def __init__(self):
+        self.__init_handle_by_constructor__(_ffi_api.TensorRegionType)
+
+
 @tvm_ffi.register_object("ir.OpaqueType")
 class OpaqueType(Type):
     """Type marker for opaque values that must be removed from finished IR."""
diff --git a/python/tvm/script/ir_builder/__init__.py 
b/python/tvm/script/ir_builder/__init__.py
index 1a6eed82fe..172dcc08b4 100644
--- a/python/tvm/script/ir_builder/__init__.py
+++ b/python/tvm/script/ir_builder/__init__.py
@@ -28,6 +28,7 @@ from tvm.ir import (
     StringImm,
     StringType,
     TensorRegion,
+    TensorRegionType,
     Tuple,
     Type,
     make_node,
@@ -80,6 +81,7 @@ __all__ = [
     "StringImm",
     "StringType",
     "TensorRegion",
+    "TensorRegionType",
     "Tuple",
     "Type",
     "at_",
diff --git a/python/tvm/tirx/__init__.py b/python/tvm/tirx/__init__.py
index 217fee603d..6e7eda8b05 100644
--- a/python/tvm/tirx/__init__.py
+++ b/python/tvm/tirx/__init__.py
@@ -52,7 +52,7 @@ from .stmt import TensorStore, RegionStmt
 
 from .stmt import SeqStmt
 from .stmt import IfThenElse, Evaluate, stmt_seq, stmt_list
-from .stmt import BufferRegion, BufferRegionType
+from .stmt import BufferRegion
 from .stmt import ScopeIdDefStmt
 from .tile_primitive import DispatchContext, TilePrimitiveCall
 
diff --git a/python/tvm/tirx/stmt.py b/python/tvm/tirx/stmt.py
index 86792486d9..48c0e03d79 100644
--- a/python/tvm/tirx/stmt.py
+++ b/python/tvm/tirx/stmt.py
@@ -33,7 +33,7 @@ from typing import Any
 
 import tvm_ffi
 
-from tvm.ir import DictAttrs, Expr, Op, Range, Span, StringImm, TensorRegion, 
Type, Var, make_node
+from tvm.ir import DictAttrs, Expr, Op, Range, Span, StringImm, TensorRegion, 
Var, make_node
 from tvm.runtime import Object, Scriptable
 
 from . import _ffi_api
@@ -409,14 +409,6 @@ class Evaluate(Stmt):
         self.__init_handle_by_constructor__(_ffi_api.Evaluate, value, span)  # 
type: ignore
 
 
-@tvm_ffi.register_object("tirx.BufferRegionType")
-class BufferRegionType(Type):
-    """The TIRX subscript type of a buffer-backed 
:class:`tvm.ir.TensorRegion`."""
-
-    def __init__(self) -> None:
-        self.__init_handle_by_constructor__(_ffi_api.BufferRegionType)  # 
type: ignore
-
-
 def BufferRegion(buffer: Var, region: list[Range]) -> TensorRegion:
     """Construct a buffer-backed tensor region with TIRX subscript semantics.
 
diff --git a/src/ir/type.cc b/src/ir/type.cc
index dfa2601f07..13e9743694 100644
--- a/src/ir/type.cc
+++ b/src/ir/type.cc
@@ -292,6 +292,22 @@ TVM_FFI_STATIC_INIT_BLOCK() {
   refl::GlobalDef().def("ir.AnyType", [](Span span) { return AnyType(span); });
 }
 
+TensorRegionType::TensorRegionType() : Type(ffi::UnsafeInit{}) {
+  static const auto singleton = ffi::make_object<TensorRegionTypeNode>();
+  data_ = singleton;
+}
+
+TVM_FFI_STATIC_INIT_BLOCK() {
+  namespace refl = tvm::ffi::reflection;
+  TensorRegionTypeNode::RegisterReflection();
+  refl::TypeAttrDef<TensorRegionTypeNode>()
+      .attr(refl::type_attr::kStructuralVisit, 
ffi::FStructuralVisit::FromNative<&TypeVisit>())
+      .attr(refl::type_attr::kStructuralMutate, 
ffi::FStructuralMutate::FromNative<&TypeMutate>())
+      .attr(refl::type_attr::kStructuralMaybeInplaceMutate,
+            ffi::FStructuralMutate::FromNative<&TypeMaybeInplaceMutate>());
+  refl::GlobalDef().def("ir.TensorRegionType", []() { return 
TensorRegionType(); });
+}
+
 OpaqueType::OpaqueType() : Type(ffi::UnsafeInit{}) { data_ = 
ffi::make_object<OpaqueTypeNode>(); }
 
 TVM_FFI_STATIC_INIT_BLOCK() {
diff --git a/src/script/printer/ir/prim_type.cc 
b/src/script/printer/ir/prim_type.cc
index b3ef7ccec3..dc74aadde6 100644
--- a/src/script/printer/ir/prim_type.cc
+++ b/src/script/printer/ir/prim_type.cc
@@ -117,6 +117,16 @@ TVM_FFI_STATIC_INIT_BLOCK() {
       kDocTranslate, FDocTranslate::FromNative<&StringTypeDocTranslate>());
 }
 
+ffi::Optional<ExprDoc> TensorRegionTypeDocTranslate(DocTranslatorObj*, 
ffi::AnyView,
+                                                    const ffi::Object*) {
+  return NamespaceDoc("ir")->Attr("TensorRegionType")->Call({});
+}
+
+TVM_FFI_STATIC_INIT_BLOCK() {
+  ffi::reflection::TypeAttrDef<TensorRegionTypeNode>().attr(
+      kDocTranslate, 
FDocTranslate::FromNative<&TensorRegionTypeDocTranslate>());
+}
+
 ffi::Optional<ExprDoc> TupleTypeDocTranslate(DocTranslatorObj* d, ffi::AnyView 
input,
                                              const ffi::Object*) {
   const auto* ty =
diff --git a/src/script/printer/script_printer.cc 
b/src/script/printer/script_printer.cc
index 06dbf1eb05..1d450ceac5 100644
--- a/src/script/printer/script_printer.cc
+++ b/src/script/printer/script_printer.cc
@@ -69,6 +69,7 @@ TVM_FFI_STATIC_INIT_BLOCK() {
   RegisterScriptRepr<RangeNode>();
   RegisterScriptRepr<StringImmNode>();
   RegisterScriptRepr<TensorLoadNode>();
+  RegisterScriptRepr<TensorRegionTypeNode>();
   RegisterScriptRepr<TupleTypeNode>();
   RegisterScriptRepr<VarNode>();
   RegisterScriptRepr<prim::AddNode>();
diff --git a/src/tirx/ir/buffer.cc b/src/tirx/ir/buffer.cc
index 0a1fa5b789..475fe0d736 100644
--- a/src/tirx/ir/buffer.cc
+++ b/src/tirx/ir/buffer.cc
@@ -169,7 +169,7 @@ using IndexDiv = prim::FloorDivNode;
 TensorRegion BufferRegion(TensorVar buffer, ffi::Array<Range> region, Span 
span) {
   TVM_FFI_ICHECK_EQ(buffer->shape.size(), region.size())
       << "Buffer rank and region dimension mismatch";
-  return TensorRegion(std::move(buffer), std::move(region), 
BufferRegionType(), std::move(span));
+  return TensorRegion(std::move(buffer), std::move(region), 
TensorRegionType(), std::move(span));
 }
 
 TVM_FFI_STATIC_INIT_BLOCK() {
@@ -203,7 +203,7 @@ TensorRegion BufferRegionFromPoint(TensorVar buffer, 
ffi::Array<PrimExpr> indice
 TVM_FFI_STATIC_INIT_BLOCK() {
   namespace refl = tvm::ffi::reflection;
   refl::TypeAttrDef<TensorTypeNode>().def("__subscript_expr_realize__", 
RealizeBufferSubscript);
-  refl::TypeAttrDef<BufferRegionTypeNode>().def("__subscript_expr_realize__",
+  refl::TypeAttrDef<TensorRegionTypeNode>().def("__subscript_expr_realize__",
                                                 RealizeBufferRegionSubscript);
 }
 
diff --git a/src/tirx/ir/type.cc b/src/tirx/ir/type.cc
index d95db688e1..f2be37aebb 100644
--- a/src/tirx/ir/type.cc
+++ b/src/tirx/ir/type.cc
@@ -193,21 +193,6 @@ TVM_FFI_INLINE ffi::Expected<ffi::UnchangedOr<ffi::Any>> 
TensorTypeMaybeInplaceM
   return ffi::Unchanged();
 }
 
-TVM_FFI_INLINE ffi::Expected<ffi::Optional<ffi::VisitInterrupt>> 
BufferRegionTypeVisit(
-    ffi::StructuralVisitorObj*, ffi::AnyView) noexcept {
-  return std::nullopt;
-}
-
-TVM_FFI_INLINE ffi::Expected<ffi::UnchangedOr<ffi::Any>> 
BufferRegionTypeMutate(
-    ffi::StructuralMutatorObj*, ffi::AnyView) noexcept {
-  return ffi::Unchanged();
-}
-
-TVM_FFI_INLINE ffi::Expected<ffi::UnchangedOr<ffi::Any>> 
BufferRegionTypeMaybeInplaceMutate(
-    ffi::StructuralMutatorObj*, ffi::AnyView) noexcept {
-  return ffi::Unchanged();
-}
-
 }  // namespace
 
 TensorType::TensorType(ffi::String storage_scope, PrimType dtype, 
ffi::Array<PrimExpr> shape,
@@ -253,26 +238,6 @@ TVM_FFI_STATIC_INIT_BLOCK() {
       });
 }
 
-// TensorRegion
-BufferRegionType::BufferRegionType() : Type(ffi::UnsafeInit{}) {
-  static ffi::ObjectPtr<BufferRegionTypeNode> singleton = 
ffi::make_object<BufferRegionTypeNode>();
-  data_ = singleton;
-}
-
-TVM_FFI_STATIC_INIT_BLOCK() {
-  namespace refl = tvm::ffi::reflection;
-  BufferRegionTypeNode::RegisterReflection();
-  refl::TypeAttrDef<BufferRegionTypeNode>()
-      .attr(refl::type_attr::kStructuralVisit,
-            ffi::FStructuralVisit::FromNative<&BufferRegionTypeVisit>())
-      .attr(refl::type_attr::kStructuralMutate,
-            ffi::FStructuralMutate::FromNative<&BufferRegionTypeMutate>())
-      .attr(refl::type_attr::kStructuralMaybeInplaceMutate,
-            
ffi::FStructuralMutate::FromNative<&BufferRegionTypeMaybeInplaceMutate>());
-
-  refl::GlobalDef().def("tirx.BufferRegionType", []() { return 
BufferRegionType(); });
-}
-
 TensorMapType::TensorMapType(Span span) : Type(ffi::UnsafeInit{}) {
   ffi::ObjectPtr<TensorMapTypeNode> n = ffi::make_object<TensorMapTypeNode>();
   n->span = std::move(span);
diff --git a/src/tirx/script/printer/buffer.cc 
b/src/tirx/script/printer/buffer.cc
index 1c21dc68db..51bc27fb06 100644
--- a/src/tirx/script/printer/buffer.cc
+++ b/src/tirx/script/printer/buffer.cc
@@ -233,18 +233,9 @@ ffi::Optional<ExprDoc> 
TensorTypeDocTranslate(DocTranslatorObj* d, ffi::AnyView
       {TupleDoc(shape), LiteralDoc::DataType(buffer->dtype->dtype, 
std::nullopt)}, keys, values);
 }
 
-ffi::Optional<ExprDoc> BufferRegionTypeDocTranslate(DocTranslatorObj*, 
ffi::AnyView,
-                                                    const ffi::Object*) {
-  return NamespaceDoc("ir")
-      ->Attr("make_node")
-      ->Call({LiteralDoc::Str("tirx.BufferRegionType", std::nullopt)});
-}
-
 TVM_FFI_STATIC_INIT_BLOCK() {
   ffi::reflection::TypeAttrDef<tirx::TensorTypeNode>().attr(
       kDocTranslate, FDocTranslate::FromNative<&TensorTypeDocTranslate>());
-  ffi::reflection::TypeAttrDef<tirx::BufferRegionTypeNode>().attr(
-      kDocTranslate, 
FDocTranslate::FromNative<&BufferRegionTypeDocTranslate>());
 }
 
 }  // namespace

Reply via email to