class_docstr: This transform works for each ``const`` op if:
  
  - ``_is_deprecated=True`` and the ``op_selector`` returns ``True``.
  - ``_is_deprecated=False`` and the ``const`` value size ``> weight_threshold``.
  
  The transform performs the following:
  
  - The fraction of values with the least absolute value are zeroed out (self.sparsity).
  - If ``fake_compression=False``, the zeroed-out value is encoded using the ``constexpr_sparse_to_dense`` op.
  - If ``fake_compression=True``, the zeroed-out value is encoded using the ``const`` op.
  - Old ``const`` is replaced by a new operation with zeroed-out value.
class_docstr_tok: ["This","transform","works","for","each","``","const","``","op","if",":","-","``","_is_deprecated=True","``","and","the","``","op_selector","``","returns","``","True","``",".","-","``","_is_deprecated=False","``","and","the","``","const","``","value","size","``",">","weight_threshold","``",".","The","transform","performs","the","following",":","-","The","fraction","of","values","with","the","least","absolute","value","are","zeroed","out","(","self.sparsity",")",".","-","If","``","fake_compression=False","``",",","the","zeroed-out","value","is","encoded","using","the","``","constexpr_sparse_to_dense","``","op",".","-","If","``","fake_compression=True","``",",","the","zeroed-out","value","is","encoded","using","the","``","const","``","op",".","-","Old","``","const","``","is","replaced","by","a","new","operation","with","zeroed-out","value","."]
code: def compress_by_nm_sparsity(val, n_m_ratio, dim):
      n, m = n_m_ratio
      assert n <= m
      shape = val.shape
      rank = len(shape)
      assert dim in [0, 1], "n:m pruning only supports dim [0, 1]."
      assert rank in [
          2,
          3,
          4,
          5,
      ], "m:m pruning only supports weights of rank [2, 3, 4, 5]"
      """
          The `n-m` pruning process follows these steps:
          1. Input tensor with shape of ``[C_out, C_in, *K]``, where ``K`` is the spatial dimension from ``0`` to ``3``.
          2. If ``axis = 1``, transpose the tensor to shape ``[*K, C_out, C_in]``; otherwise, ``(axis = 0)`` to ``[*K, C_in, C_out]``.
          3. For the case of ``axis = 1``, reshape input to a 2D tensor ``[*K*C_out, C_in]``. Similar for ``axis = 0``.
          4. Pad the last dimension with ``0`` so that it can be divided by ``m``: ``[*K*C_out, C_in_pad]``.
          5. Reshape the tensor to have the last dimension ``m``: ``[*K*C_out*C_in_pad//m, m]``.
          6. For each vector of length ``m``, we set the lowest ``n`` magnitute elements to ``0``.
          7. Reshape the tensor back to the shape of ``[*K*C_out, C_in_pad]``.
          8. Crop the last dimension to match the original shape of ``[*K*C_out, C_in]``.
          9. Reshape the tensor to shape ``[*K, C_out, C_in]``.
          10. Transpose the tensor back to ``[C_out, C_in, K]``.
          """
      perm = list(range(2, rank)) + [0, 1]
      if dim == 0:
          perm[-2], perm[-1] = 1, 0
      weight = np.copy(np.transpose(val, axes=perm))
      shape_begin = weight.shape
  
      weight = np.reshape(weight, (-1, weight.shape[-1]))
      channel = weight.shape[-1]
      if m > channel / 2:
          logger.warning(
              f"m > channel / 2 is not applicable for n:m pruning. Got m = {m}, channel = {channel}. Skipped."
          )
          return None
      if channel % m != 0:
          pad_size = m - channel % m
          weight = np.pad(weight, ((0, 0), (0, pad_size)))
      shape_padded = weight.shape
      assert shape_padded[-1] % m == 0
  
      weight = np.reshape(weight, (-1, m))
      magnitute = np.abs(weight)
      indices = np.argsort(magnitute, axis=-1)[:, :n]
  
      n_m_mask = np.zeros(weight.shape).astype(val.dtype)
      np.put_along_axis(n_m_mask, indices, 1.0, axis=-1)
      n_m_mask = np.reshape(n_m_mask, shape_padded)
      n_m_mask = n_m_mask[:, :channel]
  
      n_m_mask = np.reshape(n_m_mask, shape_begin)
      perm_back = [perm.index(i) for i in range(rank)]
      n_m_mask = np.transpose(n_m_mask, axes=perm_back)
  
      val = val * (1 - n_m_mask)
      return prune_weights._pack_val_to_sparse_param(val)
  
imports: from typing import Callable, Optional, Tuple
  import numpy
  from tqdm import tqdm
  from coremltools import _logger
  from coremltools.converters.mil._deployment_compatibility import AvailableTarget
  from coremltools.converters.mil.backend.mil.load import should_use_weight_file
  from coremltools.converters.mil.mil import Builder
  from coremltools.converters.mil.mil import Operation, Program, types
  from coremltools.converters.mil.mil.block import is_current_opset_version_compatible_with
  from coremltools.converters.mil.mil.ops.defs._utils import pack_elements_into_bits
  from coremltools.converters.mil.mil.ops.defs.iOS16 import constexpr_affine_dequantize, constexpr_lut_to_dense, constexpr_sparse_to_dense
  from coremltools.converters.mil.mil.passes.defs.quantization import AbstractQuantizationPass
  from coremltools.converters.mil.mil.passes.helper import block_context_manager
  from coremltools.converters.mil.mil.passes.pass_registry import register_pass
  from coremltools.converters.mil.mil.types.type_mapping import nptype_from_builtin
  from coremltools.models.neural_network.quantization_utils import _get_kmeans_lookup_table_and_weight
  from coremltools.optimize.coreml._config import OpLinearQuantizerConfig, OpMagnitudePrunerConfig, OpPalettizerConfig, OpThresholdPrunerConfig, OptimizationConfig
label_desc: Use image node_id 5 for calling the prune_weights obj's underlying member method code with example usage: obj.compress_by_nm_sparsity(val, n_m_ratio, dim) and returns: prune_weights, None