code: def test_acquisition_functions(self):
      tkwargs = {"device": self.device, "dtype": torch.double}
      # Using a single output model here since we test with single objective acqfs.
      train_X, train_Y, train_Yvar, model = self._get_data_and_model(
          task_rank=1, output_tasks=[0], **tkwargs
      )
      fit_fully_bayesian_model_nuts(
          model,
          warmup_steps=8,
          num_samples=5,
          thinning=2,
          disable_progbar=True,
      )
      for include_task_feature in [True, False]:
          if not include_task_feature:
              test_X = train_X[..., :-1]
          else:
              test_X = train_X
  
          deterministic = GenericDeterministicModel(
              f=lambda x: x[..., :1]
          )
          list_gp = ModelListGP(model, model)
          mixed_list = ModelList(deterministic, model)
          simple_sampler = get_sampler(
              posterior=model.posterior(test_X),
              sample_shape=torch.Size([2]),
          )
          list_gp_sampler = get_sampler(
              posterior=list_gp.posterior(test_X),
              sample_shape=torch.Size([2]),
          )
          mixed_list_sampler = get_sampler(
              posterior=mixed_list.posterior(test_X),
              sample_shape=torch.Size([2]),
          )
          acquisition_functions = [
              ExpectedImprovement(model=model, best_f=train_Y.max()),
              ProbabilityOfImprovement(
                  model=model, best_f=train_Y.max()
              ),
              PosteriorMean(model=model),
              UpperConfidenceBound(model=model, beta=4),
              qExpectedImprovement(
                  model=model,
                  best_f=train_Y.max(),
                  sampler=simple_sampler,
              ),
              qNoisyExpectedImprovement(
                  model=model, X_baseline=test_X, sampler=simple_sampler
              ),
              qProbabilityOfImprovement(
                  model=model,
                  best_f=train_Y.max(),
                  sampler=simple_sampler,
              ),
              qSimpleRegret(model=model, sampler=simple_sampler),
              qUpperConfidenceBound(
                  model=model, beta=4, sampler=simple_sampler
              ),
              qNoisyExpectedHypervolumeImprovement(
                  model=list_gp,
                  X_baseline=test_X,
                  ref_point=torch.zeros(2, **tkwargs),
                  sampler=list_gp_sampler,
              ),
              qExpectedHypervolumeImprovement(
                  model=list_gp,
                  ref_point=torch.zeros(2, **tkwargs),
                  sampler=list_gp_sampler,
                  partitioning=NondominatedPartitioning(
                      ref_point=torch.zeros(2, **tkwargs),
                      Y=train_Y.repeat([1, 2]),
                  ),
              ),
              # qEHVI/qNEHVI with mixed models
              qNoisyExpectedHypervolumeImprovement(
                  model=mixed_list,
                  X_baseline=test_X,
                  ref_point=torch.zeros(2, **tkwargs),
                  sampler=mixed_list_sampler,
              ),
              qExpectedHypervolumeImprovement(
                  model=mixed_list,
                  ref_point=torch.zeros(2, **tkwargs),
                  sampler=mixed_list_sampler,
                  partitioning=NondominatedPartitioning(
                      ref_point=torch.zeros(2, **tkwargs),
                      Y=train_Y.repeat([1, 2]),
                  ),
              ),
          ]
  
          for acqf in acquisition_functions:
              for batch_shape in [[2], [6, 2], [5, 6, 2]]:
                  test_X = torch.rand(*batch_shape, 1, 4, **tkwargs)
                  if include_task_feature:
                      test_X = torch.cat(
                          [test_X, torch.zeros_like(test_X[..., :1])],
                          dim=-1,
                      )
                  self.assertEqual(
                      acqf(test_X).shape, torch.Size(batch_shape)
                  )
  
imports: import itertools
  from typing import List, Optional
  import torch
  from botorch import fit_fully_bayesian_model_nuts
  from botorch.acquisition.analytic import ExpectedImprovement, PosteriorMean, ProbabilityOfImprovement, UpperConfidenceBound
  from botorch.acquisition.monte_carlo import qExpectedImprovement, qNoisyExpectedImprovement, qProbabilityOfImprovement, qSimpleRegret, qUpperConfidenceBound
  from botorch.acquisition.multi_objective import qExpectedHypervolumeImprovement, qNoisyExpectedHypervolumeImprovement
  from botorch.models import ModelList, ModelListGP
  from botorch.models.deterministic import GenericDeterministicModel
  from botorch.models.fully_bayesian import MCMC_DIM, MIN_INFERRED_NOISE_LEVEL
  from botorch.models.fully_bayesian_multitask import MultitaskSaasPyroModel, SaasFullyBayesianMultiTaskGP
  from botorch.models.transforms.input import Normalize
  from botorch.models.transforms.outcome import Standardize
  from botorch.posteriors import GaussianMixturePosterior
  from botorch.sampling.get_sampler import get_sampler
  from botorch.sampling.normal import IIDNormalSampler
  from botorch.utils.multi_objective.box_decompositions.non_dominated import NondominatedPartitioning
  from botorch.utils.test_helpers import gen_multi_task_dataset
  from botorch.utils.testing import BotorchTestCase
  from gpytorch.kernels import MaternKernel, ScaleKernel
  from gpytorch.likelihoods import FixedNoiseGaussianLikelihood
  from gpytorch.likelihoods.gaussian_likelihood import GaussianLikelihood
  from gpytorch.means import ConstantMean
label_desc: Use image node_id 10 for calling the TestFullyBayesianMultiTaskGP obj's underlying member method code with example usage: obj.test_acquisition_functions() without return types