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

tlopex 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 ced7181708 [TVMScript] Add block name suffix management for TIR macros 
(#18465)
ced7181708 is described below

commit ced7181708b6359d86d6e5f7196daa51c552e628
Author: Guan-Ming (Wesley) Chiu <[email protected]>
AuthorDate: Tue Nov 25 14:34:23 2025 +0800

    [TVMScript] Add block name suffix management for TIR macros (#18465)
    
    ## Related Issue
    
    closes https://github.com/apache/tvm/issues/18344
    
    ## Why
    
    When a `T.macro` containing a block was called multiple times in a TIR
    function, all expanded blocks had the same name, causing a "Duplicated
    block name" error in meta_schedule.
    
    ## How
    
    Implemented automatic block name suffixing during macro expansion
---
 python/tvm/script/ir_builder/tir/ir.py | 35 ++++++++++++++++++++++++++++++++++
 python/tvm/script/parser/tir/entry.py  | 20 ++++++++++++++++---
 2 files changed, 52 insertions(+), 3 deletions(-)

diff --git a/python/tvm/script/ir_builder/tir/ir.py 
b/python/tvm/script/ir_builder/tir/ir.py
index 31e48260f5..a08e66789f 100644
--- a/python/tvm/script/ir_builder/tir/ir.py
+++ b/python/tvm/script/ir_builder/tir/ir.py
@@ -16,9 +16,11 @@
 # under the License.
 """IRBuilder for TIR"""
 
+import contextlib
 import functools
 import inspect
 import sys
+import threading
 from numbers import Integral
 from typing import Any, Callable, Dict, List, Optional, Tuple, Union
 
@@ -87,6 +89,35 @@ from .external_kernel import call_kernel
 # pylint: enable=unused-import
 
 
+_block_name_suffix = threading.local()
+
+
+def _get_block_name_suffix() -> str:
+    """Get the current block name suffix for macro expansion."""
+    return getattr(_block_name_suffix, "value", "")
+
+
[email protected]
+def block_name_suffix_context(block_suffix: str):
+    """Context manager to set block name suffix during macro expansion.
+
+    Parameters
+    ----------
+    block_suffix : str
+        The suffix to append to block names (e.g., "_1", "_2").
+
+    Yields
+    ------
+    None
+    """
+    old_suffix = getattr(_block_name_suffix, "value", "")
+    _block_name_suffix.value = block_suffix
+    try:
+        yield
+    finally:
+        _block_name_suffix.value = old_suffix
+
+
 def buffer(
     shape: Union[List[PrimExpr], Tuple[PrimExpr], PrimExpr, Integral],
     dtype: str = "float32",
@@ -352,6 +383,9 @@ def block(name: str = "", no_realize: bool = False) -> 
frame.BlockFrame:
     res : frame.BlockFrame
         The BlockFrame.
     """
+    block_suffix = _get_block_name_suffix()
+    if block_suffix and name:
+        name = name + block_suffix
     return _ffi_api.Block(name, no_realize)  # type: ignore[attr-defined] # 
pylint: disable=no-member
 
 
@@ -2135,6 +2169,7 @@ __all__ = float_types + [
     "func_ret",
     "match_buffer",
     "block",
+    "block_name_suffix_context",
     "init",
     "where",
     "reads",
diff --git a/python/tvm/script/parser/tir/entry.py 
b/python/tvm/script/parser/tir/entry.py
index c7d5dc756b..bcac49733d 100644
--- a/python/tvm/script/parser/tir/entry.py
+++ b/python/tvm/script/parser/tir/entry.py
@@ -21,7 +21,7 @@ from typing import Callable, Optional, Union
 from tvm.ir.base import deprecated
 from tvm.tir import Buffer, PrimFunc
 
-from ...ir_builder.tir import buffer, ptr
+from ...ir_builder.tir import block_name_suffix_context, buffer, ptr
 from .._core import parse, scan_macro, utils
 from ..core.parser import Parser, ScriptMacro
 
@@ -90,11 +90,25 @@ setattr(prim_func, "dispatch_token", "tir")
 
 
 class TIRMacro(ScriptMacro):
-    """Specialization of the ScriptMacro class for TIR."""
+    """Specialization of the ScriptMacro class for TIR.
+
+    Attributes
+    ----------
+    call_count : int
+        Counter for the number of times this macro has been invoked.
+        Used to generate unique block name suffixes.
+    """
+
+    def __init__(self, *args, **kwargs):
+        super().__init__(*args, **kwargs)
+        self.call_count = 0
 
     def parse_macro(self, parser: Parser) -> None:
         macro_def = self.get_macro_def()
-        parser.visit_body(macro_def.body)
+        suffix = f"_{self.call_count}" if self.call_count > 0 else ""
+        self.call_count += 1
+        with block_name_suffix_context(suffix):
+            parser.visit_body(macro_def.body)
 
 
 def macro(*args, hygienic: bool = True) -> Callable:

Reply via email to