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

yaxingcai 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 e8576db88b [Fix]Fix function ObjectPath in IRModule SEqual (#14230)
e8576db88b is described below

commit e8576db88bad824a9997b8d499a9730059d0348c
Author: Yaxing Cai <[email protected]>
AuthorDate: Wed Mar 8 01:34:18 2023 -0800

    [Fix]Fix function ObjectPath in IRModule SEqual (#14230)
    
    This PR fixes the `IRModuleNode::SEqualReduce` to produce the correct 
`ObjectPath` for functions in `IRModule`.
    
    And this PR fixes some missing `Doc->source_paths`'s, when printer 
transforms `Doc` locally.
---
 src/ir/module.cc                                   | 21 ++++++
 .../printer/doc_printer/python_doc_printer.cc      |  1 -
 src/script/printer/ir/ir.cc                        |  1 +
 src/script/printer/utils.h                         | 10 ++-
 .../test_tvmscript_printer_structural_equal.py     | 40 ++++++----
 .../unittest/test_tvmscript_printer_underlining.py | 86 +++++++++++++++++++++-
 6 files changed, 143 insertions(+), 16 deletions(-)

diff --git a/src/ir/module.cc b/src/ir/module.cc
index 22c6faf3d6..42ced96120 100644
--- a/src/ir/module.cc
+++ b/src/ir/module.cc
@@ -65,6 +65,27 @@ IRModule::IRModule(tvm::Map<GlobalVar, BaseFunc> functions,
 bool IRModuleNode::SEqualReduce(const IRModuleNode* other, SEqualReducer 
equal) const {
   if (functions.size() != other->functions.size()) return false;
   if (!equal(this->attrs, other->attrs)) return false;
+  if (equal.IsPathTracingEnabled()) {
+    const ObjectPathPair& obj_path_pair = equal.GetCurrentObjectPaths();
+    for (const auto& kv : this->functions) {
+      if (!other->ContainGlobalVar(kv.first->name_hint)) return false;
+      ObjectPathPair func_paths = 
{obj_path_pair->lhs_path->Attr("functions")->MapValue(kv.first),
+                                   obj_path_pair->rhs_path->Attr("functions")
+                                       
->MapValue(other->GetGlobalVar(kv.first->name_hint))};
+      if (!equal(kv.second, other->Lookup(kv.first->name_hint), func_paths)) 
return false;
+    }
+    if (type_definitions.size() != other->type_definitions.size()) return 
false;
+    for (const auto& kv : this->type_definitions) {
+      if (!other->ContainGlobalTypeVar(kv.first->name_hint)) return false;
+      ObjectPathPair type_def_paths = {
+          
obj_path_pair->lhs_path->Attr("type_definitions")->MapValue(kv.first),
+          obj_path_pair->rhs_path->Attr("type_definitions")
+              ->MapValue(other->GetGlobalTypeVar(kv.first->name_hint))};
+      if (!equal(kv.second, other->LookupTypeDef(kv.first->name_hint), 
type_def_paths))
+        return false;
+    }
+    return true;
+  }
   for (const auto& kv : this->functions) {
     if (!other->ContainGlobalVar(kv.first->name_hint)) return false;
     if (!equal(kv.second, other->Lookup(kv.first->name_hint))) return false;
diff --git a/src/script/printer/doc_printer/python_doc_printer.cc 
b/src/script/printer/doc_printer/python_doc_printer.cc
index 994d048a2e..e726cd42a2 100644
--- a/src/script/printer/doc_printer/python_doc_printer.cc
+++ b/src/script/printer/doc_printer/python_doc_printer.cc
@@ -674,7 +674,6 @@ void PythonDocPrinter::PrintTypedDoc(const ClassDoc& doc) {
     PrintBlockComment(doc->comment.value());
   }
   PrintIndentedBlock(doc->body);
-  NewLineWithoutIndent();
 }
 
 void PythonDocPrinter::PrintTypedDoc(const CommentDoc& doc) {
diff --git a/src/script/printer/ir/ir.cc b/src/script/printer/ir/ir.cc
index e6f4a1eaee..065cfe5168 100644
--- a/src/script/printer/ir/ir.cc
+++ b/src/script/printer/ir/ir.cc
@@ -72,6 +72,7 @@ TVM_STATIC_IR_FUNCTOR(IRDocsifier, vtable)
         d->cfg->binding_names.pop_back();
         if (const auto* stmt_block = doc.as<StmtBlockDocNode>()) {
           (*f)->stmts.push_back(stmt_block->stmts.back());
+          (*f)->stmts.back()->source_paths = std::move(doc->source_paths);
         } else if (const auto* stmt = doc.as<StmtDocNode>()) {
           (*f)->stmts.push_back(GetRef<StmtDoc>(stmt));
         } else {
diff --git a/src/script/printer/utils.h b/src/script/printer/utils.h
index 10c7aaf4f2..ec0f0eaf72 100644
--- a/src/script/printer/utils.h
+++ b/src/script/printer/utils.h
@@ -61,6 +61,7 @@ inline void RedirectedReprPrinterMethod(const ObjectRef& obj, 
ReprPrinter* p) {
 inline std::string Docsify(const ObjectRef& obj, const IRDocsifier& d, const 
Frame& f,
                            const PrinterConfig& cfg) {
   Doc doc = d->AsDoc(obj, ObjectPath::Root());
+  bool move_source_paths = false;
   if (const auto* expr_doc = doc.as<ExprDocNode>()) {
     if (!cfg->verbose_expr) {
       f->stmts.clear();
@@ -72,6 +73,7 @@ inline std::string Docsify(const ObjectRef& obj, const 
IRDocsifier& d, const Fra
     for (const StmtDoc& d : stmt_block->stmts) {
       f->stmts.push_back(d);
     }
+    move_source_paths = true;
   } else {
     LOG(FATAL) << "TypeError: Unexpected doc type: " << doc->GetTypeKey();
   }
@@ -87,7 +89,13 @@ inline std::string Docsify(const ObjectRef& obj, const 
IRDocsifier& d, const Fra
           CommentDoc("Metadata omitted. Use show_meta=True in script() method 
to show it."));
     }
   }
-  os << DocToPythonScript(StmtBlockDoc(f->stmts), cfg);
+  if (move_source_paths) {
+    StmtBlockDoc new_doc(f->stmts);
+    new_doc->source_paths = std::move(doc->source_paths);
+    os << DocToPythonScript(new_doc, cfg);
+  } else {
+    os << DocToPythonScript(StmtBlockDoc(f->stmts), cfg);
+  }
   return os.str();
 }
 
diff --git a/tests/python/unittest/test_tvmscript_printer_structural_equal.py 
b/tests/python/unittest/test_tvmscript_printer_structural_equal.py
index 1b9e0fa9be..5c587354cc 100644
--- a/tests/python/unittest/test_tvmscript_printer_structural_equal.py
+++ b/tests/python/unittest/test_tvmscript_printer_structural_equal.py
@@ -21,7 +21,7 @@ import tvm
 from tvm.ir import assert_structural_equal
 from tvm.relay.op.transform import split
 from tvm.runtime import ObjectPath
-from tvm.script import tir as T
+from tvm.script import ir as I, tir as T
 
 
 def _error_message(exception):
@@ -68,21 +68,35 @@ def test_prim_func_buffer_map():
 
 
 def test_evaluate():
-    @T.prim_func
-    def func1():
-        T.evaluate(0)
-
-    @T.prim_func
-    def func2():
-        T.evaluate(1)
+    @I.ir_module
+    class module1:
+        @T.prim_func
+        def func():
+            T.evaluate(0)
+
+    @I.ir_module
+    class module2:
+        @T.prim_func
+        def func():
+            T.evaluate(1)
 
     with pytest.raises(ValueError) as ve:
-        assert_structural_equal(func1, func2)
+        assert_structural_equal(module1, module2)
     assert _error_message(ve.value) == _expected_result(
-        func1,
-        func2,
-        ObjectPath.root().attr("body").attr("value").attr("value"),
-        ObjectPath.root().attr("body").attr("value").attr("value"),
+        module1,
+        module2,
+        ObjectPath.root()
+        .attr("functions")
+        .map_value(module1.get_global_var("func"))
+        .attr("body")
+        .attr("value")
+        .attr("value"),
+        ObjectPath.root()
+        .attr("functions")
+        .map_value(module2.get_global_var("func"))
+        .attr("body")
+        .attr("value")
+        .attr("value"),
     )
 
 
diff --git a/tests/python/unittest/test_tvmscript_printer_underlining.py 
b/tests/python/unittest/test_tvmscript_printer_underlining.py
index 7230d4546a..4a4d17d0d8 100644
--- a/tests/python/unittest/test_tvmscript_printer_underlining.py
+++ b/tests/python/unittest/test_tvmscript_printer_underlining.py
@@ -27,7 +27,7 @@ from tvm.script.printer.doc import (
     StmtBlockDoc,
 )
 from tvm.script.printer.doc_printer import to_python_script
-from tvm.script import tir as T
+from tvm.script import ir as I, tir as T
 
 
 def make_path(name: str) -> ObjectPath:
@@ -470,3 +470,87 @@ def test_underline_from_multi_obj():
             ^^^^^^^^^^^^^
     """
     )
+
+
+def test_underline_func():
+    @T.prim_func
+    def func():
+        T.evaluate(0)
+
+    result = func.script(
+        path_to_underline=[
+            ObjectPath.root(),
+        ]
+    )
+    assert result == format_script(
+        """
+        # from tvm.script import tir as T
+
+        @T.prim_func
+        ^^^^^^^^^^^^
+        def main():
+        ^^^^^^^^^^^
+            T.evaluate(0)
+            ^^^^^^^^^^^^^
+    """
+    )
+
+
+def test_underline_func_in_irmodule():
+    @I.ir_module
+    class irmodule:
+        @T.prim_func
+        def func():
+            T.evaluate(0)
+
+    result = irmodule.script(
+        path_to_underline=[
+            
ObjectPath.root().attr("functions").map_value(irmodule.get_global_var("func")),
+        ]
+    )
+    assert result == format_script(
+        """
+        # from tvm.script import ir as I
+        # from tvm.script import tir as T
+
+        @I.ir_module
+        class Module:
+            @T.prim_func
+            ^^^^^^^^^^^^
+            def func():
+            ^^^^^^^^^^^
+                T.evaluate(0)
+                ^^^^^^^^^^^^^
+    """
+    )
+
+
+def test_underline_irmodule():
+    @I.ir_module
+    class irmodule:
+        @T.prim_func
+        def func():
+            T.evaluate(0)
+
+    result = irmodule.script(
+        path_to_underline=[
+            ObjectPath.root(),
+        ]
+    )
+    assert result == format_script(
+        """
+        # from tvm.script import ir as I
+        # from tvm.script import tir as T
+
+        @I.ir_module
+        ^^^^^^^^^^^^
+        class Module:
+        ^^^^^^^^^^^^^
+            @T.prim_func
+            ^^^^^^^^^^^^
+            def func():
+            ^^^^^^^^^^^
+                T.evaluate(0)
+                ^^^^^^^^^^^^^
+    """
+    )

Reply via email to