code: def _make_decorator(
      check_func,
      name,
      type_check,
      contiguous_check,
      accept_error,
      sp_name=None,
      scipy_name=None,
      check_sparse_format=True,
  ):
      assert isinstance(name, str)
      assert sp_name is None or isinstance(sp_name, str)
      assert scipy_name is None or isinstance(scipy_name, str)
  
      def decorator(impl):
          @_wraps_partial_xp(impl, name, sp_name, scipy_name)
          def test_func(*args, **kw):
              # Run cupy and numpy
              (
                  cupy_result,
                  cupy_error,
                  numpy_result,
                  numpy_error,
              ) = _call_func_numpy_cupy(
                  impl, args, kw, name, sp_name, scipy_name
              )
              assert cupy_result is not None or cupy_error is not None
              assert numpy_result is not None or numpy_error is not None
  
              # Check errors raised
              if cupy_error or numpy_error:
                  _check_cupy_numpy_error(
                      cupy_error, numpy_error, accept_error=accept_error
                  )
                  return
  
              # Check returned arrays
  
              if not isinstance(cupy_result, (tuple, list)):
                  cupy_result = (cupy_result,)
              if not isinstance(numpy_result, (tuple, list)):
                  numpy_result = (numpy_result,)
  
              assert len(cupy_result) == len(numpy_result)
  
              # Check types
              cupy_numpy_result_ndarrays = [
                  _convert_output_to_ndarray(
                      cupy_r, numpy_r, sp_name, check_sparse_format
                  )
                  for cupy_r, numpy_r in zip(cupy_result, numpy_result)
              ]
  
              # Check dtypes
              if type_check:
                  for cupy_r, numpy_r in cupy_numpy_result_ndarrays:
                      if cupy_r.dtype != numpy_r.dtype:
                          raise AssertionError(
                              """ndarrays of different dtypes are returned.
  cupy: {}
  numpy: {}""".format(
                                  cupy_r.dtype, numpy_r.dtype
                              )
                          )
  
              # Check contiguities
              if contiguous_check:
                  for cupy_r, numpy_r in zip(cupy_result, numpy_result):
                      if isinstance(numpy_r, numpy.ndarray):
                          if (
                              numpy_r.flags.c_contiguous
                              and not cupy_r.flags.c_contiguous
                          ):
                              raise AssertionError(
                                  "The state of c_contiguous flag is false. "
                                  "(cupy_result:{} numpy_result:{})".format(
                                      cupy_r.flags.c_contiguous,
                                      numpy_r.flags.c_contiguous,
                                  )
                              )
                          if (
                              numpy_r.flags.f_contiguous
                              and not cupy_r.flags.f_contiguous
                          ):
                              raise AssertionError(
                                  "The state of f_contiguous flag is false. "
                                  "(cupy_result:{} numpy_result:{})".format(
                                      cupy_r.flags.f_contiguous,
                                      numpy_r.flags.f_contiguous,
                                  )
                              )
  
              # Check shapes
              for cupy_r, numpy_r in cupy_numpy_result_ndarrays:
                  assert cupy_r.shape == numpy_r.shape
  
              masks = [None] * len(cupy_result)
              if _contains_signed_and_unsigned(kw):
                  needs_mask = [
                      cupy_r.dtype in _unsigned_dtypes
                      for cupy_r in cupy_result
                  ]
                  if any(needs_mask):
                      masks = _make_positive_masks(
                          impl, args, kw, name, sp_name, scipy_name
                      )
                      for i, flag in enumerate(needs_mask):
                          if not flag:
                              masks[i] = None
  
              # Check item values
              for (cupy_r, numpy_r), mask in zip(
                  cupy_numpy_result_ndarrays, masks
              ):
                  # Behavior of assigning a negative value to an unsigned integer
                  # variable is undefined.
                  # nVidia GPUs and Intel CPUs behave differently.
                  # To avoid this difference, we need to ignore dimensions whose
                  # values are negative.
  
                  skip = False
                  if mask is not None:
                      if cupy_r.shape == ():
                          skip = (mask == 0).all()
                      else:
                          cupy_r = cupy_r[mask].get()
                          numpy_r = numpy_r[mask]
  
                  if not skip:
                      check_func(cupy_r, numpy_r)
  
          return test_func
  
      return decorator
  
imports: import functools
  import inspect
  import os
  import random
  from typing import Tuple, Type
  import traceback
  import unittest
  import warnings
  import numpy
  import cupy
  from cupy.testing import _array
  from cupy.testing import _parameterized
  import cupyx
  import cupyx.scipy.sparse
  from cupy.testing._pytest_impl import is_available
label_desc: Use image node_id 14 for calling a global function with example usage: _make_decorator(check_func, name, type_check, contiguous_check, accept_error, sp_name, scipy_name, check_sparse_format) and returns: decorator, test_func