code: def select_modules_by_config(
      model: torch.nn.Module, config: Dict[str, Any]
  ) -> Tuple[
      Dict[str, torch.nn.Module], Dict[str, Any], List[Tuple[str]]
  ]:
      """
      This is a helper function for selecting the modules in model specified in config.
  
      There are six optional keys in config to specify the module,
      note that the module name should be the same as the name obtained from ``model.named_modules()``,
      module type is the ``__name__`` of the module class:
          - ``op_names``: a module name list, the modules with these names will be selected.
          - ``op_types``: a module type name list, the modules satisfied these types will be selected.
          - ``op_names_re``: a regular expression list, the modules satisfied the regular expressions will be selected.
          - ``exclude_op_names``: a module name list, the modules with these names will be excluded.
          - ``exclude_op_types``: a module type name list, the modules satisfied these types will be excluded.
          - ``exclude_op_names_re``: a regular expression list, the modules satisfied the regular expressions will be excluded.
          - ``fuse_names``: a List contains tuples of fusion module names in the model.
  
      A module is selected if it satisfies all the following conditions:
          1. If ``op_names`` or ``op_names_re`` is not empty, the module name should in ``op_names``
             or satisfied one of regular expressions in ``op_names_re``.
          2. If ``op_types`` is not empty, the module type name should in ``op_types``.
          3. If ``exclude_op_names`` or ``exclude_op_names_re`` is not empty, the module name should not in ``exclude_op_names``
             and should not satisfied each of regular expressions in ``exclude_op_names_re``.
          4. If ``exclude_op_types`` is not empty, the module type name should not in ``exclude_op_types``.
  
      Parameters
      ----------
      model
          The modules selected from.
      config
          A dict contains keys ['op_names', 'op_types', 'op_names_re', 'exclude_op_names', 'exclude_op_types', 'exclude_op_names_re']
  
      Returns
      -------
      Tuple[Dict[str, torch.nn.Module], Dict[str, Any]]
          (named_module_dict, public_config).
          Named module dict is {module_name: selected_module}
          Public config is the passed-in config without keys:
          ['op_names', 'op_types', 'op_names_re', 'exclude_op_names', 'exclude_op_types', 'exclude_op_names_re', 'fuse_names'].
      """
      # intersection(union(op_names, op_names_re), op_types) - exclude_op_names - exclude_op_names_re - exclude_op_types
      name2module = {}
      type2names = defaultdict(set)
      for module_name, module in model.named_modules(
          remove_duplicate=False
      ):
          name2module[module_name] = module
          type2names[type(module).__name__].add(module_name)
  
      config = deepcopy(config)
      op_names = config.pop("op_names", None)
      op_types = config.pop("op_types", None)
      op_names_re = config.pop("op_names_re", None)
      exclude_op_names = config.pop("exclude_op_names", list())
      exclude_op_types = config.pop("exclude_op_types", list())
      exclude_op_names_re = config.pop("exclude_op_names_re", list())
      fuse_names = config.pop("fuse_names", list())
  
      selected_op_names = set(op_names) if op_names else set()
  
      for op_name_re in op_names_re if op_names_re else []:
          for op_name in name2module:
              if re.match(op_name_re, op_name):
                  selected_op_names.add(op_name)
  
      if op_types:
          selected_by_op_types = set()
          for op_type in op_types:
              selected_by_op_types.update(
                  type2names.get(op_type, set())
              )
          if op_names or op_names_re:
              selected_op_names.intersection_update(
                  selected_by_op_types
              )
          else:
              selected_op_names.update(selected_by_op_types)
  
      selected_op_names.difference_update(exclude_op_names)
  
      for op_name_re in exclude_op_names_re:
          for op_name in name2module:
              if (
                  re.match(op_name_re, op_name)
                  and op_name in selected_op_names
              ):
                  selected_op_names.remove(op_name)
  
      for op_type in exclude_op_types:
          selected_op_names.difference_update(
              type2names.get(op_type, set())
          )
  
      return (
          {
              module_name: name2module[module_name]
              for module_name in selected_op_names
          },
          config,
          fuse_names,
      )
  
file_path: nni/nni/compression/base/config.py
imports: from __future__ import annotations
  from collections import defaultdict
  from copy import deepcopy
  import re
  from typing import Any, Dict, List, Literal, Tuple
  from schema import Schema, Optional, Or
  import torch
  from .setting import INPUT_PREFIX, OUTPUT_PREFIX
label_desc: Use image node_id 2 for calling a global function with example usage: select_modules_by_config(model, config) and returns: unknown,  config,  fuse_names