psrivas2 opened a new issue, #14240:
URL: https://github.com/apache/tvm/issues/14240

   How is scoping handled in `assert_structural_equal`?
   
   Take an example of following two IRModules
   ```python
       # a relax function object created separately
       @R.function
       def foo(y: R.Object):
           return y
   
       @I.ir_module
       class Foo:
           @R.function
           def main(x: R.Object):
               return foo(x)
   
       @I.ir_module
       class Bar:
           @R.function
           def main(x: R.Object):
               @R.function
               def bar(y: R.Object):
                   return y
               return bar(x)
   
       tvm.ir.assert_structural_equal(Foo, Bar, map_free_vars=True) # succeeds
   ``` 
   
   If we compare the two IRModules `Foo` and `Bar`, structural equal check 
would pass as expected since their ASTs are identical (shown below). The `main` 
function in both defines a local func `inner func` and returns `inner_func(x)`. 
   ```python
   @I.ir_module
   class Module:
       @R.function
       def main(x: R.Tensor((16,), dtype="float32")) -> R.Tensor((16,), 
dtype="float32"):
           @R.function
           def inner_func(y: R.Tensor((16,), dtype="float32")) -> 
R.Tensor((16,), dtype="float32"):
               return y
           gv1: R.Tensor((16,), dtype="float32") = inner_func(x)
           return gv1
   ```
   
   However, if we add another function `some_func` to both the modules `Foo` 
and `Bar` that is identical to `main`, the modules would fail structural equal 
test. See below:
   ```python
       # a relax function object created separately
       @R.function
       def foo(y: R.Object):
           return y
   
       @I.ir_module
       class Foo:
           @R.function
           def main(x: R.Object):
               return foo(x)
           @R.function
           def some_func(x: R.Object):
               return foo(x)
   
       @I.ir_module
       class Bar:
           @R.function
           def main(x: R.Object):
               @R.function
               def bar0(y: R.Object):
                   return y
               return bar0(x)
           @R.function
           def some_func(x: R.Object):
               @R.function
               def bar1(y: R.Object):
                   return y
               return bar1(x)
   
       tvm.ir.assert_structural_equal(Foo, Bar, map_free_vars=True)  # fails
   ```
   
   This failure is unexpected, as `inner_func` is local to functions `main` and 
`some` is both the IRModules. So as long as 
`tvm.ir.assert_structural_equal(Foo["main"], Bar["main"])` and 
`tvm.ir.assert_structural_equal(Foo["some_func"], Bar["some_func"])` succeed, 
the module structural equality should pass. 
   
   The root cause seems to be how we handle scoping in structural equality. 
When we compare `main` functions, `foo` gets mapped to `bar0` and then later 
when we compare `some_func`, comparing `foo` and `bar1` fails as `foo` is 
already mapped to `bar0`.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to