class_docstr: A structured pruning masker base class that prunes convolutional layer filters.
  
  Parameters
  ----------
  model: nn.Module
      model to be pruned
  pruner: Pruner
      A Pruner instance used to prune the model
  preserve_round: int
      after pruning, preserve filters/channels round to `preserve_round`, for example:
      for a Conv2d layer, output channel is 32, sparsity is 0.2, if preserve_round is
      1 (no preserve round), then there will be int(32 * 0.2) = 6 filters pruned, and
      32 - 6 = 26 filters are preserved. If preserve_round is 4, preserved filters will
      be round up to 28 (which can be divided by 4) and only 4 filters are pruned.
class_docstr_tok: ["A","structured","pruning","masker","base","class","that","prunes","convolutional","layer","filters",".","Parameters","--","--","--","--","--","model",":","nn.Module","model","to","be","pruned","pruner",":","Pruner","A","Pruner","instance","used","to","prune","the","model","preserve_round",":","int","after","pruning",",","preserve","filters\/channels","round","to","`","preserve_round","`",",","for","example",":","for","a","Conv2d","layer",",","output","channel","is","32",",","sparsity","is","0.2",",","if","preserve_round","is","1","(","no","preserve","round",")",",","then","there","will","be","int","(","32","*","0.2",")","=","6","filters","pruned",",","and","32","-","6","=","26","filters","are","preserved",".","If","preserve_round","is","4",",","preserved","filters","will","be","round","up","to","28","(","which","can","be","divided","by","4",")","and","only","4","filters","are","pruned","."]
docstr: Calculate the common channels should be pruned by all the layers in this group.
  This function is for filter pruning of Conv layers. if want to support the dependency-aware
  mode for others ops, you need to inherit this class and overwrite `_common_channel_to_prune`.
  
  Parameters
  ----------
  sparsities : list
      List of float that specify the sparsity for each conv layer.
  wrappers : list
      List of wrappers
  groups : list
      The number of the filter groups of each layer.
  wrappers_idx : list
      The indexes of the wrappers
docstr_tok: ["Calculate","the","common","channels","should","be","pruned","by","all","the","layers","in","this","group",".","This","function","is","for","filter","pruning","of","Conv","layers",".","if","want","to","support","the","dependency-aware","mode","for","others","ops",",","you","need","to","inherit","this","class","and","overwrite","`","_common_channel_to_prune","`",".","Parameters","--","--","--","--","--","sparsities",":","list","List","of","float","that","specify","the","sparsity","for","each","conv","layer",".","wrappers",":","list","List","of","wrappers","groups",":","list","The","number","of","the","filter","groups","of","each","layer",".","wrappers_idx",":","list","The","indexes","of","the","wrappers"]
code: def _common_channel_to_prune(
      self, sparsities, wrappers, wrappers_idx, channel_dsets, groups
  ):
      """
      Calculate the common channels should be pruned by all the layers in this group.
      This function is for filter pruning of Conv layers. if want to support the dependency-aware
      mode for others ops, you need to inherit this class and overwrite `_common_channel_to_prune`.
  
      Parameters
      ----------
      sparsities : list
          List of float that specify the sparsity for each conv layer.
      wrappers : list
          List of wrappers
      groups : list
          The number of the filter groups of each layer.
      wrappers_idx : list
          The indexes of the wrappers
      """
      # sparsity configs for each wrapper
      # sparsities = [_w.config['sparsity'] for _w in wrappers]
      # check the type of the input wrappers
      for _w in wrappers:
          msg = "module type {} is not supported!".format(_w.type)
          assert _w.type == "Conv2d", msg
      # Among the dependent layers, the layer with smallest
      # sparsity determines the final benefit of the speedup
      # module. To better harvest the speed benefit, we need
      # to ensure that these dependent layers have at least
      # `min_sparsity` pruned channel are the same.
      if len(channel_dsets) == len(wrappers):
          # all the layers in the dependency sets are pruned
          min_sparsity = min(sparsities)
      else:
          # not all the layers in the dependency set
          # are pruned
          min_sparsity = 0
      # donnot prune the channels that we cannot harvest the speed from
      sparsities = [min_sparsity] * len(sparsities)
      # find the max number of the filter groups of the dependent
      # layers. The group constraint of this dependency set is decided
      # by the layer with the max groups.
  
      # should use the least common multiple for all the groups
      # the max_group is lower than the channel_count, because
      # the number of the filter is always divisible by the number of the group
      max_group = np.lcm.reduce(groups)
      channel_count = wrappers[0].module.weight.data.size(0)
      device = wrappers[0].module.weight.device
      channel_sum = torch.zeros(channel_count).to(device)
      for _w, _w_idx in zip(wrappers, wrappers_idx):
          # calculate the L1/L2 sum for all channels
          c_sum = self.get_channel_sum(_w, _w_idx)
  
          if c_sum is None:
              # if the channel sum cannot be calculated
              # now, return None
              return None
          channel_sum += c_sum
  
      # prune the same `min_sparsity` channels based on channel_sum
      # for all the layers in the channel sparsity
      target_pruned = int(channel_count * min_sparsity)
      # pruned_per_group may be zero, for example dw conv
      pruned_per_group = int(target_pruned / max_group)
      group_step = int(channel_count / max_group)
  
      channel_masks = []
      for gid in range(max_group):
          _start = gid * group_step
          _end = (gid + 1) * group_step
          if pruned_per_group > 0:
              threshold = torch.topk(
                  channel_sum[_start:_end],
                  pruned_per_group,
                  largest=False,
              )[0].max()
              group_mask = torch.gt(channel_sum[_start:_end], threshold)
          else:
              group_mask = torch.ones(group_step).to(device)
          channel_masks.append(group_mask)
      channel_masks = torch.cat(channel_masks, dim=0)
      pruned_channel_index = (
          (channel_masks == False).nonzero().squeeze(1).tolist()
      )
      logger.info(
          "Prune the %s channels for all dependent",
          ",".join([str(x) for x in pruned_channel_index]),
      )
      return channel_masks
  
imports: import logging
  import math
  import numpy
  import torch
  from .weight_masker import WeightMasker
label_desc: Use image node_id 5 for calling the StructuredWeightMasker obj's underlying member method code with example usage: obj._common_channel_to_prune(sparsities, wrappers, wrappers_idx, channel_dsets, groups) and returns: channel_masks, None