class_docstr: Tensor quantizer module
  
  This module uses tensor_quant or fake_tensor_quant function to quantize a tensor. And wrappers variable, moving
  statistics we'd want when training a quantized network.
  
  Experimental features:
      ``clip`` stage learns range before enabling quantization.
      ``calib`` stage runs calibration
  
  Args:
      quant_desc: An instance of :func:`QuantDescriptor <csrc.pytorch.pytorch_quantization.tensor_quant.QuantDescriptor>`.
      disabled: A boolean. If True, by pass the whole module returns input. Default False.
      if_quant: A boolean. If True, run main quantization body. Default True.
      if_clip: A boolean. If True, clip before quantization and learn amax. Default False.
      if_calib: A boolean. If True, run calibration. Not implemented yet. Settings of calibration will probably
          go to :func:`QuantDescriptor <csrc.pytorch.pytorch_quantization.tensor_quant.QuantDescriptor>`.
  
  Raises:
  
  Readonly Properties:
      - axis:
      - fake_quant:
      - scale:
      - step_size:
  
  Mutable Properties:
      - num_bits:
      - unsigned:
      - amax:
class_docstr_tok: ["Tensor","quantizer","module","This","module","uses","tensor_quant","or","fake_tensor_quant","function","to","quantize","a","tensor",".","And","wrappers","variable",",","moving","statistics","we","'d","want","when","training","a","quantized","network",".","Experimental","features",":","``","clip","``","stage","learns","range","before","enabling","quantization",".","``","calib","``","stage","runs","calibration","Args",":","quant_desc",":","An","instance","of",":","func",":","`","QuantDescriptor","<","csrc.pytorch.pytorch_quantization.tensor_quant.QuantDescriptor",">","`",".","disabled",":","A","boolean",".","If","True",",","by","pass","the","whole","module","returns","input",".","Default","False",".","if_quant",":","A","boolean",".","If","True",",","run","main","quantization","body",".","Default","True",".","if_clip",":","A","boolean",".","If","True",",","clip","before","quantization","and","learn","amax",".","Default","False",".","if_calib",":","A","boolean",".","If","True",",","run","calibration",".","Not","implemented","yet",".","Settings","of","calibration","will","probably","go","to",":","func",":","`","QuantDescriptor","<","csrc.pytorch.pytorch_quantization.tensor_quant.QuantDescriptor",">","`",".","Raises",":","Readonly","Properties",":","-","axis",":","-","fake_quant",":","-","scale",":","-","step_size",":","Mutable","Properties",":","-","num_bits",":","-","unsigned",":","-","amax",":"]
docstr: Initialize quantizer and set up required variables
code: def __init__(
      self,
      quant_desc=QuantDescriptor(),
      disabled=True,
      if_quant=False,
      if_clip=False,
      if_calib=False,
  ):
      """Initialize quantizer and set up required variables"""
      super(TensorQuantizer, self).__init__()
      # Expand quant_desc. Use quant_desc.dict would be eaiser, but adding one-by-one explicitly gives more control
      self._num_bits = quant_desc.num_bits
      self._fake_quant = quant_desc.fake_quant
      self._axis = quant_desc.axis
      self._scale_amax = quant_desc.scale_amax
      self._learn_amax = quant_desc.learn_amax
      self._unsigned = quant_desc.unsigned
      self._narrow_range = quant_desc.narrow_range
  
      self._scale = None if not quant_desc.fake_quant else 1.0
      self._disabled = disabled
      self._if_quant = if_quant
      self._if_clip = False
      self._if_calib = if_calib
  
      if quant_desc.amax is not None:
          self.register_buffer("_amax", torch.tensor(quant_desc.amax))
  
      # Clip module consumes a lot of memory, so only create it if learn_amax is True
      if self._learn_amax:
          init_amax = (
              quant_desc.amax if quant_desc.amax is not None else 1.0
          )
          self.clip = Clip(
              -init_amax, init_amax, learn_min=True, learn_max=True
          )
          # It makes more sense to enable clip stage (which learns amax) if learn_amax is true
          self.enable_clip()
      if if_clip:
          self.enable_clip()
  
      if quant_desc.calib_method == "histogram":
          self._calibrator = calib.HistogramCalibrator(
              num_bits=self._num_bits,
              axis=self._axis,
              unsigned=self._unsigned,
          )
      elif quant_desc.calib_method == "max":
          self._calibrator = calib.MaxCalibrator(
              num_bits=self._num_bits,
              axis=self._axis,
              unsigned=self._unsigned,
          )
  
imports: import math
  import logging
  import torch
  from torch import nn
  from csrc.pytorch.pytorch_quantization.tensor_quant import QuantDescriptor, tensor_quant, fake_tensor_quant
  from csrc.pytorch.pytorch_quantization.nn.modules.clip import Clip
  from csrc.pytorch.pytorch_quantization import calib
  import csrc.pytorch.pytorch_quantization.utils
label_desc: Use image node_id 1 to create a new TensorQuantizer object from inherited base classes: nn with example: obj = TensorQuantizer(quant_desc, disabled, if_quant, if_clip, if_calib)