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

tqchen pushed a commit to branch tqchen/printer-refinement
in repository https://gitbox.apache.org/repos/asf/tvm.git


The following commit(s) were added to refs/heads/tqchen/printer-refinement by 
this push:
     new 6ffc67eedd Keep complete scripts executable and parameter occurrences 
precise
6ffc67eedd is described below

commit 6ffc67eedda97270912c4d2d7abe4ac6a39c1471
Author: Tianqi Chen <[email protected]>
AuthorDate: Thu Oct 1 23:18:20 2026 +0000

    Keep complete scripts executable and parameter occurrences precise
---
 src/script/printer/printer.cc                      | 33 +++++++++++++++---
 .../relax/script/test_relax_script_printer.py      | 20 ++++++-----
 .../s_tir/script/test_s_tir_script_printer.py      | 40 ++++++++++++----------
 .../tirx/script/test_tirx_script_basic_usage.py    |  6 ++--
 4 files changed, 64 insertions(+), 35 deletions(-)

diff --git a/src/script/printer/printer.cc b/src/script/printer/printer.cc
index 8269f0745e..a8ca135d9f 100644
--- a/src/script/printer/printer.cc
+++ b/src/script/printer/printer.cc
@@ -235,9 +235,34 @@ void RecoverDocPaths(
     ffi::reflection::ForEachFieldInfo(
         TVMFFIGetTypeInfo(object->type_index()), [&](const TVMFFIFieldInfo* 
field) {
           if (ffi::String(field->name) == "source_paths") return;
-          RecoverDocPaths(ffi::reflection::FieldGetter(field)(object), 
context, origins, ir_paths,
-                          active,
-                          value.as<FunctionDocNode>() && 
ffi::String(field->name) == "args");
+          ffi::Any children = ffi::reflection::FieldGetter(field)(object);
+          bool parameters = value.as<FunctionDocNode>() && 
ffi::String(field->name) == "args";
+          if (parameters) {
+            auto function_origin = origins.find(object);
+            auto args = children.as<ffi::Array<AssignDoc>>();
+            auto params =
+                function_origin == origins.end()
+                    ? std::nullopt
+                    : ReflectedField(function_origin->second, 
"params").as<ffi::Array<ffi::Any>>();
+            bool matched = args && params && args->size() == params->size();
+            for (size_t i = 0; matched && i < args->size(); ++i) {
+              auto origin = origins.find((*args)[i].get());
+              matched =
+                  origin != origins.end() && origin->second.get() == 
(*params)[i].as<ffi::Object>();
+            }
+            if (matched) {
+              // Formal argument order identifies its occurrence even when the
+              // same object is also referenced by another parameter's type.
+              for (size_t i = 0; i < args->size(); ++i) {
+                std::vector<AccessPath> parameter_paths;
+                for (const AccessPath& path : context)
+                  
parameter_paths.push_back(path->Attr("params")->ArrayItem(i));
+                RecoverDocPaths((*args)[i], parameter_paths, origins, 
ir_paths, active, true);
+              }
+              return;
+            }
+          }
+          RecoverDocPaths(children, context, origins, ir_paths, active, 
parameters);
         });
   }
   active->erase(object);
