class_docstr: Detect the pattern ``concat-->reshape--->transpose--->reshape``, where ``concat`` is
  along the channel axis ``(axis=-3)``, and map this pattern to the ``concat`` with ``interleave`` op.
  
  This pattern occurs, for example, in the ``shufflenet`` model in ``torchvision``.
  
  .. code-block::
  
      Given:
          %3 = concat(%1.a, %1.b, ..., axis=-3, interleave=False) #shape = (B, n*C, H, W)
          %4 = reshape(%3) #shape = (B, n, C, H, W)
          %5 = transpose(%4, perm=[0, 2, 1, 3, 4]) # shape = (B, C, n, H, W)
          %6 = reshape(%5) # shape = (B, C*n, H, W)
  
      Result:
          %6 = concat(%1.a, %1.b, ..., axis=-3, interleave=True)
class_docstr_tok: ["Detect","the","pattern","``","concat","--",">","reshape","--","-",">","transpose","--","-",">","reshape","``",",","where","``","concat","``","is","along","the","channel","axis","``","(","axis=-3",")","``",",","and","map","this","pattern","to","the","``","concat","``","with","``","interleave","``","op",".","This","pattern","occurs",",","for","example",",","in","the","``","shufflenet","``","model","in","``","torchvision","``",".","..","code-block",":",":","Given",":","%","3","=","concat","(","%","1.a",",","%","1.b",",","...",",","axis=-3",",","interleave=False",")","#","shape","=","(","B",",","n","*","C",",","H",",","W",")","%","4","=","reshape","(","%","3",")","#","shape","=","(","B",",","n",",","C",",","H",",","W",")","%","5","=","transpose","(","%","4",",","perm=","[","0",",","2",",","1",",","3",",","4","]",")","#","shape","=","(","B",",","C",",","n",",","H",",","W",")","%","6","=","reshape","(","%","5",")","#","shape","=","(","B",",","C","*","n",",","H",",","W",")","Result",":","%","6","=","concat","(","%","1.a",",","%","1.b",",","...",",","axis=-3",",","interleave=True",")"]
code: def _try_to_transform(concat_op, add_op, block):
      all_ops = [concat_op]
      B, C, H, W = list(concat_op.values[0].shape)
      n = len(concat_op.values)
  
      # check that reshape shapes the input to (B, n, C, H, W)
      reshape_op1 = concat_op.outputs[0].child_ops[0]
      reshape_shape1 = reshape_op1.shape.val
      if reshape_shape1 is None:
          return False
      if not isinstance(reshape_shape1, np.ndarray):
          return False
      reshape_shape1 = list(reshape_shape1)
      if reshape_shape1 != [B, n, C, H, W]:
          return False
      all_ops.append(reshape_op1)
  
      # check that after reshape is a transpose op with perm=[0, 2, 1, 3, 4]
      if len(list(reshape_op1.outputs[0].child_ops)) != 1:
          return False
      transpose_op = list(reshape_op1.outputs[0].child_ops)[0]
      if transpose_op.op_type != "transpose":
          return False
      perm = transpose_op.perm.val
      if perm is None:
          return
      if list(perm) != [0, 2, 1, 3, 4]:
          return False
      all_ops.append(transpose_op)
  
      # check that after transpose is another reshape with [B, . , H, W]
      if len(list(transpose_op.outputs[0].child_ops)) != 1:
          return False
      reshape_op2 = list(transpose_op.outputs[0].child_ops)[0]
      if reshape_op2.op_type != "reshape":
          return False
      reshape_shape2 = reshape_op2.shape.val
      if reshape_shape2 is None:
          return False
      if not isinstance(reshape_shape2, np.ndarray):
          return False
      reshape_shape2 = list(reshape_shape2)
      if len(reshape_shape2) != 4:
          return False
      if [
          reshape_shape2[0],
          reshape_shape2[-2],
          reshape_shape2[-1],
      ] != [B, H, W]:
          return False
      all_ops.append(reshape_op2)
  
      # check that none of the op in this pattern is connected to the output
      # (except the last mul op)
      for i, op in enumerate(all_ops):
          if i == len(all_ops) - 1:
              continue
          for out in op.outputs:
              if out in block.outputs:
                  return False
  
      # add a new concat op
      out_name = reshape_op2.outputs[0].name
      x = mb.concat(
          values=concat_op.values,
          axis=concat_op.axis.val,
          interleave=True,
          name=out_name,
          before_op=concat_op,
      )
  
      reshape_op2.enclosing_block.replace_uses_of_var_after_op(
          anchor_op=reshape_op2,
          old_var=reshape_op2.outputs[0],
          new_var=x,
      )
  
      # Remove all the ops at once
      block.remove_ops(all_ops)
      return True
  
imports: import numpy
  from coremltools.converters.mil._deployment_compatibility import AvailableTarget
  from coremltools.converters.mil.frontend._utils import value_at
  from coremltools.converters.mil.mil import Builder
  from coremltools.converters.mil.mil.block import is_current_opset_version_compatible_with
  from coremltools.converters.mil.mil.passes.graph_pass import AbstractGraphPass
  from coremltools.converters.mil.mil.passes.helper import _check_child_op_type, _check_var_scalar_value, block_context_manager
  from coremltools.converters.mil.mil.passes.pass_registry import register_pass
  from coremltools.converters.mil.mil.types.symbolic import any_symbolic
label_desc: Use image node_id 3 for calling the detect_concat_interleave obj's underlying member method code with example usage: obj._try_to_transform(concat_op, add_op, block) and returns: True, False, False, False, False, False, False, False, False, False, False, False, False, False