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

bohan pushed a commit to branch unity
in repository https://gitbox.apache.org/repos/asf/tvm.git


The following commit(s) were added to refs/heads/unity by this push:
     new 34e87ae7f8 [Unity] Fix ConvertLayout on binary elemwise ops involving 
scalar input (#14961)
34e87ae7f8 is described below

commit 34e87ae7f8ad17eab5c4556e69d19cf859720113
Author: masahi <[email protected]>
AuthorDate: Wed May 31 04:07:12 2023 +0900

    [Unity] Fix ConvertLayout on binary elemwise ops involving scalar input 
(#14961)
---
 src/relax/op/tensor/binary.cc                      |  9 +++++
 src/relax/transform/convert_layout.cc              |  2 +-
 .../python/relax/test_transform_convert_layout.py  | 45 +++++++++++++++++++++-
 3 files changed, 54 insertions(+), 2 deletions(-)

diff --git a/src/relax/op/tensor/binary.cc b/src/relax/op/tensor/binary.cc
index 96d1f01e8a..d44b6da629 100644
--- a/src/relax/op/tensor/binary.cc
+++ b/src/relax/op/tensor/binary.cc
@@ -92,10 +92,19 @@ InferLayoutOutput InferLayoutBinaryEwise(const Call& call,
       << "Unknown dim tensors should not be handled by this function";
 
   if (x1_sinfo->ndim <= x2_sinfo->ndim) {
+    if (x1_sinfo->ndim == 0) {
+      LayoutDecision out_layout = layout2;
+      return InferLayoutOutput({LayoutDecision(""), layout2}, {out_layout}, 
Attrs(call->attrs));
+    }
     LayoutDecision out_layout = FollowDecision(layout1, x2_sinfo->ndim);
     return InferLayoutOutput({layout1, out_layout}, {out_layout}, 
Attrs(call->attrs));
   } else {
+    if (x2_sinfo->ndim == 0) {
+      LayoutDecision out_layout = layout1;
+      return InferLayoutOutput({layout1, LayoutDecision("")}, {out_layout}, 
Attrs(call->attrs));
+    }
     LayoutDecision out_layout = FollowDecision(layout2, x1_sinfo->ndim);
+
     return InferLayoutOutput({out_layout, layout2}, {out_layout}, 
Attrs(call->attrs));
   }
 }
diff --git a/src/relax/transform/convert_layout.cc 
b/src/relax/transform/convert_layout.cc
index 4f36cfbc0f..91dcd5d8e8 100644
--- a/src/relax/transform/convert_layout.cc
+++ b/src/relax/transform/convert_layout.cc
@@ -90,7 +90,7 @@ class LayoutConvertMutator : public ExprMutator {
   Expr RewriteExpr(const Expr& expr, const NLayout& to) {
     auto fvisitleaf = [&](const Expr& expr, std::array<NLayout, 2> layouts) -> 
Expr {
       NLayout from = layouts[0], to = layouts[1];
-      if (NLayoutEqual()(from, to)) return expr;
+      if (NLayoutEqual()(from, to) || layouts[0].LeafValue()->layout->name == 
"") return expr;
       // If not both from and to are unknown, then none of them can be unknown.
       ICHECK(!NLayoutEqual()(from, LayoutDecision::InitUnknownDim()) &&
              !NLayoutEqual()(to, LayoutDecision::InitUnknownDim()))
diff --git a/tests/python/relax/test_transform_convert_layout.py 
b/tests/python/relax/test_transform_convert_layout.py
index 5187ab30b7..570a53b48f 100644
--- a/tests/python/relax/test_transform_convert_layout.py
+++ b/tests/python/relax/test_transform_convert_layout.py
@@ -24,7 +24,6 @@ from tvm.script.parser import ir as I, relax as R, tir as T
 def verify(input, expected):
     mod = ConvertLayout({"relax.nn.conv2d": ["NHWC", "OHWI"]})(input)
     mod = Normalize()(mod)
-    print(mod.script())
     tvm.ir.assert_structural_equal(mod, expected)
 
 
@@ -1402,5 +1401,49 @@ def test_binary_broadcast():
     verify(Input, Expected)
 
 
+def test_binary_ewise_scalar():
+    @I.ir_module
+    class Input:
+        @R.function
+        def main(
+            x: R.Tensor((2, 3, 28, 28), "float32"), w: R.Tensor((4, 3, 3, 3), 
"float32")
+        ) -> R.Tensor(None, "float32", ndim=4):
+            with R.dataflow():
+                gv: R.Tensor((2, 4, 26, 26), "float32") = R.nn.conv2d(x, w, 
out_dtype="float32")
+                gv2: R.Tensor((2, 4, 26, 26), "float32") = R.add(gv, 
R.const(1, "float32"))
+                R.output(gv2)
+            return gv2
+
+    @I.ir_module
+    class Expected:
+        @R.function
+        def main(
+            x: R.Tensor((2, 3, 28, 28), dtype="float32"), w: R.Tensor((4, 3, 
3, 3), dtype="float32")
+        ) -> R.Tensor((2, 4, 26, 26), dtype="float32"):
+            with R.dataflow():
+                lv: R.Tensor((2, 28, 28, 3), dtype="float32") = 
R.permute_dims(x, axes=[0, 2, 3, 1])
+                lv1: R.Tensor((4, 3, 3, 3), dtype="float32") = 
R.permute_dims(w, axes=[0, 2, 3, 1])
+                gv: R.Tensor((2, 26, 26, 4), dtype="float32") = R.nn.conv2d(
+                    lv,
+                    lv1,
+                    strides=[1, 1],
+                    padding=[0, 0, 0, 0],
+                    dilation=[1, 1],
+                    groups=1,
+                    data_layout="NHWC",
+                    kernel_layout="OHWI",
+                    out_layout="NHWC",
+                    out_dtype="float32",
+                )
+                lv2: R.Tensor((2, 26, 26, 4), dtype="float32") = R.add(gv, 
R.const(1, "float32"))
+                gv2: R.Tensor((2, 4, 26, 26), dtype="float32") = 
R.permute_dims(
+                    lv2, axes=[0, 3, 1, 2]
+                )
+                R.output(gv2)
+            return gv2
+
+    verify(Input, Expected)
+
+
 if __name__ == "__main__":
     tvm.testing.main()

Reply via email to