class_docstr: Identify a reflection padding layer composed out of `slices` and `concats`.
  
  .. code-block::
  
      Input graph:
  
              ------------------------------------------------------------------------------------- |
              |                                                                                     v
      input(1, 2, 6, 8) ------> slice_by_index(begin=[0, 0, 0, 1], end=[0, 0, 0, 2]) -----> concat(axis=3) ---> out(1, 2, 6, 10)
              |                                                                                     ^
              ----------------> slice_by_index(begin=[0, 0, 0, -2], end=[0, 0, 0, -1]) -------------|
  
  
      Output graph:
  
      input(1, 2, 6, 8) -----0> pad(mode=reflect, size=[0, 0, 1, 1]) -----> out(1, 2, 6, 10)
class_docstr_tok: ["Identify","a","reflection","padding","layer","composed","out","of","`","slices","`","and","`","concats","`",".","..","code-block",":",":","Input","graph",":","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","--","-","|","|","v","input","(","1",",","2",",","6",",","8",")","--","--","--",">","slice_by_index","(","begin=","[","0",",","0",",","0",",","1","]",",","end=","[","0",",","0",",","0",",","2","]",")","--","--","-",">","concat","(","axis=3",")","--","-",">","out","(","1",",","2",",","6",",","10",")","|","^","--","--","--","--","--","--","--","--",">","slice_by_index","(","begin=","[","0",",","0",",","0",",","-2","]",",","end=","[","0",",","0",",","0",",","-1","]",")","--","--","--","--","--","--","-|","Output","graph",":","input","(","1",",","2",",","6",",","8",")","--","--","-0",">","pad","(","mode=reflect",",","size=","[","0",",","0",",","1",",","1","]",")","--","--","-",">","out","(","1",",","2",",","6",",","10",")"]
code: def _match_pattern(concat_op, block):
      if concat_op.op_type != "concat":
          return False
  
      concat_inputs = list(concat_op.inputs["values"])
      # There need to be an odd number of inputs, and at least one model has a concat input of
      # length 1
      if len(concat_inputs) % 2 != 1 or len(concat_inputs) == 1:
          return False
  
      # The original input will need to be in the middle of the concatenated inputs
      original_input = concat_inputs[len(concat_inputs) // 2]
  
      axis = None
      slice_ops_out = []
      end_mask = None
      begin_index = len(concat_inputs) // 2
  
      for slice_op in concat_inputs:
          # one of the concat inputs is the original input (to the slices)
          if slice_op == original_input:
              # We'll now start checking indices from the end
              begin_index = begin_index - 2
              continue
  
          slice_op = slice_op.op
          if not slice_op:
              return False
  
          if slice_op.op_type != "slice_by_index":
              return False
  
          # check that the input to slice op is the original input
          if slice_op.inputs["x"] != original_input:
              return False
  
          # If the slice is an output
          if slice_op.outputs[0] in block.outputs:
              return False
  
          if end_mask is None:
              end_mask = slice_op.inputs["end_mask"].val
              axis = list(end_mask).index(False, 0, len(end_mask))
  
          if end_mask is None:
              return False
  
          if axis != list(end_mask).index(False, 0, len(end_mask)):
              return False
  
          # Check that we're only taking a slice of size 1
          end = slice_op.inputs["end"].val
          begin = slice_op.inputs["begin"].val
          if end[axis] - begin[axis] != 1:
              return False
  
          input_shape = original_input.shape
          # Check that the slices are in order
          if (
              begin[axis] != begin_index
              and begin[axis] != begin_index + input_shape[axis]
          ):
              return False
          begin_index = begin_index - 1
  
          slice_ops_out.append(slice_op)
  
      if axis is None:
          return False
  
      return use_reflection_padding._replace_ops(
          block, concat_op, slice_ops_out, axis - len(end_mask)
      )
  
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 2 for calling the use_reflection_padding obj's underlying member method code with example usage: obj._match_pattern(concat_op, block) and returns: use_reflection_padding, False, False, False, False, False, False, False, False, False, False, False