class_docstr: Weight-Norm Sparsifier
  
  This sparsifier computes the norm of every sparse block and "zeroes-out" the
  ones with the lowest norm. The level of sparsity defines how many of the
  blocks is removed.
  
  This sparsifier is controlled by three variables:
  1. `sparsity_level` defines the number of *sparse blocks* that are zeroed-out
  2. `sparse_block_shape` defines the shape of the sparse blocks. Note that
      the sparse blocks originate at the zero-index of the tensor.
  3. `zeros_per_block` is the number of zeros that we are expecting in each
      sparse block. By default we assume that all elements within a block are
      zeroed-out. However, setting this variable sets the target number of
      zeros per block. The zeros within each block are chosen as the *smallest
      absolute values*.
  
  Args:
  
      sparsity_level: The target level of sparsity
      sparse_block_shape: The shape of a sparse block (see note below)
      zeros_per_block: Number of zeros in a sparse block
      norm: Norm to use. Could be either `int` or a callable.
          If `int`, only L1 and L2 are implemented.
  
  Note::
      The `sparse_block_shape` is tuple representing (block_ROWS, block_COLS),
      irrespective of what the rows / cols mean in the data tensor. That means,
      if you were to sparsify a weight tensor in the nn.Linear, which has a
      weight shape `(Cout, Cin)`, the `block_ROWS` would refer to the output
      channels, while the `block_COLS` would refer to the input channels.
  
  Note::
      All arguments to the WeightNormSparsifier constructor are "default"
      arguments and could be overriden by the configuration provided in the
      `prepare` step.
code: def __init__(
      self,
      sparsity_level: float = 0.5,
      sparse_block_shape: Tuple[int, int] = (1, 4),
      zeros_per_block: Optional[int] = None,
      norm: Optional[Union[Callable, int]] = None,
  ):
      if zeros_per_block is None:
          zeros_per_block = reduce(operator.mul, sparse_block_shape)
      defaults = {
          "sparsity_level": sparsity_level,
          "sparse_block_shape": sparse_block_shape,
          "zeros_per_block": zeros_per_block,
      }
      if norm is None:
          norm = 2
      if callable(norm):
          self.norm_fn = norm
      elif norm == 1:
          self.norm_fn = lambda T: T.abs()
      elif norm == 2:
          self.norm_fn = lambda T: T * T
      else:
          raise NotImplementedError(f"L-{norm} is not yet implemented.")
      super().__init__(defaults=defaults)
  
file_path: pytorch/torch/ao/pruning/sparsifier/weight_norm_sparsifier.py
imports: from functools import reduce
  from typing import Callable, Optional, Tuple, Union
  import torch
  import torch.nn.functional
  from .base_sparsifier import BaseSparsifier
  import operator
label_desc: Use image node_id 1 to create a new WeightNormSparsifier object from inherited base classes: BaseSparsifier with example: obj = WeightNormSparsifier(sparsity_level, sparse_block_shape, zeros_per_block, norm)