class_docstr: ``dequantize`` op with constant input is equivalent to ``constexpr_affine_dequantize``.
  This is one of the canonicalization pass that transforms all such
  ``dequantize`` ops to respective ``constexpr_affine_dequantize`` ops.
  
  .. code-block::
  
      Input graph:
  
          dequantize(input=const) -> downstream op
  
      Output graph:
  
          constexpr_affine_dequantize -> downstream op
  
  This pass is being performed because constant tensors being propagated
  through ``dequantize`` op would be serialized in bloated/decompressed fashion,
  whereas with ``constexpr_affine_dequantize``,
  constant weights/tensors remain compressed at serialization.
class_docstr_tok: ["``","dequantize","``","op","with","constant","input","is","equivalent","to","``","constexpr_affine_dequantize","``",".","This","is","one","of","the","canonicalization","pass","that","transforms","all","such","``","dequantize","``","ops","to","respective","``","constexpr_affine_dequantize","``","ops",".","..","code-block",":",":","Input","graph",":","dequantize","(","input=const",")","-",">","downstream","op","Output","graph",":","constexpr_affine_dequantize","-",">","downstream","op","This","pass","is","being","performed","because","constant","tensors","being","propagated","through","``","dequantize","``","op","would","be","serialized","in","bloated\/decompressed","fashion",",","whereas","with","``","constexpr_affine_dequantize","``",",","constant","weights\/tensors","remain","compressed","at","serialization","."]
code: def transform_op(self, op):
      quantized_data = op.input.val
  
      scale = op.scale.val
  
      zero_point = None
      if op.zero_point is not None:
          zero_point = op.zero_point.val
      else:
          zero_point = (
              np.int8(0)
              if op.input.dtype == types.int8
              else np.uint8(0)
          )
  
      # In dequantize semantics, axis may be None:
      #     when scale is a scalar, axis is None
      #
      # In constexpr_affine_dequantize semantics, None axis is not allowed;
      # since axis is not referred to when scale is a scalar, we pass a dummy
      axis = 0
      if op.axis is not None:
          axis = op.axis.val
  
      new_var = mb.constexpr_affine_dequantize(
          quantized_data=quantized_data,
          zero_point=zero_point,
          scale=scale,
          axis=axis,
          before_op=op,
          name=op.name + "_affine_dequantized",
      )
  
      block = op.enclosing_block
      block.replace_uses_of_var_after_op(
          anchor_op=op, old_var=op.outputs[0], new_var=new_var
      )
      block.remove_ops([op])
  
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 3 for calling the dequantize_to_constexpr obj's underlying member method code with example usage: obj.transform_op(op) without return types