code: def batch_compute_kernel_matrix(
      x: Union[list, np.ndarray, torch.Tensor],
      y: Union[list, np.ndarray, torch.Tensor],
      kernel: Union[nn.Module, nn.Sequential],
      device: torch.device = None,
      batch_size: int = int(1e10),
      preprocess_fn: Callable[..., torch.Tensor] = None,
  ) -> torch.Tensor:
      """
      Compute the kernel matrix between x and y by filling in blocks of size
      batch_size x batch_size at a time.
  
      Parameters
      ----------
      x
          Reference set.
      y
          Test set.
      kernel
          PyTorch module.
      device
          Device type used. The default None tries to use the GPU and falls back on CPU if needed.
          Can be specified by passing either torch.device('cuda') or torch.device('cpu').
      batch_size
          Batch size used during prediction.
      preprocess_fn
          Optional preprocessing function for each batch.
  
      Returns
      -------
      Kernel matrix in the form of a torch tensor
      """
      if device is None:
          device = torch.device(
              "cuda" if torch.cuda.is_available() else "cpu"
          )
      if type(x) != type(y):  # noqa: E721
          raise ValueError("x and y should be of the same type")
  
      if isinstance(x, np.ndarray):
          x, y = torch.from_numpy(x), torch.from_numpy(y)
  
      n_x, n_y = len(x), len(y)
      n_batch_x, n_batch_y = int(np.ceil(n_x / batch_size)), int(
          np.ceil(n_y / batch_size)
      )
      with torch.no_grad():
          k_is: List[torch.Tensor] = []
          for i in range(n_batch_x):
              istart, istop = i * batch_size, min(
                  (i + 1) * batch_size, n_x
              )
              x_batch = x[istart:istop]
              if preprocess_fn is not None:
                  x_batch = preprocess_fn(x_batch)
              x_batch = x_batch.to(device)  # type: ignore
              k_ijs: List[torch.Tensor] = []
              for j in range(n_batch_y):
                  jstart, jstop = j * batch_size, min(
                      (j + 1) * batch_size, n_y
                  )
                  y_batch = y[jstart:jstop]
                  if preprocess_fn is not None:
                      y_batch = preprocess_fn(y_batch)
                  y_batch = y_batch.to(device)  # type: ignore
                  k_ijs.append(kernel(x_batch, y_batch).cpu())
              k_is.append(torch.cat(k_ijs, 1))
          k_mat = torch.cat(k_is, 0)
      return k_mat
  
file_path: alibi-detect/alibi_detect/utils/pytorch/distance.py
imports: import logging
  import torch
  from torch import nn
  import numpy
  from typing import Callable, List, Tuple, Optional, Union
label_desc: Use image node_id 2 for calling a global function with example usage: batch_compute_kernel_matrix(x, y, kernel, device, batch_size, preprocess_fn) and returns: k_mat