mbaret commented on a change in pull request #10759:
URL: https://github.com/apache/tvm/pull/10759#discussion_r839647945



##########
File path: tests/python/relay/test_pass_inline_composites.py
##########
@@ -0,0 +1,217 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+# pylint: disable=invalid-name, missing-docstring, too-many-statements
+"""Unit tests for inline composites."""
+import pytest
+import tvm
+from tvm import relay, tir
+from tvm.relay.dataflow_pattern import TupleGetItemPattern, is_op, wildcard
+from tvm.relay.testing import run_opt_pass
+
+"""
+The inline composite pass is designed to inline multiple kernel generated 
through 
+the merge composite composite pass. The underlying idea is to inline N kernels 
+produced from merge composite based on a given set of pattern into a single IR 
module.
+Also, clears Composite and PartionedFromPatterns that infer with certain BYOC 
implementations
+
+For example suppose we have the graph:
+
+        a  b                   
+        \ /              
+        add     
+         |            
+       relu                            
+
+Merge composite will wrap each standalone op to it's own function, while 
setting Composite and
+PartitionedFromPattern attrs. 
+       
+Relay IR after merge composite pass when registering each op as a standalone 
pattern: 
+fn (%a: Tensor[(10, 10), float32], %b: Tensor[(10, 10), float32]) -> 
Tensor[(10, 10), float32] {
+  %0 = fn (%FunctionVar_0_01: Tensor[(10, 10), float32], %FunctionVar_0_1: 
Tensor[(10, 10), float32], PartitionedFromPattern="add_", Composite="add") -> 
Tensor[(10, 10), float32] {
+    add(%FunctionVar_0_01, %FunctionVar_0_1) /* ty=Tensor[(10, 10), float32] */
+  };
+  %1 = %0(%a, %b) /* ty=Tensor[(10, 10), float32] */;
+  %2 = fn (%FunctionVar_0_0: Tensor[(10, 10), float32], 
PartitionedFromPattern="nn.relu_", Composite="nn.relu") -> Tensor[(10, 10), 
float32] {
+    nn.relu(%FunctionVar_0_0) /* ty=Tensor[(10, 10), float32] */
+  };
+  %2(%1) /* ty=Tensor[(10, 10), float32] */
+}
+
+Relay IR after inline composites pass:
+fn (%a: Tensor[(10, 10), float32], %b: Tensor[(10, 10), float32]) -> 
Tensor[(10, 10), float32] {
+  %0 = add(%a, %b) /* ty=Tensor[(10, 10), float32] */;
+  nn.relu(%0) /* ty=Tensor[(10, 10), float32] */
+}
+
+One conventient use of this pass is to use Pattern-based operator support to 
move away

Review comment:
       convenient

##########
File path: tests/python/relay/test_pass_inline_composites.py
##########
@@ -0,0 +1,217 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+# pylint: disable=invalid-name, missing-docstring, too-many-statements
+"""Unit tests for inline composites."""
+import pytest
+import tvm
+from tvm import relay, tir
+from tvm.relay.dataflow_pattern import TupleGetItemPattern, is_op, wildcard
+from tvm.relay.testing import run_opt_pass
+
+"""
+The inline composite pass is designed to inline multiple kernel generated 
through 
+the merge composite composite pass. The underlying idea is to inline N kernels 
+produced from merge composite based on a given set of pattern into a single IR 
module.
+Also, clears Composite and PartionedFromPatterns that infer with certain BYOC 
implementations
+
+For example suppose we have the graph:
+
+        a  b                   
+        \ /              
+        add     
+         |            
+       relu                            
+
+Merge composite will wrap each standalone op to it's own function, while 
setting Composite and
+PartitionedFromPattern attrs. 
+       
+Relay IR after merge composite pass when registering each op as a standalone 
pattern: 
+fn (%a: Tensor[(10, 10), float32], %b: Tensor[(10, 10), float32]) -> 
Tensor[(10, 10), float32] {
+  %0 = fn (%FunctionVar_0_01: Tensor[(10, 10), float32], %FunctionVar_0_1: 
Tensor[(10, 10), float32], PartitionedFromPattern="add_", Composite="add") -> 
Tensor[(10, 10), float32] {
+    add(%FunctionVar_0_01, %FunctionVar_0_1) /* ty=Tensor[(10, 10), float32] */
+  };
+  %1 = %0(%a, %b) /* ty=Tensor[(10, 10), float32] */;
+  %2 = fn (%FunctionVar_0_0: Tensor[(10, 10), float32], 
PartitionedFromPattern="nn.relu_", Composite="nn.relu") -> Tensor[(10, 10), 
float32] {
+    nn.relu(%FunctionVar_0_0) /* ty=Tensor[(10, 10), float32] */
+  };
+  %2(%1) /* ty=Tensor[(10, 10), float32] */
+}
+
+Relay IR after inline composites pass:
+fn (%a: Tensor[(10, 10), float32], %b: Tensor[(10, 10), float32]) -> 
Tensor[(10, 10), float32] {
+  %0 = add(%a, %b) /* ty=Tensor[(10, 10), float32] */;
+  nn.relu(%0) /* ty=Tensor[(10, 10), float32] */
+}
+
+One conventient use of this pass is to use Pattern-based operator support to 
move away
+from the original operator predicates, and inline them into a single primitive 
function to offload it 
+to an external BYOC backend, such as TensorRT.
+"""
+
+
+def make_conv_bias_relu_pattern():
+    r"""Create a pattern to match the following graph.
+
+     conv2d
+       |
+    bias_add
+       |
+     relu
+    """
+    x = wildcard()
+    y = wildcard()
+    z = wildcard()
+    conv_node = is_op("nn.conv2d")(x, y)
+    bias_node = is_op("nn.bias_add")(conv_node, z)
+    r = is_op("nn.relu")(bias_node)
+    return r
+
+
+def make_add_relu_pattern():
+    r"""Create a pattern to match the following graph.
+
+     add
+      |
+    relu
+    """
+    add_node = wildcard() + wildcard()
+    r = is_op("nn.relu")(add_node)
+    return r
+
+
+def make_relu_pattern():
+    r"""Create a pattern to match the following graph
+     a
+     |
+    relu
+     |
+    """
+    pattern = is_op("nn.relu")(wildcard())
+    return pattern
+
+
+def make_add_pattern():
+    r"""Create a pattern to match the following graph
+    a  b
+    \  /
+    add
+     |
+    """
+    pattern = is_op("add")(wildcard(), wildcard())
+    return pattern
+
+
+def check_result(pattern_table, graph, expected_graph, import_prelude=False):
+    """Utility function to check inline composites results."""
+    result = run_opt_pass(
+        graph, relay.transform.MergeComposite(pattern_table), 
import_prelude=import_prelude
+    )
+    print("merge composite reusult")
+    print(result)
+    print("---------------------")

Review comment:
       We should probably omit the prints.

##########
File path: tests/python/relay/test_pass_inline_composites.py
##########
@@ -0,0 +1,217 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+# pylint: disable=invalid-name, missing-docstring, too-many-statements
+"""Unit tests for inline composites."""
+import pytest
+import tvm
+from tvm import relay, tir
+from tvm.relay.dataflow_pattern import TupleGetItemPattern, is_op, wildcard
+from tvm.relay.testing import run_opt_pass
+
+"""
+The inline composite pass is designed to inline multiple kernel generated 
through 
+the merge composite composite pass. The underlying idea is to inline N kernels 
+produced from merge composite based on a given set of pattern into a single IR 
module.
+Also, clears Composite and PartionedFromPatterns that infer with certain BYOC 
implementations
+
+For example suppose we have the graph:
+
+        a  b                   
+        \ /              
+        add     
+         |            
+       relu                            
+
+Merge composite will wrap each standalone op to it's own function, while 
setting Composite and
+PartitionedFromPattern attrs. 
+       
+Relay IR after merge composite pass when registering each op as a standalone 
pattern: 
+fn (%a: Tensor[(10, 10), float32], %b: Tensor[(10, 10), float32]) -> 
Tensor[(10, 10), float32] {
+  %0 = fn (%FunctionVar_0_01: Tensor[(10, 10), float32], %FunctionVar_0_1: 
Tensor[(10, 10), float32], PartitionedFromPattern="add_", Composite="add") -> 
Tensor[(10, 10), float32] {
+    add(%FunctionVar_0_01, %FunctionVar_0_1) /* ty=Tensor[(10, 10), float32] */
+  };
+  %1 = %0(%a, %b) /* ty=Tensor[(10, 10), float32] */;
+  %2 = fn (%FunctionVar_0_0: Tensor[(10, 10), float32], 
PartitionedFromPattern="nn.relu_", Composite="nn.relu") -> Tensor[(10, 10), 
float32] {
+    nn.relu(%FunctionVar_0_0) /* ty=Tensor[(10, 10), float32] */
+  };
+  %2(%1) /* ty=Tensor[(10, 10), float32] */
+}
+
+Relay IR after inline composites pass:
+fn (%a: Tensor[(10, 10), float32], %b: Tensor[(10, 10), float32]) -> 
Tensor[(10, 10), float32] {
+  %0 = add(%a, %b) /* ty=Tensor[(10, 10), float32] */;
+  nn.relu(%0) /* ty=Tensor[(10, 10), float32] */
+}
+
+One conventient use of this pass is to use Pattern-based operator support to 
move away
+from the original operator predicates, and inline them into a single primitive 
function to offload it 
+to an external BYOC backend, such as TensorRT.
+"""
+
+
+def make_conv_bias_relu_pattern():
+    r"""Create a pattern to match the following graph.
+
+     conv2d
+       |
+    bias_add
+       |
+     relu
+    """
+    x = wildcard()
+    y = wildcard()
+    z = wildcard()
+    conv_node = is_op("nn.conv2d")(x, y)
+    bias_node = is_op("nn.bias_add")(conv_node, z)
+    r = is_op("nn.relu")(bias_node)
+    return r
+
+
+def make_add_relu_pattern():
+    r"""Create a pattern to match the following graph.
+
+     add
+      |
+    relu
+    """
+    add_node = wildcard() + wildcard()
+    r = is_op("nn.relu")(add_node)
+    return r
+
+
+def make_relu_pattern():
+    r"""Create a pattern to match the following graph
+     a
+     |
+    relu
+     |
+    """
+    pattern = is_op("nn.relu")(wildcard())
+    return pattern
+
+
+def make_add_pattern():
+    r"""Create a pattern to match the following graph
+    a  b
+    \  /
+    add
+     |
+    """
+    pattern = is_op("add")(wildcard(), wildcard())
+    return pattern
+
+
+def check_result(pattern_table, graph, expected_graph, import_prelude=False):
+    """Utility function to check inline composites results."""
+    result = run_opt_pass(
+        graph, relay.transform.MergeComposite(pattern_table), 
import_prelude=import_prelude
+    )

Review comment:
       I think we should put some form of check here just to confirm that a 
composite function has been created (so we know MergeComposite didn't just skip 
everything if for instance there was a pattern error).

##########
File path: tests/python/relay/test_pass_inline_composites.py
##########
@@ -0,0 +1,217 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+# pylint: disable=invalid-name, missing-docstring, too-many-statements
+"""Unit tests for inline composites."""
+import pytest
+import tvm
+from tvm import relay, tir
+from tvm.relay.dataflow_pattern import TupleGetItemPattern, is_op, wildcard
+from tvm.relay.testing import run_opt_pass
+
+"""
+The inline composite pass is designed to inline multiple kernel generated 
through 
+the merge composite composite pass. The underlying idea is to inline N kernels 
+produced from merge composite based on a given set of pattern into a single IR 
module.
+Also, clears Composite and PartionedFromPatterns that infer with certain BYOC 
implementations
+
+For example suppose we have the graph:
+
+        a  b                   
+        \ /              
+        add     
+         |            
+       relu                            
+
+Merge composite will wrap each standalone op to it's own function, while 
setting Composite and
+PartitionedFromPattern attrs. 
+       
+Relay IR after merge composite pass when registering each op as a standalone 
pattern: 
+fn (%a: Tensor[(10, 10), float32], %b: Tensor[(10, 10), float32]) -> 
Tensor[(10, 10), float32] {
+  %0 = fn (%FunctionVar_0_01: Tensor[(10, 10), float32], %FunctionVar_0_1: 
Tensor[(10, 10), float32], PartitionedFromPattern="add_", Composite="add") -> 
Tensor[(10, 10), float32] {
+    add(%FunctionVar_0_01, %FunctionVar_0_1) /* ty=Tensor[(10, 10), float32] */
+  };
+  %1 = %0(%a, %b) /* ty=Tensor[(10, 10), float32] */;
+  %2 = fn (%FunctionVar_0_0: Tensor[(10, 10), float32], 
PartitionedFromPattern="nn.relu_", Composite="nn.relu") -> Tensor[(10, 10), 
float32] {
+    nn.relu(%FunctionVar_0_0) /* ty=Tensor[(10, 10), float32] */
+  };
+  %2(%1) /* ty=Tensor[(10, 10), float32] */
+}
+
+Relay IR after inline composites pass:
+fn (%a: Tensor[(10, 10), float32], %b: Tensor[(10, 10), float32]) -> 
Tensor[(10, 10), float32] {
+  %0 = add(%a, %b) /* ty=Tensor[(10, 10), float32] */;
+  nn.relu(%0) /* ty=Tensor[(10, 10), float32] */
+}
+
+One conventient use of this pass is to use Pattern-based operator support to 
move away
+from the original operator predicates, and inline them into a single primitive 
function to offload it 
+to an external BYOC backend, such as TensorRT.
+"""
+
+
+def make_conv_bias_relu_pattern():
+    r"""Create a pattern to match the following graph.
+
+     conv2d
+       |
+    bias_add
+       |
+     relu
+    """
+    x = wildcard()
+    y = wildcard()
+    z = wildcard()
+    conv_node = is_op("nn.conv2d")(x, y)
+    bias_node = is_op("nn.bias_add")(conv_node, z)
+    r = is_op("nn.relu")(bias_node)
+    return r
+
+
+def make_add_relu_pattern():
+    r"""Create a pattern to match the following graph.
+
+     add
+      |
+    relu
+    """
+    add_node = wildcard() + wildcard()
+    r = is_op("nn.relu")(add_node)
+    return r
+
+
+def make_relu_pattern():
+    r"""Create a pattern to match the following graph
+     a
+     |
+    relu
+     |
+    """
+    pattern = is_op("nn.relu")(wildcard())
+    return pattern
+
+
+def make_add_pattern():
+    r"""Create a pattern to match the following graph
+    a  b
+    \  /
+    add
+     |
+    """
+    pattern = is_op("add")(wildcard(), wildcard())
+    return pattern
+
+
+def check_result(pattern_table, graph, expected_graph, import_prelude=False):
+    """Utility function to check inline composites results."""
+    result = run_opt_pass(
+        graph, relay.transform.MergeComposite(pattern_table), 
import_prelude=import_prelude
+    )
+    print("merge composite reusult")
+    print(result)
+    print("---------------------")
+    result = run_opt_pass(
+        graph, relay.transform.InlineComposites(target=""), 
import_prelude=import_prelude
+    )
+    print(result)
+    print("-----------------")
+    assert not relay.analysis.free_vars(result), "Found free vars in the 
result graph: {0}".format(
+        str(result)
+    )
+    expected = run_opt_pass(expected_graph, relay.transform.InferType())
+    print(expected)
+    print("---------------")
+    assert tvm.ir.structural_equal(
+        result, expected, map_free_vars=True
+    ), "Graph mismatch: output vs. 
expected\n{0}\n=====\n{1}".format(str(result), str(expected))
+
+
+def test_single_op_registry():
+    r"""Test inline composite pass is correctly inline the merge composite 
result.
+
+    We could expect the pattern `make_add_relu_pattern` to be merged
+    into a single op `add_relu`.
+
+        a  b                           a  b
+        \ /              a  b          \  /
+        add    ====>     \ /    ===>   add
+         |             add_relu         |
+       relu                            relu
+
+    """
+    pattern_table = [("add", make_add_pattern()), ("nn.relu", 
make_relu_pattern())]

Review comment:
       This doesn't seem to match the description above.

##########
File path: tests/python/relay/test_pass_inline_composites.py
##########
@@ -0,0 +1,217 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+# pylint: disable=invalid-name, missing-docstring, too-many-statements
+"""Unit tests for inline composites."""
+import pytest
+import tvm
+from tvm import relay, tir
+from tvm.relay.dataflow_pattern import TupleGetItemPattern, is_op, wildcard
+from tvm.relay.testing import run_opt_pass
+
+"""
+The inline composite pass is designed to inline multiple kernel generated 
through 
+the merge composite composite pass. The underlying idea is to inline N kernels 
+produced from merge composite based on a given set of pattern into a single IR 
module.
+Also, clears Composite and PartionedFromPatterns that infer with certain BYOC 
implementations
+
+For example suppose we have the graph:
+
+        a  b                   
+        \ /              
+        add     
+         |            
+       relu                            
+
+Merge composite will wrap each standalone op to it's own function, while 
setting Composite and
+PartitionedFromPattern attrs. 
+       
+Relay IR after merge composite pass when registering each op as a standalone 
pattern: 
+fn (%a: Tensor[(10, 10), float32], %b: Tensor[(10, 10), float32]) -> 
Tensor[(10, 10), float32] {
+  %0 = fn (%FunctionVar_0_01: Tensor[(10, 10), float32], %FunctionVar_0_1: 
Tensor[(10, 10), float32], PartitionedFromPattern="add_", Composite="add") -> 
Tensor[(10, 10), float32] {
+    add(%FunctionVar_0_01, %FunctionVar_0_1) /* ty=Tensor[(10, 10), float32] */
+  };
+  %1 = %0(%a, %b) /* ty=Tensor[(10, 10), float32] */;
+  %2 = fn (%FunctionVar_0_0: Tensor[(10, 10), float32], 
PartitionedFromPattern="nn.relu_", Composite="nn.relu") -> Tensor[(10, 10), 
float32] {
+    nn.relu(%FunctionVar_0_0) /* ty=Tensor[(10, 10), float32] */
+  };
+  %2(%1) /* ty=Tensor[(10, 10), float32] */
+}
+
+Relay IR after inline composites pass:
+fn (%a: Tensor[(10, 10), float32], %b: Tensor[(10, 10), float32]) -> 
Tensor[(10, 10), float32] {
+  %0 = add(%a, %b) /* ty=Tensor[(10, 10), float32] */;
+  nn.relu(%0) /* ty=Tensor[(10, 10), float32] */
+}
+
+One conventient use of this pass is to use Pattern-based operator support to 
move away
+from the original operator predicates, and inline them into a single primitive 
function to offload it 
+to an external BYOC backend, such as TensorRT.
+"""
+
+
+def make_conv_bias_relu_pattern():
+    r"""Create a pattern to match the following graph.
+
+     conv2d
+       |
+    bias_add
+       |
+     relu
+    """
+    x = wildcard()
+    y = wildcard()
+    z = wildcard()
+    conv_node = is_op("nn.conv2d")(x, y)
+    bias_node = is_op("nn.bias_add")(conv_node, z)
+    r = is_op("nn.relu")(bias_node)
+    return r
+
+
+def make_add_relu_pattern():
+    r"""Create a pattern to match the following graph.
+
+     add
+      |
+    relu
+    """
+    add_node = wildcard() + wildcard()
+    r = is_op("nn.relu")(add_node)
+    return r
+
+
+def make_relu_pattern():
+    r"""Create a pattern to match the following graph
+     a
+     |
+    relu
+     |
+    """
+    pattern = is_op("nn.relu")(wildcard())
+    return pattern
+
+
+def make_add_pattern():
+    r"""Create a pattern to match the following graph
+    a  b
+    \  /
+    add
+     |
+    """
+    pattern = is_op("add")(wildcard(), wildcard())
+    return pattern
+
+
+def check_result(pattern_table, graph, expected_graph, import_prelude=False):
+    """Utility function to check inline composites results."""
+    result = run_opt_pass(
+        graph, relay.transform.MergeComposite(pattern_table), 
import_prelude=import_prelude
+    )
+    print("merge composite reusult")
+    print(result)
+    print("---------------------")
+    result = run_opt_pass(
+        graph, relay.transform.InlineComposites(target=""), 
import_prelude=import_prelude
+    )
+    print(result)
+    print("-----------------")
+    assert not relay.analysis.free_vars(result), "Found free vars in the 
result graph: {0}".format(
+        str(result)
+    )
+    expected = run_opt_pass(expected_graph, relay.transform.InferType())
+    print(expected)
+    print("---------------")
+    assert tvm.ir.structural_equal(
+        result, expected, map_free_vars=True
+    ), "Graph mismatch: output vs. 
expected\n{0}\n=====\n{1}".format(str(result), str(expected))
+
+
+def test_single_op_registry():
+    r"""Test inline composite pass is correctly inline the merge composite 
result.
+
+    We could expect the pattern `make_add_relu_pattern` to be merged
+    into a single op `add_relu`.
+
+        a  b                           a  b
+        \ /              a  b          \  /
+        add    ====>     \ /    ===>   add
+         |             add_relu         |
+       relu                            relu
+
+    """
+    pattern_table = [("add", make_add_pattern()), ("nn.relu", 
make_relu_pattern())]
+
+    def before():
+        a = relay.var("a", shape=(10, 10))
+        b = relay.var("b", shape=(10, 10))
+        add_node = relay.add(a, b)
+        r = relay.nn.relu(add_node)
+        return relay.Function([a, b], r)
+
+    def expected():
+        a = relay.var("a", shape=(10, 10))
+        b = relay.var("b", shape=(10, 10))
+
+        # add_relu function
+        in_1 = relay.var("in_1", shape=(10, 10))
+        in_2 = relay.var("in_2", shape=(10, 10))
+        add_node = relay.add(in_1, in_2)
+        relu_node = relay.nn.relu(add_node)
+        add_relu = relay.Function([in_1, in_2], relu_node)
+        return add_relu

Review comment:
       I think this is the same as before() (given a and b aren't used). If all 
we really want to test is that doing InlineComposites undoes MergeComposite, we 
can probably just test that the result is equal to the input.

##########
File path: tests/python/relay/test_pass_inline_composites.py
##########
@@ -0,0 +1,217 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+# pylint: disable=invalid-name, missing-docstring, too-many-statements
+"""Unit tests for inline composites."""
+import pytest
+import tvm
+from tvm import relay, tir
+from tvm.relay.dataflow_pattern import TupleGetItemPattern, is_op, wildcard
+from tvm.relay.testing import run_opt_pass
+
+"""
+The inline composite pass is designed to inline multiple kernel generated 
through 
+the merge composite composite pass. The underlying idea is to inline N kernels 
+produced from merge composite based on a given set of pattern into a single IR 
module.
+Also, clears Composite and PartionedFromPatterns that infer with certain BYOC 
implementations
+
+For example suppose we have the graph:
+
+        a  b                   
+        \ /              
+        add     
+         |            
+       relu                            
+
+Merge composite will wrap each standalone op to it's own function, while 
setting Composite and
+PartitionedFromPattern attrs. 
+       
+Relay IR after merge composite pass when registering each op as a standalone 
pattern: 
+fn (%a: Tensor[(10, 10), float32], %b: Tensor[(10, 10), float32]) -> 
Tensor[(10, 10), float32] {
+  %0 = fn (%FunctionVar_0_01: Tensor[(10, 10), float32], %FunctionVar_0_1: 
Tensor[(10, 10), float32], PartitionedFromPattern="add_", Composite="add") -> 
Tensor[(10, 10), float32] {
+    add(%FunctionVar_0_01, %FunctionVar_0_1) /* ty=Tensor[(10, 10), float32] */
+  };
+  %1 = %0(%a, %b) /* ty=Tensor[(10, 10), float32] */;
+  %2 = fn (%FunctionVar_0_0: Tensor[(10, 10), float32], 
PartitionedFromPattern="nn.relu_", Composite="nn.relu") -> Tensor[(10, 10), 
float32] {
+    nn.relu(%FunctionVar_0_0) /* ty=Tensor[(10, 10), float32] */
+  };
+  %2(%1) /* ty=Tensor[(10, 10), float32] */
+}
+
+Relay IR after inline composites pass:
+fn (%a: Tensor[(10, 10), float32], %b: Tensor[(10, 10), float32]) -> 
Tensor[(10, 10), float32] {
+  %0 = add(%a, %b) /* ty=Tensor[(10, 10), float32] */;
+  nn.relu(%0) /* ty=Tensor[(10, 10), float32] */
+}
+
+One conventient use of this pass is to use Pattern-based operator support to 
move away
+from the original operator predicates, and inline them into a single primitive 
function to offload it 
+to an external BYOC backend, such as TensorRT.
+"""
+
+
+def make_conv_bias_relu_pattern():

Review comment:
       This pattern doesn't seem to be used, I think either add a test for it 
or remove.




-- 
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