code: def _batched_kernel(kernel, batch_length: int):
      """Adds a batch dimension of size `batch_length` to all non-scalar
      Tensor parameters that govern the kernel function `kernel`.
      NOTE: prior or constraint parameters are excluded from batching.
      """
      # copy just in case there are non-tensor parameters that are passed by reference
      kernel = deepcopy(kernel)
      search_str = "raw_outputscale"
      for key, attr in kernel.state_dict().items():
          if isinstance(attr, Tensor) and (
              attr.ndim > 0 or (search_str == key.rpartition(".")[-1])
          ):
              attr = (
                  attr.unsqueeze(0)
                  .expand(batch_length, *attr.shape)
                  .clone()
              )
              set_attribute(kernel, key, torch.nn.Parameter(attr))
      return kernel
  
imports: from __future__ import annotations
  from copy import deepcopy
  from typing import Dict, Optional, Set, Tuple
  import torch
  from botorch.exceptions import UnsupportedError
  from botorch.models.gp_regression import HeteroskedasticSingleTaskGP
  from botorch.models.gp_regression_fidelity import SingleTaskMultiFidelityGP
  from botorch.models.gp_regression_mixed import MixedSingleTaskGP
  from botorch.models.gpytorch import BatchedMultiOutputGPyTorchModel
  from botorch.models.model_list_gp_regression import ModelListGP
  from botorch.models.transforms.input import InputTransform
  from botorch.models.transforms.outcome import OutcomeTransform
  from gpytorch.likelihoods.gaussian_likelihood import FixedNoiseGaussianLikelihood
  from torch import Tensor
  from torch.nn import Module
label_desc: Use image node_id 4 for calling a global function with example usage: _batched_kernel(kernel, batch_length) and returns: kernel