class_docstr: Unified histogram calibrator
  
  Histogram will be only collected once. compute_amax() performs entropy, percentile, or mse
      calibration based on arguments
  
  Args:
      num_bits: An integer. Number of bits of quantization.
      axis: A tuple. see QuantDescriptor.
      unsigned: A boolean. using unsigned quantization.
      num_bins: An integer. Number of histograms bins. Default 2048.
      grow_method: A string. DEPRECATED. default None.
      skip_zeros: A boolean. If True, skips zeros when collecting data for histogram. Default False.
      torch_hist: A boolean. If True, collect histogram by torch.histc instead of np.histogram. If input tensor
          is on GPU, histc will also be running on GPU. Default False.
class_docstr_tok: ["Unified","histogram","calibrator","Histogram","will","be","only","collected","once",".","compute_amax","(",")","performs","entropy",",","percentile",",","or","mse","calibration","based","on","arguments","Args",":","num_bits",":","An","integer",".","Number","of","bits","of","quantization",".","axis",":","A","tuple",".","see","QuantDescriptor",".","unsigned",":","A","boolean",".","using","unsigned","quantization",".","num_bins",":","An","integer",".","Number","of","histograms","bins",".","Default","2048.","grow_method",":","A","string",".","DEPRECATED",".","default","None",".","skip_zeros",":","A","boolean",".","If","True",",","skips","zeros","when","collecting","data","for","histogram",".","Default","False",".","torch_hist",":","A","boolean",".","If","True",",","collect","histogram","by","torch.histc","instead","of","np.histogram",".","If","input","tensor","is","on","GPU",",","histc","will","also","be","running","on","GPU",".","Default","False","."]
docstr: Collect histogram
docstr_tok: ["Collect","histogram"]
code: def collect(self, x):
      """Collect histogram"""
      if torch.min(x) < 0.0:
          x = x.abs()
  
      x = x.float()
  
      if not self._torch_hist:
          x_np = x.cpu().detach().numpy()
  
          if self._skip_zeros:
              x_np = x_np[np.where(x_np != 0)]
  
          if self._calib_bin_edges is None and self._calib_hist is None:
              # first time it uses num_bins to compute histogram.
              self._calib_hist, self._calib_bin_edges = np.histogram(
                  x_np, bins=self._num_bins
              )
          else:
              temp_amax = np.max(x_np)
              if temp_amax > self._calib_bin_edges[-1]:
                  # increase the number of bins
                  width = (
                      self._calib_bin_edges[1]
                      - self._calib_bin_edges[0]
                  )
                  # NOTE: np.arange may create an extra bin after the one containing temp_amax
                  new_bin_edges = np.arange(
                      self._calib_bin_edges[-1] + width,
                      temp_amax + width,
                      width,
                  )
                  self._calib_bin_edges = np.hstack(
                      (self._calib_bin_edges, new_bin_edges)
                  )
              hist, self._calib_bin_edges = np.histogram(
                  x_np, bins=self._calib_bin_edges
              )
              hist[: len(self._calib_hist)] += self._calib_hist
              self._calib_hist = hist
      else:
          # This branch of code is designed to match numpy version as close as possible
          with torch.no_grad():
              if self._skip_zeros:
                  x = x[torch.where(x != 0)]
  
              # Because we collect histogram on absolute value, setting min=0 simplifying the rare case where
              # minimum value is not exactly 0 and first batch collected has larger min value than later batches
              x_max = x.max()
              if (
                  self._calib_bin_edges is None
                  and self._calib_hist is None
              ):
                  self._calib_hist = torch.histc(
                      x, bins=self._num_bins, min=0, max=x_max
                  )
                  self._calib_bin_edges = torch.linspace(
                      0, x_max, self._num_bins + 1
                  )
              else:
                  if x_max > self._calib_bin_edges[-1]:
                      width = (
                          self._calib_bin_edges[1]
                          - self._calib_bin_edges[0]
                      )
                      self._num_bins = int(
                          (x_max / width).ceil().item()
                      )
                      self._calib_bin_edges = torch.arange(
                          0, x_max + width, width, device=x.device
                      )
  
                  hist = torch.histc(
                      x,
                      bins=self._num_bins,
                      min=0,
                      max=self._calib_bin_edges[-1],
                  )
                  hist[: self._calib_hist.numel()] += self._calib_hist
                  self._calib_hist = hist
  
imports: from collections import Counter
  import numpy
  from scipy.stats import entropy
  import logging
  import torch
  from lightseq.training.pytorch_quantization.calib.calibrator import _Calibrator
  from lightseq.training.pytorch_quantization.tensor_quant import fake_tensor_quant
  from lightseq.training.pytorch_quantization import nn
  from lightseq.training.pytorch_quantization import utils
label_desc: Use image node_id 2 for calling the HistogramCalibrator obj's underlying member method code with example usage: obj.collect(x) without return types