class_docstr: When a ``dequantize`` is followed by an identical ``quantize`` (same scale,
  zero point, axis), they cancel out and can be eliminated
  
  .. code-block::
  
      Input graph:
          input -> dequantize -> quantize -> output
  
      Output graph:
          input -> output
  
  PS: On the other hand, the reversed pattern, i.e., ``quantize -> dequantize``,
  is not redundant, since that is the pattern which naturally occurs when a
  quantized op is converted.
  In current activation quantization conversion, a quantized op becomes
  
  .. code-block::
  
      dequantize -> regular op -> quantize
  
  so if we have a sequence of quantized ops, we will get
  
  .. code-block::
  
      dequantize -> regular op1 -> quantize -> dequantize -> regular op2 -> quantize
  
  The ``quantize -> dequantize`` pair in the middle is not redundant, even if
  they have identical scales and zero points and axes, since removing them will lead to
  loss of information about the quantization parameters of the output var of op1
class_docstr_tok: ["When","a","``","dequantize","``","is","followed","by","an","identical","``","quantize","``","(","same","scale",",","zero","point",",","axis",")",",","they","cancel","out","and","can","be","eliminated","..","code-block",":",":","Input","graph",":","input","-",">","dequantize","-",">","quantize","-",">","output","Output","graph",":","input","-",">","output","PS",":","On","the","other","hand",",","the","reversed","pattern",",","i.e.",",","``","quantize","-",">","dequantize","``",",","is","not","redundant",",","since","that","is","the","pattern","which","naturally","occurs","when","a","quantized","op","is","converted",".","In","current","activation","quantization","conversion",",","a","quantized","op","becomes","..","code-block",":",":","dequantize","-",">","regular","op","-",">","quantize","so","if","we","have","a","sequence","of","quantized","ops",",","we","will","get","..","code-block",":",":","dequantize","-",">","regular","op1","-",">","quantize","-",">","dequantize","-",">","regular","op2","-",">","quantize","The","``","quantize","-",">","dequantize","``","pair","in","the","middle","is","not","redundant",",","even","if","they","have","identical","scales","and","zero","points","and","axes",",","since","removing","them","will","lead","to","loss","of","information","about","the","quantization","parameters","of","the","output","var","of","op1"]
code: def _dequantize_quantize_pair_elimination_block(self, block):
      def apply_block(block: Block) -> bool:
          for op in list(block.operations):
              for b in op.blocks:
                  self._dequantize_quantize_pair_elimination_block(b)
  
              # has to break as the downstream iterator is affected
              if self.try_dequantize_quantize_pair_elimination(op):
                  return True
  
          return False
  
      need_transformation = True
      while need_transformation:
          need_transformation = apply_block(block)
  
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 2 for calling the dequantize_quantize_pair_elimination obj's underlying member method code with example usage: obj._dequantize_quantize_pair_elimination_block(block) and returns: False, True