parameters: (quantization_configs, is_weights, config, opt_conf=None)
return_statement: return final_configs
docstring: Appends estimator configs to quantization configs of given operation
      :param quantization_configs: quantization configs of given operation read from hardware config
      :param is_weights: true if configuration is done for weights node
      :param config: the algorithm config
      :param opt_conf: optimal configuration from previous optimization runs
      :return: list of quantization configs with range estimator configs for given operation
               (based on hardware config and tuning scope)
docstring_summary: Appends estimator configs to quantization configs of given operation
      :param quantization_configs: quantization configs of given operation read from hardware config
      :param is_weights: true if configuration is done for weights node
      :param config: the algorithm config
      :param opt_conf: optimal configuration from previous optimization runs
      :return: list of quantization configs with range estimator configs for given operation
               (based on hardware config and tuning scope)
docstring_tokens: Appends estimator configs to quantization configs of given operation : param quantization_configs : quantization configs of given operation read from hardware config : param is_weights : true if configuration is done for weights node : param config : the algorithm config : param opt_conf : optimal configuration from previous optimization runs : return : list of quantization configs with range estimator configs for given operation ( based on hardware config and tuning scope )
function: def append_estimator_configs(quantization_configs, is_weights, config, opt_conf=None):
      """ Appends estimator configs to quantization configs of given operation
      :param quantization_configs: quantization configs of given operation read from hardware config
      :param is_weights: true if configuration is done for weights node
      :param config: the algorithm config
      :param opt_conf: optimal configuration from previous optimization runs
      :return: list of quantization configs with range estimator configs for given operation
               (based on hardware config and tuning scope)
      """
  
      def _generate_configs(base_estimator_config, param_name, values):
          """
          Generator function that derives new estimator configs from base one
          with specified values of a specific param
          :param base_estimator_config: base estimator config
          :param param_name: name of the parameter with new values
          :param values: new values for parameter
          :return: derived estimator configs one by one
          """
          for value in values:
              derived_estimator_config = deepcopy(base_estimator_config)
              derived_estimator_config[param_name] = value
              yield derived_estimator_config
  
      def _generate_type_values(key, _base_estimator_config):
          """
          Values generator function for type parameter
          :param key: estimated value name
          :param _base_estimator_config: base estimator config
          :return: list of values for type parameter
          """
          stats_functions = {
              'min': ['min', 'quantile'],
              'max': ['max', 'abs_max', 'quantile', 'abs_quantile']
          }
          return stats_functions[key]
  
      def _generate_outlier_prob_values(_key, base_estimator_config):
          """
          Values generator function for outlier_prob parameter
          :param _key: estimated value name
          :param base_estimator_config: base estimator config
          :return: list of values for outlier_prob parameter
          """
          if base_estimator_config['type'] in ['quantile', 'abs_quantile']:
              outlier_prob_values = config.outlier_prob_choices
          else:
              outlier_prob_values = [base_estimator_config['outlier_prob']]
          return outlier_prob_values
  
      def _extend_options(available_config_options, param_name, values, values_generator=None):
          """
          Extends available_config_options with new config options derived from existing ones, but with new values
          (optionally generated by values_generator function) of specified param_name.
          :param available_config_options: dict with estimated value name as key and list of available estimator
          config options as values
          :param param_name: name of config parameter to be extended with new values
          :param values: list of values for config parameter
          :param values_generator: optional function that generates new values depending on already available options
          :return: available_config_options extended with new options
          """
          new_available_config_options = {}
          for key, options in available_config_options.items():
              new_options = []
              for option in options:
                  if values_generator:
                      values = values_generator(key, option)
                  new_options.extend(list(_generate_configs(option, param_name, values)))
              new_available_config_options[key] = new_options
          return new_available_config_options
  
      def _merge_configs(available_config_options):
          """
          Merges available config options for min and max into complete estimator configs
          :param available_config_options: available config options for min and max estimators
          :return: list of complete estimator configs as a combination of all min options with all max options
          """
          merged_configs = []
          if len(available_config_options.keys()) == 1:
              key, values = list(available_config_options.items())[0]
              for value in values:
                  merged_configs.append({key: value})
          else:
              for min_config in available_config_options['min']:
                  for max_config in available_config_options['max']:
                      merged_configs.append({'min': min_config, 'max': max_config})
          return merged_configs
  
      def _create_estimator_configs(qconfig):
          tensor_type = 'weights' if is_weights else 'activations'
          default_config = get_range_estimator_config(config, tensor_type, qconfig['granularity'],
                                                      qconfig['mode'])
          if opt_conf is not None and tensor_type in opt_conf \
                  and len(opt_conf[tensor_type]['range_estimator']) >= len(default_config):
              # Some configurations (e.g. weights symmetric quantization) do not have min and max estimator configs,
              # so we need to check opt_conf compatibility and either use default or limit the scope
              base_configs = [{key: value for key, value in opt_conf[tensor_type]['range_estimator'].items() if
                               key in default_config.keys()}]
          else:
              base_configs = [default_config]
  
          if 'estimator_preset' in config.tuning_scope:
              base_configs.extend([get_range_estimator_config(config, tensor_type, qconfig['granularity'],
                                                              qconfig['mode'], preset)
                                   for preset in ['default', 'quantile']])
  
          estimator_configs = []
          for base_config in base_configs:
              for value in base_config.values():
                  if 'outlier_prob' not in value:
                      # Add default outlier_prob value to be used later if type is changed to quantile,
                      # but outlier_prob is not in tuning_scope
                      value['outlier_prob'] = 1e-4
              if base_config in estimator_configs:
                  # If base_config is already in estimator_configs then below code will generate subset of options
                  # already in estimator_configs
                  continue
              available_config_options = {key: [value] for key, value in base_config.items()}
              if 'estimator_type' in config.tuning_scope:
                  available_config_options = _extend_options(available_config_options, 'type', [None],
                                                             _generate_type_values)
              # outlier_prob config extension requires new types to be already added to config options
              if 'estimator_outlier_prob' in config.tuning_scope:
                  available_config_options = _extend_options(available_config_options, 'outlier_prob', [None],
                                                             _generate_outlier_prob_values)
              if 'estimator_aggregator' in config.tuning_scope and not is_weights:
                  available_config_options = _extend_options(available_config_options, 'aggregator',
                                                             list(AGGREGATION_FN.registry_dict.keys()))
              estimator_configs.extend(_merge_configs(available_config_options))
  
          return estimator_configs
  
      final_configs = []
      for quantization_config in quantization_configs:
          for estimator_config in _create_estimator_configs(quantization_config):
              final_configs.append({**quantization_config, 'range_estimator': estimator_config})
      return final_configs
