class_docstr: Determines whether input-weight equalization can help improve quantization for certain modules.
  
  Specifically, this list of modules includes:
      linear
      conv
  
  Determines whether input-weight equalization is recommended based on the comp stat:
      s_c = sqrt(w_c/W)/sqrt(i_c/I)
      where:
          w_c is range of weight for channel c, W is range of weight over all channels
          i_c is range of input for channel c, I is range of input over all channels
  
      if s_c >= threshold or <= 1 / threshold, recommends input-weight equalization
  
  Args:
      ratio_threshold (float): The threshold for s_c to determine if input-weight equalization is suggested
          Should be between 0 and 1 (both non-inclusive)
      ch_axis (int, optional): The channel axis being observed to determine input weight equalization
          Default: 1
  
  * :attr:`ratio_threshold`: The threshold for s_c to determine if input-weight equalization is suggested
      Should be between 0 and 1
  
  * :attr:`ch_axis`: The channel axis being observed to determine input weight equalization
  
  * :attr:`SUPPORTED_MODULES`: This specifies the modules that are supported for input-weight equalization
  
  * :attr:`DEFAULT_PRE_OBSERVER_NAME`: The name of the pre-observer to be inserted for this detector
class_docstr_tok: ["Determines","whether","input-weight","equalization","can","help","improve","quantization","for","certain","modules",".","Specifically",",","this","list","of","modules","includes",":","linear","conv","Determines","whether","input-weight","equalization","is","recommended","based","on","the","comp","stat",":","s_c","=","sqrt","(","w_c\/W",")","\/sqrt","(","i_c\/I",")","where",":","w_c","is","range","of","weight","for","channel","c",",","W","is","range","of","weight","over","all","channels","i_c","is","range","of","input","for","channel","c",",","I","is","range","of","input","over","all","channels","if","s_c",">","=","threshold","or","<","=","1","\/","threshold",",","recommends","input-weight","equalization","Args",":","ratio_threshold","(","float",")",":","The","threshold","for","s_c","to","determine","if","input-weight","equalization","is","suggested","Should","be","between","0","and","1","(","both","non-inclusive",")","ch_axis","(","int",",","optional",")",":","The","channel","axis","being","observed","to","determine","input","weight","equalization","Default",":","1","*",":","attr",":","`","ratio_threshold","`",":","The","threshold","for","s_c","to","determine","if","input-weight","equalization","is","suggested","Should","be","between","0","and","1","*",":","attr",":","`","ch_axis","`",":","The","channel","axis","being","observed","to","determine","input","weight","equalization","*",":","attr",":","`","SUPPORTED_MODULES","`",":","This","specifies","the","modules","that","are","supported","for","input-weight","equalization","*",":","attr",":","`","DEFAULT_PRE_OBSERVER_NAME","`",":","The","name","of","the","pre-observer","to","be","inserted","for","this","detector"]
docstr: Determines whether input weight equalization is appropriate for a given module.
  
  Takes advantage of the ModelReport Observer which records per channel information of input range
  It then uses the passed in weight info inconjunction to compute the desired ratio
  Finally, it gives suggestions based on this information for each module of interest
  
  Args:
      model (GraphModule): The prepared and calibrated GraphModule with inserted ModelReportObservers
  
  Returns a tuple with two elements:
      String report of of whether input weight equalization is recommended for certain modules
      Dictionary mapping modules of interest to:
          whether input weight equalization is recommended
          their s_c metric compared to the threshold
          the threshold used to make the recommendation
          the channel used for recording data
          the input channel range info
          the weight channel range info
