code: def test_multiple_input_subgraphs():
      r"""Test the case when multiple input subgraphs feed into another subgraph.
  
       (1)    (2)    (3)    (4)
      add    add    add    add
       |      |      |      |
      relu   relu   relu   relu
       \      /      \      /
        \   /         \   /
         add           sub
          \            /
            \        /
              \    /
                mul
  
      ----> When 1=3 and 2=4 (Case 'A')
  
      add_relu  add_relu
         \         /
          \      /
         add_sub_mul
  
      ----> When 1!=3 and 2!=4 (Case 'B')
  
      add_relu  add_relu  add_relu  add_relu
         \       /           \       /
           \   /               \   /
            add                 sub
             \                  /
              --------     -----
                     \    /
                      mul
  
      The difference in behaviour comes from the fact that add_sub_mul expects that the
      inputs to add and sub are identical (the same two relay expressions). So when you
      have 4 independent inputs, the pattern should not be merged.
      """
  
      def before():
          before_funcs = {}
          inputs = [
              relay.var("input_" + str(i), shape=(10, 10))
              for i in range(8)
          ]
          add_relu_1 = relay.add(inputs[0], inputs[1])
          add_relu_1 = relay.nn.relu(add_relu_1)
          add_relu_2 = relay.add(inputs[2], inputs[3])
          add_relu_2 = relay.nn.relu(add_relu_2)
          add_relu_3 = relay.add(inputs[4], inputs[5])
          add_relu_3 = relay.nn.relu(add_relu_3)
          add_relu_4 = relay.add(inputs[6], inputs[7])
          add_relu_4 = relay.nn.relu(add_relu_4)
          add = relay.add(add_relu_1, add_relu_2)
          sub = relay.subtract(add_relu_3, add_relu_4)
          out = relay.multiply(add, sub)
          before_funcs["B"] = relay.Function(inputs, out)
          sub = relay.subtract(add_relu_1, add_relu_2)
          out = relay.multiply(add, sub)
          before_funcs["A"] = relay.Function(inputs[:4], out)
          return before_funcs
  
      def after_A():
          inputs = [
              relay.var("input_" + str(i), shape=(10, 10))
              for i in range(4)
          ]
          x = relay.var("x")
          y = relay.var("y")
          add_relu_1 = relay.add(x, y)
          add_relu_1 = relay.nn.relu(add_relu_1)
          add_relu_1 = relay.Function([x, y], add_relu_1)
          add_relu_1 = add_relu_1.with_attr("Composite", "add_relu")
          add_relu_1 = add_relu_1.with_attr(
              "PartitionedFromPattern", "add_nn.relu_"
          )
          add_relu_call_1 = relay.Call(
              add_relu_1, [inputs[0], inputs[1]]
          )
          x1 = relay.var("x1")
          y1 = relay.var("y1")
          add_relu_2 = relay.add(x1, y1)
          add_relu_2 = relay.nn.relu(add_relu_2)
          add_relu_2 = relay.Function([x1, y1], add_relu_2)
          add_relu_2 = add_relu_2.with_attr("Composite", "add_relu")
          add_relu_2 = add_relu_2.with_attr(
              "PartitionedFromPattern", "add_nn.relu_"
          )
          add_relu_call_2 = relay.Call(
              add_relu_2, [inputs[2], inputs[3]]
          )
          x2 = relay.var("x2")
          y2 = relay.var("y2")
          add = relay.add(x2, y2)
          sub = relay.subtract(x2, y2)
          add_sub_mul = relay.multiply(add, sub)
          add_sub_mul = relay.Function([x2, y2], add_sub_mul)
          add_sub_mul = add_sub_mul.with_attr(
              "Composite", "add_sub_mul"
          )
          add_sub_mul = add_sub_mul.with_attr(
              "PartitionedFromPattern", "add_subtract_multiply_"
          )
          add_sub_mul_call = relay.Call(
              add_sub_mul, [add_relu_call_1, add_relu_call_2]
          )
          return relay.Function(inputs, add_sub_mul_call)
  
      def after_B():
          inputs = [
              relay.var("input_" + str(i), shape=(10, 10))
              for i in range(8)
          ]
          add_relu_calls = []
          for i in range(4):
              x = relay.var("x" + str(i))
              y = relay.var("x" + str(i))
              add_relu = relay.add(x, y)
              add_relu = relay.nn.relu(add_relu)
              add_relu = relay.Function([x, y], add_relu)
              add_relu = add_relu.with_attr("Composite", "add_relu")
              add_relu = add_relu.with_attr(
                  "PartitionedFromPattern", "add_nn.relu_"
              )
              add_relu_call = relay.Call(
                  add_relu, [inputs[i * 2], inputs[i * 2 + 1]]
              )
              add_relu_calls.append(add_relu_call)
  
          add = relay.add(add_relu_calls[0], add_relu_calls[1])
          sub = relay.subtract(add_relu_calls[2], add_relu_calls[3])
          out = relay.multiply(add, sub)
          return relay.Function(inputs, out)
  
      pattern_table = [
          ("add_sub_mul", make_add_sub_mul_pattern()),
          ("add_relu", make_add_relu_pattern()),
      ]
      check_result(pattern_table, before()["A"], after_A())
      check_result(pattern_table, before()["B"], after_B())
  
imports: import pytest
  import tvm
  from tvm import relay, tir
  from tvm.relay.dataflow_pattern import TuplePattern, TupleGetItemPattern, is_op, wildcard
  from tvm.relay.testing import run_opt_pass
label_desc: Use image node_id 15 for calling a global function with example usage: test_multiple_input_subgraphs() and returns: before_funcs, relay, relay