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_magnitude(
      val, target_sparsity, block_size=None, dim=None
  ):
      def _apply_block_sparsity(val, block_size, dim):
          shape = val.shape
          rank = len(shape)
          assert dim in [
              0,
              1,
          ], "bock sparsity pruning only supports dim [0, 1]."
          assert rank in [
              2,
              3,
              4,
              5,
          ], "block sparsity only supports weights of rank [2, 3, 4, 5]"
          """
              Block sparsity follows these steps:
  
              1. Input tensor with shape of ``[C_out, Cin, *K]``.
              2. If ``dim = 1``, the tensor is transposed to ``[Cin, C_out, *K]``. The following example assumes ``dim = 0``.
              3. Pad ``C_out`` so that it can be divided by ``block_size``: ``[C_out_pad, Cin, *K]``.
              4. Divide the output channel by ``block_size`` and reshape: ``[C_out_pad // block_size, block_size, C_in, *K]``.
              5. Compute the magnitude for each block: ``[C_out_pad // block_size, 1, C_in, *K]``.
              6. Replicate the magnitude values for each block: ``[C_out_pad // block_size, block_size, C_in, *K]``.
              7. Reshape the tensor back to ``[Cout_pad, C_in, *K]``.
              8. Crop the tensor to ``[C_out, C_in, *K]``.
              9. If ``dim = 1``, transpose the tensor back to the original layout.
              """
          if dim == 1:
              perm = [1, 0] + list(range(2, rank))
              val = np.transpose(val, axes=perm)
  
          channel = val.shape[0]
          if channel % block_size != 0:
              pad_size = block_size - channel % block_size
              pad_value = [(0, pad_size)] + [(0, 0)] * (rank - 1)
              val = np.pad(val, pad_value)
          shape_padded = val.shape
          assert shape_padded[0] % block_size == 0
  
          new_shape = list(shape_padded)
          new_shape.insert(1, block_size)
          new_shape[0] = new_shape[0] // block_size
          val = np.reshape(val, (new_shape))
  
          val = val * val
          val = np.sum(val, axis=1, keepdims=True)
          val = np.sqrt(val)
  
          reps = [1] * (rank + 1)
          reps[1] = block_size
          val = np.tile(val, reps)
          val = np.reshape(val, shape_padded)
          val = val[:channel]
  
          if dim == 1:
              val = np.transpose(val, axes=perm)
  
          return val
  
      magnitude_map = np.abs(val)
      if block_size is not None:
          channel = magnitude_map.shape[dim]
          if block_size > channel / 2:
              logger.warning(
                  f"block_size > channel / 2 is not applicable for block sparsity. Got block_size = {block_size}, channel = {channel}. Skipped."
              )
              return None
  
          magnitude_map = _apply_block_sparsity(
              magnitude_map, block_size, dim
          )
      q = target_sparsity * 100
      if q == 100:
          val = 0 * val
      elif q != 0:
          val = np.where(
              magnitude_map <= np.percentile(magnitude_map, q), 0, val
          )
      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 4 for calling the prune_weights obj's underlying member method code with example usage: obj.compress_by_magnitude(val, target_sparsity, block_size, dim) and returns: prune_weights, val, None