code: def test_sparse_qlinear(self):
      batch_size = 12
      input_channels = 16
      output_channels = 4
      decimal_val = 4
      row_block_size = 1
      col_block_size = 4
  
      # X86 implementation of sparse ops in qnnpack only support
      # block pattern 1x4.
      # arm kernels have support for both 1x4 and 8x1.
      # This distinction is only because x86 implementations exist
      # only to enable testing of integration path.
      # We do plan to add 8x1 as well so that testing does not have to
      # special case like this. At the moment it is deprioritized due
      # to other higher priority works.
      if qengine_is_qnnpack() and not (
          row_block_size == 1 and col_block_size == 4
      ):
          return
      # ONEDNN and X86 do not support this yet
      if qengine_is_onednn() or qengine_is_x86():
          return
  
      dense_prepack = torch.ops.quantized.linear_prepack
      dense_qlinear = torch.ops.quantized.linear
      dense_qlinear_dynamic = torch.ops.quantized.linear_dynamic
  
      sparse_prepack = torch.ops.sparse.qlinear_prepack
      sparse_qlinear = torch.ops.sparse.qlinear
      sparse_qlinear_dynamic = torch.ops.sparse.qlinear_dynamic
  
      X_scale = 0.2
      X_zp = 2
      X_fp32 = torch.randn(
          batch_size, input_channels, dtype=torch.float32
      )
      float_bias = torch.randn(output_channels, dtype=torch.float32)
  
      W_scales = torch.rand(output_channels, dtype=torch.float32)
      W_zps = torch.zeros(output_channels, dtype=torch.int32)
      W_fp32 = torch.randn(
          output_channels, input_channels, dtype=torch.float32
      )
  
      with override_cpu_allocator_for_qnnpack(qengine_is_qnnpack()):
          X_q = torch.quantize_per_tensor(
              X_fp32, scale=X_scale, zero_point=X_zp, dtype=torch.quint8
          )
  
          for use_channelwise, dynamic_mode in product(
              [True, False], [True, False]
          ):
              if qengine_is_fbgemm() and dynamic_mode:
                  logging.info(
                      "dynamic sparse qlinear is only available in qnnpack"
                  )
                  continue
              if qengine_is_qnnpack() and not dynamic_mode:
                  logging.info(
                      "static sparse qlinear is only available in fbgemm"
                  )
                  continue
              if use_channelwise:
                  W_q = torch.quantize_per_channel(
                      W_fp32,
                      scales=W_scales,
                      zero_points=W_zps,
                      axis=0,
                      dtype=torch.qint8,
                  )
              else:
                  W_q = torch.quantize_per_tensor(
                      W_fp32,
                      scale=W_scales[0],
                      zero_point=W_zps[0],
                      dtype=torch.qint8,
                  )
  
              Y_scale = 1.1234
              Y_zp = 5
              W_prepack_dense = dense_prepack(W_q, float_bias)
              W_prepack_sparse = sparse_prepack(
                  W_q, float_bias, row_block_size, col_block_size
              )
  
              if dynamic_mode:
                  Y = sparse_qlinear_dynamic(X_fp32, W_prepack_sparse)
                  Y_ref = dense_qlinear_dynamic(X_fp32, W_prepack_dense)
  
                  np.testing.assert_array_almost_equal(
                      Y_ref.numpy(), Y.numpy(), decimal=decimal_val
                  )
              else:
                  Y_q = sparse_qlinear(
                      X_q, W_prepack_sparse, Y_scale, Y_zp
                  )
                  Y_q_ref = dense_qlinear(
                      X_q, W_prepack_dense, Y_scale, Y_zp
                  )
  
                  np.testing.assert_array_almost_equal(
                      Y_q_ref.int_repr().numpy(),
                      Y_q.int_repr().numpy(),
                      decimal=decimal_val,
                  )
  
imports: from torch.testing._internal.common_utils import run_tests
  import copy
  import numpy
  import io
  import logging
  from itertools import product
  import torch
  import torch.ao.quantization
  from torch import nn
  from torch.ao.pruning.sparsifier.utils import fqn_to_module
  from torch.testing._internal.common_utils import TestCase, skipIfTorchDynamo
  from torch.testing._internal.common_quantized import override_cpu_allocator_for_qnnpack, override_qengines, qengine_is_qnnpack, qengine_is_fbgemm, qengine_is_onednn, qengine_is_x86
label_desc: Use image node_id 1 for calling the TestQuantizedSparseKernels obj's underlying member method code with example usage: obj.test_sparse_qlinear() without return types