class_docstr: This graph pass does const folding to a chain of supported ops starts with a
  tensor-wise ``constexpr_affine_dequantize`` op. i.e., both ``scale`` and
  ``zero_point`` are scalar (rank 0).
  
  For example:
  Input graph:
      data -> constexpr_affine_dequantize -> transpose -> expand_dims -> out
  
  Output graph:
      new_data -> constexpr_affine_dequantize -> out
  
  where ``new_data`` is computed by ``data -> transpose -> expand_dims``.
  
  Note that, the graph pass only supports const folding of a single linked list pattern.
  For example, the following pattern will not be changed:
  
      data ---> constexpr_affine_dequantize -> transpose -> out
            |
            --> constexpr_affine_dequantize -> reshape -> out_2
class_docstr_tok: ["This","graph","pass","does","const","folding","to","a","chain","of","supported","ops","starts","with","a","tensor-wise","``","constexpr_affine_dequantize","``","op",".","i.e.",",","both","``","scale","``","and","``","zero_point","``","are","scalar","(","rank","0",")",".","For","example",":","Input","graph",":","data","-",">","constexpr_affine_dequantize","-",">","transpose","-",">","expand_dims","-",">","out","Output","graph",":","new_data","-",">","constexpr_affine_dequantize","-",">","out","where","``","new_data","``","is","computed","by","``","data","-",">","transpose","-",">","expand_dims","``",".","Note","that",",","the","graph","pass","only","supports","const","folding","of","a","single","linked","list","pattern",".","For","example",",","the","following","pattern","will","not","be","changed",":","data","--","-",">","constexpr_affine_dequantize","-",">","transpose","-",">","out","|","--",">","constexpr_affine_dequantize","-",">","reshape","-",">","out_2"]
code: def _try_to_transform(op, block):
      # first check if it is tensorwise quantization
      if op.scale.rank != 0 or op.zero_point.rank != 0:
          return False
  
      # first check if quantized_data only feeds into a single op
      if len(op.quantized_data.child_ops) != 1:
          return False
  
      # traverse the graph to get a chain of applicable ops to fold
      ops_to_fold = []
      cursor = op
      while True:
          prev_cursor = cursor
          if cursor.outputs[0] in block.outputs:
              break
          for (
              val
          ) in (
              merge_tensorwise_affine_dequantize_with_consecutive_ops.SUPPORTED_OPS
          ):
              if _check_child_op_type(cursor, val):
                  ops_to_fold.append(cursor.outputs[0].child_ops[0])
                  cursor = ops_to_fold[-1]
                  break
          if prev_cursor == cursor:
              break
  
      if len(ops_to_fold) == 0:
          return False
  
      # do the same transformation on the source quantized data
      cursor = op.quantized_data.val
      for val in ops_to_fold:
          cursor = merge_tensorwise_affine_dequantize_with_consecutive_ops._apply_equivalent_transform(
              cursor, val
          )
  
      # after transformation, we create a new constexpr_affine_dequantize op and do the replacement
      new_var = mb.constexpr_affine_dequantize(
          quantized_data=cursor,
          zero_point=op.zero_point,
          scale=op.scale,
          axis=op.axis,
          name=ops_to_fold[-1].outputs[0].name,
          before_op=ops_to_fold[-1],
      )
      block.replace_uses_of_var_after_op(
          anchor_op=ops_to_fold[-1],
          old_var=ops_to_fold[-1].outputs[0],
          new_var=new_var,
          force_replace=True,
      )
      block.remove_ops([op] + ops_to_fold)
      return True
  
imports: from typing import Tuple
  import numpy
  import coremltools.converters.mil.mil.types
  from coremltools.converters.mil._deployment_compatibility import AvailableTarget
  from coremltools.converters.mil.mil import Block
  from coremltools.converters.mil.mil import Builder
  from coremltools.converters.mil.mil import Operation, Var
  from coremltools.converters.mil.mil.passes.graph_pass import AbstractGraphPass
  from coremltools.converters.mil.mil.passes.helper import _check_child_op_type, _check_no_output_connection, block_context_manager
  from coremltools.converters.mil.mil.passes.pass_registry import register_pass
label_desc: Use image node_id 4 for calling the merge_tensorwise_affine_dequantize_with_consecutive_ops obj's underlying member method code with example usage: obj._try_to_transform(op, block) and returns: True, False, False, False