class_docstr: Base class for Post-Training Quantization transforms.
  
  Derived class needs to implement following two methods:
      - is_valid_op(op)
      - transform_op(op)
class_docstr_tok: ["Base","class","for","Post-Training","Quantization","transforms",".","Derived","class","needs","to","implement","following","two","methods",":","-","is_valid_op","(","op",")","-","transform_op","(","op",")"]
docstr: Walks over each operation in the graph and performs following two steps,
  1. Checks whether an operation is valid for that quantized transform using `is_valid_op` method.
  2. If yes, calls `transform_op` method of the derived quantized transform class.
  
  :param prog: MIL program
  :return: Transformed MIL program
docstr_tok: ["Walks","over","each","operation","in","the","graph","and","performs","following","two","steps",",","1",".","Checks","whether","an","operation","is","valid","for","that","quantized","transform","using","`","is_valid_op","`","method",".","2",".","If","yes",",","calls","`","transform_op","`","method","of","the","derived","quantized","transform","class",".",":","param","prog",":","MIL","program",":","return",":","Transformed","MIL","program"]
code: def apply(self, prog):
      """
      Walks over each operation in the graph and performs following two steps,
      1. Checks whether an operation is valid for that quantized transform using `is_valid_op` method.
      2. If yes, calls `transform_op` method of the derived quantized transform class.
  
      :param prog: MIL program
      :return: Transformed MIL program
      """
      if not isinstance(prog, Program):
          raise TypeError(
              'Transform "{}" can only be applied on PyMIL programs.'.format(
                  self
              )
          )
  
      if (
          getattr(self, "skip_ops_by_type", set())
          and self.op_selector is not None
      ):
          raise ValueError(
              "The graph pass option `skip_ops_by_type` cannot be set along with "
              "the `op_selector` in FP16ComputePrecision. Please only use one "
              "method to control which ops to operate on."
          )
  
      @block_context_manager
      def apply_block(block):
          for op in list(block.operations):
              for b in op.blocks:
                  apply_block(b)
  
              if self.is_valid_op(op):
                  need_transform: bool
                  if self.op_selector is not None:
                      need_transform = self.op_selector(op)
                  else:
                      need_transform = op.op_type not in getattr(
                          self, "skip_ops_by_type", set()
                      )
                  if need_transform:
                      self.transform_op(op)
  
      for f in prog.functions.values():
          apply_block(f)
  
imports: from abc import abstractmethod
  from enum import Enum
  from typing import Set, Text
  import numpy
  from coremltools.converters.mil._deployment_compatibility import AvailableTarget
  from coremltools.converters.mil.mil import Builder
  from coremltools.converters.mil.mil import Operation, types
  from coremltools.converters.mil.mil.block import is_current_opset_version_compatible_with
  from coremltools.converters.mil.mil.ops.registry import SSAOpRegistry
  from coremltools.converters.mil.mil.passes.graph_pass import AbstractGraphPass
  from coremltools.converters.mil.mil.passes.helper import block_context_manager
  from coremltools.converters.mil.mil.passes.pass_registry import register_pass
  from coremltools.converters.mil.mil.program import Program
  from coremltools.converters.mil.mil.types.symbolic import is_symbolic
label_desc: Use image node_id 2 for calling the AbstractQuantizationPass obj's underlying member method code with example usage: obj.apply(prog) without return types