class_docstr: Base class for structured pruning.
  
  Abstract methods that need to be implemented:
      - update_mask: Function to compute a new mask for all keys in the
          `groups` attribute.
  
  Args:
      - defaults [dict]: default configurations will be attached to the
          configuration. Only the keys that don't exist in the `config` will
          be updated.
docstr: This function will FX symbolically trace the model and then find instances of the patterns
  defined in self.patterns (by default SUPPORTED_STRUCTURED_PRUNING_PATTERNS ).
  
  For each pattern, it will apply to corresponding conversion function, which will modify the output
  and input size expected by the modules within the pattern
docstr_tok: ["This","function","will","FX","symbolically","trace","the","model","and","then","find","instances","of","the","patterns","defined","in","self.patterns","(","by","default","SUPPORTED_STRUCTURED_PRUNING_PATTERNS",")",".","For","each","pattern",",","it","will","apply","to","corresponding","conversion","function",",","which","will","modify","the","output","and","input","size","expected","by","the","modules","within","the","pattern"]
code: def prune(self) -> None:
      r"""
      This function will FX symbolically trace the model and then find instances of the patterns
      defined in self.patterns (by default SUPPORTED_STRUCTURED_PRUNING_PATTERNS ).
  
      For each pattern, it will apply to corresponding conversion function, which will modify the output
      and input size expected by the modules within the pattern
      """
  
      self.traced = symbolic_trace(self.model)
      modules = dict(self.traced.named_modules())
  
      # Right now we check for matches simply by iterating across all the patterns
      # if this is slow we can store patterns in a trie-structure and modify this code for faster lookup
      for node in self.traced.graph.nodes:
          for pattern, convert_fn in self.patterns.items():
              matched = apply_match(modules, pattern, node, [])
              if matched is None:
                  continue
  
              first_module = modules.get(node.target)
              # check if first module exists and has appropriate parameterization, otherwise skip
              if (
                  first_module is not None
                  and parametrize.is_parametrized(first_module)
                  and module_contains_param(
                      first_module, FakeStructuredSparsity
                  )
              ):
                  convert_block = []
                  for node in matched:
                      if node.op == "call_module":
                          convert_block.append(modules.get(node.target))
                      elif node.op == "call_function":
                          convert_block.append(node.target)
                  convert_fn(*convert_block)
  
      for module in self.traced.modules():
          if module_contains_param(module, FakeStructuredSparsity):
              raise Exception(
                  f"Error: {module} still contains FakeStructuredSparsity parametrizations!"
              )
  
      self.traced.graph.lint()
      self.traced.recompile()
      return self.traced
  
imports: from itertools import chain
  from operator import getitem
  import torch
  import torch.nn.functional
  from torch import nn
  from torch.fx import symbolic_trace
  from torch.nn.utils import parametrize
  from typing import Type, Set, Dict, Callable, Tuple, Optional, Union
  from torch.ao.pruning import BaseSparsifier
  from .parametrization import FakeStructuredSparsity, BiasHook, module_contains_param
  from .match_utils import apply_match, MatchAllNode
  from .prune_functions import prune_linear, prune_linear_linear, prune_linear_activation_linear, prune_conv2d, prune_conv2d_conv2d, prune_conv2d_activation_conv2d, prune_conv2d_activation_pool_conv2d, prune_conv2d_pool_activation_conv2d, prune_conv2d_pool_flatten_linear, prune_lstm_output_linear, prune_lstm_output_layernorm_linear
label_desc: Use image node_id 4 for calling the BaseStructuredSparsifier obj's underlying member method code with example usage: obj.prune() and returns: self