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

lunderberg 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 fac9520921 [Unity][Transform] Raise error in FuseOpsByPattern for SSA 
violation (#16421)
fac9520921 is described below

commit fac95209212a568b9effdf8b8525822ddfef728c
Author: Eric Lunderberg <[email protected]>
AuthorDate: Fri Feb 23 08:05:51 2024 -0600

    [Unity][Transform] Raise error in FuseOpsByPattern for SSA violation 
(#16421)
    
    Internally, `FuseOpsByPattern` makes a mapping from relax variables to
    the fused group containing that variable.  If the input module
    violates SSA, this map may be ill-formed.  While not strictly
    necessary for FuseOps to handle ill-formed inputs, checking it at this
    level provides better error handling than propagating it to downstream
    passes.
    
    This commit checks for ill-formed inputs that would produce invalid
    fused outputs and raises an error.
---
 src/relax/transform/fuse_ops.cc                     |  9 ++++++++-
 .../relax/test_transform_fuse_ops_by_pattern.py     | 21 +++++++++++++++++++++
 2 files changed, 29 insertions(+), 1 deletion(-)

diff --git a/src/relax/transform/fuse_ops.cc b/src/relax/transform/fuse_ops.cc
index 5ead71f3b3..5d3f80bb02 100644
--- a/src/relax/transform/fuse_ops.cc
+++ b/src/relax/transform/fuse_ops.cc
@@ -1286,7 +1286,14 @@ IRModule FuseOpsByPattern(const 
tvm::Array<transform::FusionPattern>& patterns,
                                               pattern->annotation_patterns,
                                               
pattern->check.value_or(nullptr), entry.second,
                                               &arena, 
pattern->attrs_getter.value_or(nullptr));
-      group_map.insert(map.begin(), map.end());
+      for (const auto& [key, value] : map) {
+        CHECK(!group_map.count(key))
+            << "ValueError: "
+            << "IRModule is invalid.  "
+            << "The object " << GetRef<ObjectRef>(key) << " appears in 
multiple partitions, "
+            << "which can occur when the IRModule was not single-site 
assignment";
+        group_map.insert({key, value});
+      }
     }
     mod = MakeGroupedFunctions(mod, group_map, /*lift_constants*/ 
!bind_constants);
   }
diff --git a/tests/python/relax/test_transform_fuse_ops_by_pattern.py 
b/tests/python/relax/test_transform_fuse_ops_by_pattern.py
index 99ca117d65..b6bcf01862 100644
--- a/tests/python/relax/test_transform_fuse_ops_by_pattern.py
+++ b/tests/python/relax/test_transform_fuse_ops_by_pattern.py
@@ -1109,5 +1109,26 @@ def test_multple_runs():
     )
 
 
[email protected]_well_formed_check_before_transform
+def test_error_on_repeated_variable_definitions():
+    """Raise error for SSA violations
+
+    Internally, `FuseOpsByPattern` makes a mapping from relax
+    variables to the fused group containing that variable.  If the
+    input module violates SSA, this map may be ill-formed.
+
+    While not strictly necessary for FuseOps to handle ill-formed
+    inputs, checking it at this level provides better error handling
+    than propagating it to downstream passes.
+    """
+    mod = Conv2dReLU.clone()
+    mod["copy"] = mod["main"].with_attr("global_symbol", "copy")
+
+    patterns = [("dnnl.conv2d_relu", conv2d_relu_pat)]
+
+    with pytest.raises(ValueError):
+        relax.transform.FuseOpsByPattern(patterns)(mod)
+
+
 if __name__ == "__main__":
     pytest.main([__file__])

Reply via email to