function_tokens: def append_estimator_configs ( quantization_configs , is_weights , config , opt_conf = None ) : def _generate_configs ( base_estimator_config , param_name , values ) : """
          Generator function that derives new estimator configs from base one
          with specified values of a specific param
          :param base_estimator_config: base estimator config
          :param param_name: name of the parameter with new values
          :param values: new values for parameter
          :return: derived estimator configs one by one
          """ for value in values : derived_estimator_config = deepcopy ( base_estimator_config ) derived_estimator_config [ param_name ] = value yield derived_estimator_config def _generate_type_values ( key , _base_estimator_config ) : """
          Values generator function for type parameter
          :param key: estimated value name
          :param _base_estimator_config: base estimator config
          :return: list of values for type parameter
          """ stats_functions = { 'min' : [ 'min' , 'quantile' ] , 'max' : [ 'max' , 'abs_max' , 'quantile' , 'abs_quantile' ] } return stats_functions [ key ] def _generate_outlier_prob_values ( _key , base_estimator_config ) : """
          Values generator function for outlier_prob parameter
          :param _key: estimated value name
          :param base_estimator_config: base estimator config
          :return: list of values for outlier_prob parameter
          """ if base_estimator_config [ 'type' ] in [ 'quantile' , 'abs_quantile' ] : outlier_prob_values = config . outlier_prob_choices else : outlier_prob_values = [ base_estimator_config [ 'outlier_prob' ] ] return outlier_prob_values def _extend_options ( available_config_options , param_name , values , values_generator = None ) : """
          Extends available_config_options with new config options derived from existing ones, but with new values
          (optionally generated by values_generator function) of specified param_name.
          :param available_config_options: dict with estimated value name as key and list of available estimator
          config options as values
          :param param_name: name of config parameter to be extended with new values
          :param values: list of values for config parameter
          :param values_generator: optional function that generates new values depending on already available options
          :return: available_config_options extended with new options
          """ new_available_config_options = { } for key , options in available_config_options . items ( ) : new_options = [ ] for option in options : if values_generator : values = values_generator ( key , option ) new_options . extend ( list ( _generate_configs ( option , param_name , values ) ) ) new_available_config_options [ key ] = new_options return new_available_config_options def _merge_configs ( available_config_options ) : """
          Merges available config options for min and max into complete estimator configs
          :param available_config_options: available config options for min and max estimators
          :return: list of complete estimator configs as a combination of all min options with all max options
          """ merged_configs = [ ] if len ( available_config_options . keys ( ) ) == 1 : key , values = list ( available_config_options . items ( ) ) [ 0 ] for value in values : merged_configs . append ( { key : value } ) else : for min_config in available_config_options [ 'min' ] : for max_config in available_config_options [ 'max' ] : merged_configs . append ( { 'min' : min_config , 'max' : max_config } ) return merged_configs def _create_estimator_configs ( qconfig ) : tensor_type = 'weights' if is_weights else 'activations' default_config = get_range_estimator_config ( config , tensor_type , qconfig [ 'granularity' ] , qconfig [ 'mode' ] ) if opt_conf is not None and tensor_type in opt_conf and len ( opt_conf [ tensor_type ] [ 'range_estimator' ] ) >= len ( default_config ) : # Some configurations (e.g. weights symmetric quantization) do not have min and max estimator configs, # so we need to check opt_conf compatibility and either use default or limit the scope base_configs = [ { key : value for key , value in opt_conf [ tensor_type ] [ 'range_estimator' ] . items ( ) if key in default_config . keys ( ) } ] else : base_configs = [ default_config ] if 'estimator_preset' in config . tuning_scope : base_configs . extend ( [ get_range_estimator_config ( config , tensor_type , qconfig [ 'granularity' ] , qconfig [ 'mode' ] , preset ) for preset in [ 'default' , 'quantile' ] ] ) estimator_configs = [ ] for base_config in base_configs : for value in base_config . values ( ) : if 'outlier_prob' not in value : # Add default outlier_prob value to be used later if type is changed to quantile, # but outlier_prob is not in tuning_scope value [ 'outlier_prob' ] = 1e-4 if base_config in estimator_configs : # If base_config is already in estimator_configs then below code will generate subset of options # already in estimator_configs continue available_config_options = { key : [ value ] for key , value in base_config . items ( ) } if 'estimator_type' in config . tuning_scope : available_config_options = _extend_options ( available_config_options , 'type' , [ None ] , _generate_type_values ) # outlier_prob config extension requires new types to be already added to config options if 'estimator_outlier_prob' in config . tuning_scope : available_config_options = _extend_options ( available_config_options , 'outlier_prob' , [ None ] , _generate_outlier_prob_values ) if 'estimator_aggregator' in config . tuning_scope and not is_weights : available_config_options = _extend_options ( available_config_options , 'aggregator' , list ( AGGREGATION_FN . registry_dict . keys ( ) ) ) estimator_configs . extend ( _merge_configs ( available_config_options ) ) return estimator_configs final_configs = [ ] for quantization_config in quantization_configs : for estimator_config in _create_estimator_configs ( quantization_config ) : final_configs . append ( { * * quantization_config , 'range_estimator' : estimator_config } ) return final_configs