code: def _sparse_layer_test_helper(
      model_class,
      sparse_mapping,
      ref_mapping,
      qconfig_dict,
      fqn_to_check,
      test_class,
      test_scripting,
  ):
      # SET UP TEST PARAMETERS, INPUTS AND WEIGHTS
      # ------------------------------------------
      batch_size = 12
      input_channels = 4
      output_channels = 7
      model = model_class(input_channels, output_channels)
  
      # For sparse kernels both the activation and weight ZP = 0
      X_scale = 0.2
      X_zp = 2
      W_scale = 1e-2
      W_zp = 0
  
      X_fp32 = torch.randn(
          batch_size, input_channels, dtype=torch.float32
      )
      float_bias = torch.randn(output_channels, dtype=torch.float32)
  
      # generate a weight which we'll insert into the model
      W_fp32 = torch.randn(
          output_channels, input_channels, dtype=torch.float32
      )
      mask = torch.randint(0, 2, W_fp32.shape)
      W_fp32 *= mask
      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
          )
          X_fp32 = X_q.dequantize()
  
          W_q = torch.quantize_per_tensor(
              W_fp32, W_scale, W_zp, torch.qint8
          )
  
          # PREPARE MODELS FOR QUANTIZATION
          # -------------------------------
          model.linear.weight = nn.Parameter(W_q.dequantize())
          model.eval()
  
          # Add `sparse_params` to the model. The test for correct
          # sparse_param addition is in the sparsifier tests
          model.linear.sparse_params = {"sparse_block_shape": (1, 4)}
  
          # generate model versions
          qmodel = copy.deepcopy(model)
          sqmodel = copy.deepcopy(model)
  
          # generate model versions and apply qconfigs
          tq.propagate_qconfig_(qmodel, qconfig_dict)
          tq.propagate_qconfig_(sqmodel, qconfig_dict)
  
          tq.prepare(qmodel, inplace=True)
          tq.prepare(sqmodel, inplace=True)
  
          # calibrate
          with torch.no_grad():
              qmodel(X_fp32)
              sqmodel(X_fp32)
  
          # ACTUAL TESTING BEGINS HERE
          # --------------------------
  
          # Make sure the quantization parameters are computed the same way
          qparams = qmodel.linear.qconfig.weight().calculate_qparams()
          sqparams = sqmodel.linear.qconfig.weight().calculate_qparams()
          test_class.assertEqual(qparams, sqparams)
  
          sqmodule_to_check = fqn_to_module(sqmodel, fqn_to_check)
          sqmodule_start_class = sqmodule_to_check.__class__
          sqmodule_expected_converted_class = sparse_mapping[
              sqmodule_start_class
          ]
  
          qmodule_to_check = fqn_to_module(qmodel, fqn_to_check)
          qmodule_start_class = qmodule_to_check.__class__
          qmodule_expected_converted_class = ref_mapping[
              qmodule_start_class
          ]
  
          # need to determine whether dynamic quantization is being performed since
          # input dtype will be different at the end
          is_dynamic = isinstance(
              qmodule_to_check.activation_post_process,
              tq.PlaceholderObserver,
          )
  
          tq.convert(sqmodel, inplace=True, mapping=sparse_mapping)
          tq.convert(qmodel, inplace=True, mapping=ref_mapping)
  
          # this code is a duplicate of above since the references do not
          # update to the post-convert modules
          sqmodule_to_check = fqn_to_module(sqmodel, fqn_to_check)
          qmodule_to_check = fqn_to_module(qmodel, fqn_to_check)
  
          # check that the modules were converted as expected
          assert isinstance(
              sqmodule_to_check, sqmodule_expected_converted_class
          ), "Convert failed"
          assert isinstance(
              qmodule_to_check, qmodule_expected_converted_class
          ), "Mapping failed"
  
          (
              row_block_size,
              col_block_size,
          ) = sqmodel.linear._packed_params._weight_bias()[2:]
          assert row_block_size == 1 and col_block_size == 4
  
          # only run during serialization/deserialization tests
          # makes sure script/save/load doesn't malform the sqmodel
          if test_scripting:
              scripted_sqmodel = torch.jit.script(sqmodel)
              scripted_sqmodel.eval()
              buffer = io.BytesIO()
              torch.jit.save(scripted_sqmodel, buffer)
              buffer.seek(0)
              sqmodel = torch.jit.load(buffer)
  
          # use correct input dtype
          if is_dynamic:
              Y_ref = qmodel(X_fp32)
              Y_hat = sqmodel(X_fp32)
              test_class.assertEqual(Y_ref, Y_hat)
          else:
              Y_ref = qmodel(X_q)
              Y_hat = sqmodel(X_q)
              test_class.assertEqual(
                  Y_ref.dequantize(), Y_hat.dequantize()
              )
  
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 a global function with example usage: _sparse_layer_test_helper(model_class, sparse_mapping, ref_mapping, qconfig_dict, fqn_to_check, test_class, test_scripting) without return types