class_docstr: This observer is used to record additional information regarding keeping track
  of S = average_batch_activation_range/epoch_activation_range.
  
  The purpose of this information is to prepare a report to present to users on whether
  Dynamic or Static Quantization is more appropriate for their model given the general
  distributions of their data.
  
  Args:
      ch_axis (int, optional): The channel axis for which the range and outlier stats are computed
          Default: 1
      comp_percentile (float, optional): The percentile to compare against 100 percentile to find outliers
          Should be between 0 and 1 exclusive
          Default: 0.9
  
  * :attr:`num_batches_tracked` specifies number of batches passed through the observer
  
  * :attr:`average_batch_activation_range` defines average across the ranges of each batch passed through
  
  * :attr:`epoch_activation_min` defines the minimum value passed through the observer
  
  * :attr:`epoch_activation_max` defines the maximum value passed through the observer
  
  * :attr:`ch_axis` defines the channel being used to compute per channel min max stats
  
  * :attr:`min_val` defines the per channel minimum values passed through
  
  * :attr:`max_val` defines the per channel maximum values passed through
  
  * :attr:`comp_percentile` defines comparison percentile to find outliers
  
  * :attr:`average_percentile_ratio` defines the per channel average percentile ratios
  
  * :attr:`percentile_batches_tracked` defines the number of percentile batches tracked for each channel
  
  * :attr:`constant_channels` defines the number of batches that aren't constant channels per channel
  
  Note: this tool is meant for FX Graph Mode Quantization
docstr: Calculates and stores the per_channel min, max stats with forward values.
  Does calculation based on channel axis: self.ch_axis
  
  Args
      x_copy: A copy of the forward data
  
  Returns the passed in x_copy
code: def _calculate_min_max_stats(self, x_copy):
      r"""Calculates and stores the per_channel min, max stats with forward values.
      Does calculation based on channel axis: self.ch_axis
  
      Args
          x_copy: A copy of the forward data
  
      Returns the passed in x_copy
      """
      # get the current min and max vals
      min_val = self.min_val
      max_val = self.max_val
      x_dim = x_copy.size()
  
      new_axis_list = [i for i in range(len(x_dim))]  # noqa: C416
      new_axis_list[self.ch_axis] = 0
      new_axis_list[0] = self.ch_axis
      y = x_copy.permute(new_axis_list)
      # Need to match dtype of min/max because the updates to buffers
      # are done in place and types need to match for comparisons
      y = y.to(self.min_val.dtype)
      y = torch.flatten(y, start_dim=1)
      if min_val.numel() == 0 or max_val.numel() == 0:
          min_val, max_val = torch.aminmax(y, dim=1)
      else:
          min_val_cur, max_val_cur = torch.aminmax(y, dim=1)
          min_val = torch.min(min_val_cur, min_val)
          max_val = torch.max(max_val_cur, max_val)
  
      self.min_val.resize_(min_val.shape)
      self.max_val.resize_(max_val.shape)
      self.min_val.copy_(min_val)
      self.max_val.copy_(max_val)
  
      return x_copy
  
file_path: pytorch/torch/ao/quantization/fx/_model_report/model_report_observer.py
imports: import torch
  from torch.ao.quantization.observer import ObserverBase
label_desc: Use image node_id 4 for calling the ModelReportObserver obj's underlying member method code with example usage: obj._calculate_min_max_stats(x_copy) and returns: x_copy