@@ -388,7 +413,7 @@ ffi::String Script(const ffi::ObjectRef& obj, const 
PrinterConfig& config) {
       ffi::String alias = canonical == "ir" ? config->ir_prefix
                                             : 
config->GetExtraConfig<ffi::String>(key, fallback);
       ffi::String import = "from tvm.script import " + canonical + " as " + 
std::string(alias);
-      if (config->GetExtraConfig<bool>("ir.comment_imports", false)) {
+      if (config->GetExtraConfig<bool>("ir.comment_imports", false) && 
!config->show_meta) {
         header.push_back(CommentDoc(import));
       } else {
         header.push_back(ffi::String(std::string(import) + "\n"));
diff --git a/tests/python/relax/script/test_relax_script_printer.py 
b/tests/python/relax/script/test_relax_script_printer.py
index 08b12bc2e8..4a8ab35f95 100644
--- a/tests/python/relax/script/test_relax_script_printer.py
+++ b/tests/python/relax/script/test_relax_script_printer.py
@@ -146,15 +146,17 @@ class Module:
     @Ts.prim_func
     def tir_func(x: T.Buffer((T.int64(128), T.int64(128)), "float32"), y: 
T.Buffer((T.int64(128), T.int64(128)), "float32")):
         T.func_attr({"tirx.noalias": True})
-        # with Ts.sblock("root"):
-        for i in range(T.int64(0), T.int64(128)):
-            for j in range(T.int64(0), T.int64(128)):
-                with Ts.sblock(""):
-                    v = Ts.axis.spatial(T.int64(128), i, dtype="int64")
-                    v_1 = Ts.axis.spatial(T.int64(128), j, dtype="int64")
-                    Ts.reads(x[v, v_1])
-                    Ts.writes(y[v, v_1])
-                    y[v, v_1] = x[v, v_1] + T.float32(1.0)
+        with Ts.sblock("root"):
+            Ts.reads()
+            Ts.writes()
+            for i in range(T.int64(0), T.int64(128)):
+                for j in range(T.int64(0), T.int64(128)):
+                    with Ts.sblock(""):
+                        v = Ts.axis.spatial(T.int64(128), i, dtype="int64")
+                        v_1 = Ts.axis.spatial(T.int64(128), j, dtype="int64")
+                        Ts.reads(x[v, v_1])
+                        Ts.writes(y[v, v_1])
+                        y[v, v_1] = x[v, v_1] + T.float32(1.0)
 
     @R.function
     def foo(x: R.DTensor((128, 128), "float32", "mesh[0]", "S[0], R")) -> 
R.DTensor((128, 128), "float32", "mesh[0]", "S[0], R"):
diff --git a/tests/python/s_tir/script/test_s_tir_script_printer.py 
b/tests/python/s_tir/script/test_s_tir_script_printer.py
index 5d9c9b07a8..ae3b0f806f 100644
--- a/tests/python/s_tir/script/test_s_tir_script_printer.py
+++ b/tests/python/s_tir/script/test_s_tir_script_printer.py
@@ -322,23 +322,25 @@ def test_remap():
 
 @Ts.prim_func
 def main():
-    # with Ts.sblock("root"):
-    for i0 in range(128):
-        for i1 in range(128):
-            for i2 in range(128):
-                for i3 in range(128):
-                    for i4 in range(128):
-                        for i5 in range(128):
-                            with Ts.sblock("update"):
-                                v = Ts.axis.spatial(128, i0 + 1)
-                                v_1 = Ts.axis.spatial(128, i1)
-                                v_2 = Ts.axis.reduce(128, i2)
-                                v_3 = Ts.axis.spatial(128, i3 - 1)
-                                v_4 = Ts.axis.reduce(128, i4)
-                                v_5 = Ts.axis.spatial(128, i5)
-                                Ts.reads()
-                                Ts.writes()
-                                T.evaluate(0)"""
+    with Ts.sblock("root"):
+        Ts.reads()
+        Ts.writes()
+        for i0 in range(128):
+            for i1 in range(128):
+                for i2 in range(128):
+                    for i3 in range(128):
+                        for i4 in range(128):
+                            for i5 in range(128):
+                                with Ts.sblock("update"):
+                                    v = Ts.axis.spatial(128, i0 + 1)
+                                    v_1 = Ts.axis.spatial(128, i1)
+                                    v_2 = Ts.axis.reduce(128, i2)
+                                    v_3 = Ts.axis.spatial(128, i3 - 1)
+                                    v_4 = Ts.axis.reduce(128, i4)
+                                    v_5 = Ts.axis.spatial(128, i5)
+                                    Ts.reads()
+                                    Ts.writes()
+                                    T.evaluate(0)"""
     _assert_print(block_with_remap_explicitly.with_attr("global_symbol", 
"main"), expected_output)
     _assert_print(block_with_remap_implicitly.with_attr("global_symbol", 
"main"), expected_output)
 
@@ -1278,8 +1280,8 @@ def test_same_name_var():
         },
     )
     tvm.ir.assert_structural_equal(func, rt_func)
-    assert out_str.count("for i in range(16):\n        for j in range(16):") 
== 1
-    assert out_str.count("for i_1 in range(16):\n        for j_1 in 
range(16):") == 1
+    assert out_str.count("for i in range(16):\n            for j in 
range(16):") == 1
+    assert out_str.count("for i_1 in range(16):\n            for j_1 in 
range(16):") == 1
     assert out_str.find("i_2") == -1
     assert out_str.find("j_2") == -1
 
diff --git a/tests/python/tirx/script/test_tirx_script_basic_usage.py 
b/tests/python/tirx/script/test_tirx_script_basic_usage.py
index d9910eb366..fccdf56306 100644
--- a/tests/python/tirx/script/test_tirx_script_basic_usage.py
+++ b/tests/python/tirx/script/test_tirx_script_basic_usage.py
@@ -732,7 +732,7 @@ def test_roundtrip_serial_unroll_false():
 
     code = test.script()
     assert "unroll=False" in code, f"printer should emit unroll=False, 
got:\n{code}"
-    assert "annotations" not in code, "printer should NOT emit annotations 
dict"
+    assert "annotations=" not in code, "printer should NOT emit annotations 
dict"
     assert from_source(code).script() == code
     assert_structural_equal(test, from_source(code))
 
@@ -754,7 +754,7 @@ def test_roundtrip_serial_unroll_true():
 
     code = test.script()
     assert "unroll=True" in code, f"printer should emit unroll=True, 
got:\n{code}"
-    assert "annotations" not in code, "printer should NOT emit annotations 
dict"
+    assert "annotations=" not in code, "printer should NOT emit annotations 
dict"
     assert from_source(code).script() == code
     assert_structural_equal(test, from_source(code))
 
@@ -776,7 +776,7 @@ def test_roundtrip_serial_unroll_count():
 
     code = test.script()
     assert "unroll=2" in code, f"printer should emit unroll=2, got:\n{code}"
-    assert "annotations" not in code, "printer should NOT emit annotations 
dict"
+    assert "annotations=" not in code, "printer should NOT emit annotations 
dict"
     assert from_source(code).script() == code
     assert_structural_equal(test, from_source(code))
 

Reply via email to