code: def test_transpose_convert_layout():
      def verify_transpose(
          after, expected_axes, expected_transform_cnt
      ):
          # Verify if the transpose after the convert layout has the expected axes.
          has_expected = list()
          checker = lambda x: has_expected.append(
              isinstance(x, tvm.relay.expr.Call)
              and x.op.name == "transpose"
              and str(x.attrs.axes) == str(expected_axes)
          )
          relay.analysis.post_order_visit(after, checker)
          assert any(has_expected), after
  
          is_transform = list()
          checker = lambda x: is_transform.append(
              1
              if isinstance(x, tvm.relay.expr.Call)
              and x.op.name == "layout_transform"
              else 0
          )
          relay.analysis.post_order_visit(after, checker)
          assert (
              sum(is_transform) == expected_transform_cnt
          ), "Expected %s layout_transform, but get\n%s" % (
              expected_transform_cnt,
              after,
          )
  
      def nhwc_to_nchw():
          x = relay.var("x", shape=(1, 56, 56, 64))
          weight1 = relay.var("weight1", shape=(3, 3, 64, 32))
          y = relay.nn.conv2d(
              x,
              weight1,
              channels=32,
              kernel_size=(3, 3),
              padding=(1, 1),
              data_layout="NHWC",
              kernel_layout="HWIO",
          )
          z = relay.var("z", shape=(56, 56, 32))
          out = relay.add(y, z)
          out = relay.transpose(out, axes=[0, 3, 1, 2])
          out = relay.nn.batch_flatten(out)
          func = relay.Function(analysis.free_vars(out), out)
          return run_opt_pass(
              func,
              transform.ConvertLayout(
                  {"nn.conv2d": ["NCHW", "default"]}
              ),
          )
  
      verify_transpose(nhwc_to_nchw(), [0, 1, 2, 3], 3)
  
      def nchw_to_nhwc():
          x = relay.var("x", shape=(1, 64, 56, 56))
          weight1 = relay.var("weight1", shape=(32, 64, 3, 3))
          y = relay.nn.conv2d(
              x,
              weight1,
              channels=32,
              kernel_size=(3, 3),
              padding=(1, 1),
              data_layout="NCHW",
              kernel_layout="OIHW",
          )
          z = relay.var("z", shape=(32, 56, 56))
          out = relay.add(y, z)
          out = relay.transpose(
              out, axes=[0, 2, -1, 1]
          )  # Also test a negative axis.
          out = relay.nn.batch_flatten(out)
          func = relay.Function(analysis.free_vars(out), out)
          return run_opt_pass(
              func,
              transform.ConvertLayout(
                  {"nn.conv2d": ["NHWC", "default"]}
              ),
          )
  
      verify_transpose(nchw_to_nhwc(), [0, 1, 2, 3], 3)
  
      def default_axes():
          x = relay.var("x", shape=(1, 64, 56, 56))
          weight1 = relay.var("weight1", shape=(32, 64, 3, 3))
          y = relay.nn.conv2d(
              x,
              weight1,
              channels=32,
              kernel_size=(3, 3),
              padding=(1, 1),
              data_layout="NCHW",
              kernel_layout="OIHW",
          )
          z = relay.var("z", shape=(32, 56, 56))
          out = relay.add(y, z)
          out = relay.transpose(
              out
          )  # No axes provided, will use the reversed axes.
          func = relay.Function(analysis.free_vars(out), out)
          return run_opt_pass(
              func,
              transform.ConvertLayout(
                  {"nn.conv2d": ["NHWC", "default"]}
              ),
          )
  
      verify_transpose(default_axes(), [2, 1, 3, 0], 3)
  
imports: import pytest
  import tvm
  from tvm import relay, te
  from tvm.relay import analysis, transform
  from tvm.relay.op import op
  from tvm.relay.op import register_alter_op_layout
  from tvm.relay.quantize._annotate import attach_simulated_quantize, QAnnotateKind
  from tvm.relay.transform.infer_layout_utils import InferCorrectLayoutOutput
label_desc: Use image node_id 15 for calling a global function with example usage: test_transpose_convert_layout() and returns: run_opt_pass, run_opt_pass, run_opt_pass