code: def custom_kernel(X, Y, func, **kwds):
      kwds_tuple = _kwds_to_tuple_args(func, **kwds)
  
      def evaluate_pairwise_kernels(X, Y, K):
          idx = cuda.threadIdx.x + cuda.blockIdx.x * cuda.blockDim.x
          X_m = X.shape[0]
          Y_m = Y.shape[0]
          row = idx // Y_m
          col = idx % Y_m
          if idx < X_m * Y_m:
              if X is Y and row <= col:
                  # matrix is symmetric, reuse half the evaluations
                  k = func(X[row], Y[col], *kwds_tuple)
                  K[row, col] = k
                  K[col, row] = k
              else:
                  k = func(X[row], Y[col], *kwds_tuple)
                  K[row, col] = k
  
      if Y is None:
          Y = X
      if X.shape[1] != Y.shape[1]:
          raise ValueError("X and Y have different dimensions.")
  
      # Here we force K to use 64 bit, even if the input is 32 bit
      # 32 bit K results in serious numerical stability problems
      K = cp.zeros((X.shape[0], Y.shape[0]), dtype=np.float64)
  
      key = (func, kwds_tuple, X.dtype, Y.dtype)
      if key in _kernel_cache:
          compiled_kernel = _kernel_cache[key]
      else:
          compiled_kernel = cuda.jit(evaluate_pairwise_kernels)
          _kernel_cache[key] = compiled_kernel
      compiled_kernel.forall(X.shape[0] * Y.shape[0])(X, Y, K)
      return K
  
file_path: cuml/python/cuml/metrics/pairwise_kernels.py
imports: from cuml.internals.input_utils import input_to_cupy_array
  from cuml.metrics import pairwise_distances
  import cuml.internals
  from cuml.internals.safe_imports import cpu_only_import
  from cuml.internals.safe_imports import gpu_only_import
  import inspect
  from cuml.internals.safe_imports import gpu_only_import_from
label_desc: Use image node_id 12 for calling a global function with example usage: custom_kernel(X, Y, func) and returns: K