docstr_tok: ["Determines","whether","input","weight","equalization","is","appropriate","for","a","given","module",".","Takes","advantage","of","the","ModelReport","Observer","which","records","per","channel","information","of","input","range","It","then","uses","the","passed","in","weight","info","inconjunction","to","compute","the","desired","ratio","Finally",",","it","gives","suggestions","based","on","this","information","for","each","module","of","interest","Args",":","model","(","GraphModule",")",":","The","prepared","and","calibrated","GraphModule","with","inserted","ModelReportObservers","Returns","a","tuple","with","two","elements",":","String","report","of","of","whether","input","weight","equalization","is","recommended","for","certain","modules","Dictionary","mapping","modules","of","interest","to",":","whether","input","weight","equalization","is","recommended","their","s_c","metric","compared","to","the","threshold","the","threshold","used","to","make","the","recommendation","the","channel","used","for","recording","data","the","input","channel","range","info","the","weight","channel","range","info"]
code: def generate_detector_report(
      self, model: GraphModule
  ) -> Tuple[str, Dict[str, Any]]:
      r"""
      Determines whether input weight equalization is appropriate for a given module.
  
      Takes advantage of the ModelReport Observer which records per channel information of input range
      It then uses the passed in weight info inconjunction to compute the desired ratio
      Finally, it gives suggestions based on this information for each module of interest
  
      Args:
          model (GraphModule): The prepared and calibrated GraphModule with inserted ModelReportObservers
  
      Returns a tuple with two elements:
          String report of of whether input weight equalization is recommended for certain modules
          Dictionary mapping modules of interest to:
              whether input weight equalization is recommended
              their s_c metric compared to the threshold
              the threshold used to make the recommendation
              the channel used for recording data
              the input channel range info
              the weight channel range info
      """
  
      # find the range of inputs
      input_values: Dict[str, Dict] = self._extract_input_info(model)
  
      # find the range of weights
      weight_values: Dict[str, Dict] = self._extract_weight_info(model)
  
      # calculate per_channel comparison statistic s_c
      comp_stats: Dict[
          str, torch.Tensor
      ] = self._generate_comparison_values(input_values, weight_values)
  
      # generate the return dictionary
      input_weight_equalization_info: Dict[
          str, Dict
      ] = self._generate_dict_info(
          input_values, weight_values, comp_stats
      )
  
      # now we can generate report based on this information
      input_weight_string = "Input-Weight Equalization suggestions: \n"
  
      # some strings to be formatted depending on module we are adding
      module_suggestion_str = "For Module {} looked at with axis {}: \n"
      channel_suggestion_str = (
          "\tWe suggest {} input weight equalization because {}\n"
      )
      use_str = "to use"
      no_use_str = "to not use"
      input_weight_benefit_str = "{}/{} channels would benefit and we expect significant reduction in quantization error."
      input_weight_non_benefit_reasoning = "{}/{} channels benefitting from input-weight equalization being applied."
      input_weight_non_benefit_str = "we don't expect much improvement from input-weight equalization based on {}"
  
      # added module check
      added_module: bool = False
  
      # compile the suggestion string
      for module_fqn in input_weight_equalization_info:
          # we added at least 1 module
          added_module = True
          # add the module level description
          input_weight_string += module_suggestion_str.format(
              module_fqn, self.ch_axis
          )
  
          mod_info: Dict[str, Any] = input_weight_equalization_info[
              module_fqn
          ]
  
          # gather info on how many channels would benefit from input weight and
          recommendation_per_channel: torch.Tensor = mod_info[
              self.RECOMMENDED_KEY
          ]
          num_recs = sum(recommendation_per_channel)
  
          if (
              num_recs / len(recommendation_per_channel)
              >= self.DEFAULT_RECOMMEND_INPUT_WEIGHT_CHANNEL_RATIO
          ):
              input_benefit_formatted = input_weight_benefit_str.format(
                  num_recs, len(recommendation_per_channel)
              )
              channel_str = channel_suggestion_str.format(
                  use_str, input_benefit_formatted
              )
              input_weight_string += channel_str
          else:
              non_benefit_reason_formatted = (
                  input_weight_non_benefit_reasoning.format(
                      num_recs, len(recommendation_per_channel)
                  )
              )
              non_benefit_str = input_weight_non_benefit_str.format(
                  non_benefit_reason_formatted
              )
              channel_str = channel_suggestion_str.format(
                  no_use_str, non_benefit_str
              )
              input_weight_string += channel_str
  
      # if no modules looked at, amend return string
      if not added_module:
          input_weight_string += "No applicable layers for suggestions. Only linear and conv valid.\n"
  
      # return a tuple with the string explanation and the compiled dict info
      return (input_weight_string, input_weight_equalization_info)
  
imports: from typing import Any, Dict, Set, Tuple, Callable, List
  import torch
  import torch.nn
  import torch.ao.nn.qat
  from abc import ABC, abstractmethod
  from torch.ao.quantization.fake_quantize import FakeQuantize
  from torch.ao.quantization.fx.graph_module import GraphModule
  from torch.ao.quantization.fx._model_report.model_report_observer import ModelReportObserver
  from torch.ao.quantization.qconfig import QConfig, default_qconfig, _assert_valid_qconfig
  from torch.ao.quantization.observer import ObserverBase, default_dynamic_quant_observer, default_per_channel_weight_observer, default_observer, default_weight_observer
  from torch.ao.quantization.fx._equalize import default_equalization_qconfig, EqualizationQConfig
  from torch.ao.quantization.observer import _is_activation_post_process
label_desc: Use image node_id 11 for calling the InputWeightEqualizationDetector obj's underlying member method code with example usage: obj.generate_detector_report(model) and returns: input_weight_string,  input_weight_equalization_info