code: def get_mixed_gp(cat_dims, cont_dims, rs, normalize_y=True):
      cat_dims = np.array(cat_dims, dtype=np.int)
      cont_dims = np.array(cont_dims, dtype=np.int)
      n_dimensions = len(cat_dims) + len(cont_dims)
      exp_kernel = MaternKernel(
          2.5,
          lengthscale_constraint=Interval(
              torch.tensor(
                  np.exp(-6.754111155189306).repeat(cont_dims.shape[-1])
              ),
              torch.tensor(
                  np.exp(0.0858637988771976).repeat(cont_dims.shape[-1])
              ),
              transform=None,
              initial_value=1.0,
          ),
          ard_num_dims=cont_dims.shape[-1],
          active_dims=tuple(cont_dims),
          lengthscale_prior=UniformPrior(
              np.exp(-6.754111155189306), np.exp(0.858637988771976)
          ),
      ).double()
  
      ham_kernel = CategoricalKernel(
          lengthscale_constraint=Interval(
              torch.tensor(
                  np.exp(-6.754111155189306).repeat(cat_dims.shape[-1])
              ),
              torch.tensor(
                  np.exp(0.0858637988771976).repeat(cat_dims.shape[-1])
              ),
              transform=None,
              initial_value=1.0,
          ),
          ard_num_dims=cat_dims.shape[-1],
          active_dims=tuple(cat_dims),
          lengthscale_prior=UniformPrior(
              np.exp(-6.754111155189306), np.exp(0.858637988771976)
          ),
      ).double()
  
      kernel = ProductKernel(exp_kernel, ham_kernel)
  
      kernel = ScaleKernel(
          kernel,
          outputscale_constraint=Interval(
              np.exp(-10.0),
              np.exp(2.0),
              transform=None,
              initial_value=2.0,
          ),
          outputscale_prior=LogNormalPrior(0.0, 1.0),
      )
  
      bounds = [0] * n_dimensions
      types = np.zeros(n_dimensions)
      for c in cont_dims:
          bounds[c] = (0.0, 1.0)
      for c in cat_dims:
          types[c] = 3
          bounds[c] = (3, np.nan)
  
      cs = ConfigurationSpace()
      for c in cont_dims:
          cs.add_hyperparameter(
              UniformFloatHyperparameter("X%d" % c, 0, 1)
          )
      for c in cat_dims:
          cs.add_hyperparameter(
              CategoricalHyperparameter("X%d" % c, [0, 1, 2, 3])
          )
  
      model = GPyTorchGaussianProcess(
          configspace=cs,
          bounds=bounds,
          types=types,
          kernel=kernel,
          seed=rs.randint(low=1, high=10000),
          normalize_y=normalize_y,
      )
      return model
  
imports: import unittest.mock
  import numpy
  import pyro
  import torch
  from botorch.models.kernels.categorical import CategoricalKernel
  from gpytorch.constraints.constraints import Interval
  from gpytorch.kernels import MaternKernel, ProductKernel, ScaleKernel
  from gpytorch.likelihoods.gaussian_likelihood import GaussianLikelihood
  from gpytorch.mlls.exact_marginal_log_likelihood import ExactMarginalLogLikelihood
  from gpytorch.models.exact_gp import ExactGP
  from gpytorch.priors import HorseshoePrior, LogNormalPrior, UniformPrior
  from gpytorch.utils.errors import NotPSDError
  from smac.configspace import CategoricalHyperparameter, ConfigurationSpace, UniformFloatHyperparameter
  from smac.model.gaussian_process.gpytorch_gaussian_process import GPyTorchGaussianProcess
  from ._test_gp import TestGP, get_cat_data, get_cont_data
label_desc: Use image node_id 2 for calling a global function with example usage: get_mixed_gp(cat_dims, cont_dims, rs, normalize_y) and returns: model