class_docstr: Input graph:
  input -----> transpose(axis=[1,0]) -----> transpose(axis=[1,0]) ---> out
  
  Output graph:
  input -----> identity -----> out
class_docstr_tok: ["Input","graph",":","input","--","--","-",">","transpose","(","axis=","[","1,0","]",")","--","--","-",">","transpose","(","axis=","[","1,0","]",")","--","-",">","out","Output","graph",":","input","--","--","-",">","identity","--","--","-",">","out"]
docstr: Input graph:
  input -----> out (consist of duplicated input)
  
  Output graph:
  input -----> out (consist of duplicated input)
  
  Notice that a temp identity sink is added for all outputs, so the block before going through the pass is:
      function[CoreML3](%x: (2, 2, 1, 1, fp32)(Tensor)) {
        block0() {
          %identity_0: (2, 2, 1, 1, fp32)(Tensor) = identity(x=%x, name="identity_0")
        } -> (%identity_0, %identity_0)
      }
docstr_tok: ["Input","graph",":","input","--","--","-",">","out","(","consist","of","duplicated","input",")","Output","graph",":","input","--","--","-",">","out","(","consist","of","duplicated","input",")","Notice","that","a","temp","identity","sink","is","added","for","all","outputs",",","so","the","block","before","going","through","the","pass","is",":","function","[","CoreML3","]","(","%","x",":","(","2",",","2",",","1",",","1",",","fp32",")","(","Tensor",")",")","{","block0","(",")","{","%","identity_0",":","(","2",",","2",",","1",",","1",",","fp32",")","(","Tensor",")","=","identity","(","x=","%","x",",","name=","''","identity_0","''",")","}","-",">","(","%","identity_0",",","%","identity_0",")","}"]
code: def test_input_duplicate_output(self):
      """
      Input graph:
      input -----> out (consist of duplicated input)
  
      Output graph:
      input -----> out (consist of duplicated input)
  
      Notice that a temp identity sink is added for all outputs, so the block before going through the pass is:
          function[CoreML3](%x: (2, 2, 1, 1, fp32)(Tensor)) {
            block0() {
              %identity_0: (2, 2, 1, 1, fp32)(Tensor) = identity(x=%x, name="identity_0")
            } -> (%identity_0, %identity_0)
          }
      """
  
      @mb.program(input_specs=[mb.TensorSpec(shape=(2, 2, 1, 1))])
      def prog(x):
          return x, x
  
      prev_prog, prev_block, block = apply_pass_and_basic_check(
          prog, "common::reduce_transposes"
      )
  
      self.assertEqual(get_op_types_in_program(prev_prog), [])
      self.assertEqual(get_op_types_in_program(prog), [])
      assert_model_is_valid(
          prog,
          {"x": (2, 2, 1, 1)},
          backend=("mlprogram", "fp16"),
          expected_output_shapes={
              block.outputs[0].name: (2, 2, 1, 1),
              block.outputs[1].name: (2, 2, 1, 1),
          },
      )
  
imports: import unittest
  import numpy
  import pytest
  from coremltools.converters.mil.mil import Builder
  from coremltools.converters.mil.mil import get_new_symbol
  from coremltools.converters.mil.mil.passes.defs.optimize_repeat_ops import TransformAxisUpdateOps
  from coremltools.converters.mil.mil.passes.pass_registry import PASS_REGISTRY
  from coremltools.converters.mil.testing_utils import apply_pass_and_basic_check, assert_model_is_valid, get_op_types_in_program
label_desc: Use image node_id 45 for calling the TransposeOptimizationPass obj's underlying member method code with example usage: obj.test_input_duplicate_output() and returns: x,  x