code: def test_qMS(self):
      d = 2
      q = 1
      num_data = 3
      q_batch_sizes = [1, 1, 1]
      num_fantasies = [2, 2, 1]
      t_batch_size = [2]
      for dtype in (torch.float, torch.double):
          bounds = torch.tensor(
              [[0], [1]], device=self.device, dtype=dtype
          )
          bounds = bounds.repeat(1, d)
          train_X = torch.rand(
              num_data, d, device=self.device, dtype=dtype
          )
          train_Y = torch.rand(
              num_data, 1, device=self.device, dtype=dtype
          )
          model = SingleTaskGP(train_X, train_Y)
  
          # default evaluation testsÎ
          qMS = qMultiStepLookahead(
              model=model,
              batch_sizes=[1, 1, 1],
              num_fantasies=num_fantasies,
          )
          q_prime = qMS.get_augmented_q_batch_size(q)
          eval_X = torch.rand(
              t_batch_size + [q_prime, d],
              device=self.device,
              dtype=dtype,
          )
          result = qMS(eval_X)
          self.assertEqual(result.shape, torch.Size(t_batch_size))
  
          qMS = qMultiStepLookahead(
              model=model,
              batch_sizes=q_batch_sizes,
              valfunc_cls=[qExpectedImprovement] * 4,
              valfunc_argfacs=[make_best_f] * 4,
              num_fantasies=num_fantasies,
              inner_mc_samples=[2] * 4,
          )
          result = qMS(eval_X)
          self.assertEqual(result.shape, torch.Size(t_batch_size))
  
          # get induced fantasy model, with collapse_fantasy_base_samples
          fant_model = qMS.get_induced_fantasy_model(eval_X)
          self.assertEqual(
              fant_model.train_inputs[0].shape,
              torch.Size(
                  num_fantasies[::-1]
                  + t_batch_size
                  + [num_data + sum(q_batch_sizes), d]
              ),
          )
  
          # collapse fantasy base samples
          qMS = qMultiStepLookahead(
              model=model,
              batch_sizes=q_batch_sizes,
              valfunc_cls=[qExpectedImprovement] * 4,
              valfunc_argfacs=[make_best_f] * 4,
              num_fantasies=num_fantasies,
              inner_mc_samples=[2] * 4,
              collapse_fantasy_base_samples=False,
          )
          q_prime = qMS.get_augmented_q_batch_size(q)
          eval_X = torch.rand(
              t_batch_size + [q_prime, d],
              device=self.device,
              dtype=dtype,
          )
          result = qMS(eval_X)
          self.assertEqual(result.shape, torch.Size(t_batch_size))
          self.assertEqual(
              qMS.samplers[0]._get_batch_range(model.posterior(eval_X)),
              (-3, -2),
          )
  
          # get induced fantasy model, without collapse_fantasy_base_samples
          fant_model = qMS.get_induced_fantasy_model(eval_X)
          self.assertEqual(
              fant_model.train_inputs[0].shape,
              torch.Size(
                  num_fantasies[::-1]
                  + t_batch_size
                  + [num_data + sum(q_batch_sizes), d]
              ),
          )
  
          # X_pending
          X_pending = torch.rand(5, d, device=self.device, dtype=dtype)
          qMS = qMultiStepLookahead(
              model=model,
              batch_sizes=q_batch_sizes,
              valfunc_cls=[qExpectedImprovement] * 4,
              valfunc_argfacs=[make_best_f] * 4,
              num_fantasies=num_fantasies,
              inner_mc_samples=[2] * 4,
              X_pending=X_pending,
          )
          q_prime = qMS.get_augmented_q_batch_size(q)
          eval_X = torch.rand(
              t_batch_size + [q_prime, d],
              device=self.device,
              dtype=dtype,
          )
          result = qMS(eval_X)
          self.assertEqual(result.shape, torch.Size(t_batch_size))
  
          # add dummy base_weights to samplers
          samplers = [
              SobolQMCNormalSampler(sample_shape=torch.Size([nf]))
              for nf in num_fantasies
          ]
          for s in samplers:
              s.base_weights = torch.ones(
                  s.sample_shape[0], 1, device=self.device, dtype=dtype
              )
  
          qMS = qMultiStepLookahead(
              model=model,
              batch_sizes=[1, 1, 1],
              samplers=samplers,
          )
          q_prime = qMS.get_augmented_q_batch_size(q)
          eval_X = torch.rand(
              t_batch_size + [q_prime, d],
              device=self.device,
              dtype=dtype,
          )
          result = qMS(eval_X)
          self.assertEqual(result.shape, torch.Size(t_batch_size))
  
          # extract candidates
          cand = qMS.extract_candidates(eval_X)
          self.assertEqual(
              cand.shape, torch.Size(t_batch_size + [q, d])
          )
  
file_path: botorch/test/acquisition/test_multi_step_lookahead.py
imports: import torch
  from botorch.acquisition import ExpectedImprovement, qExpectedImprovement, qMultiStepLookahead
  from botorch.acquisition.multi_step_lookahead import make_best_f, warmstart_multistep
  from botorch.acquisition.objective import IdentityMCObjective
  from botorch.exceptions.errors import UnsupportedError
  from botorch.models import SingleTaskGP
  from botorch.sampling import SobolQMCNormalSampler
  from botorch.utils.testing import BotorchTestCase
label_desc: Use image node_id 2 for calling the TestMultiStepLookahead obj's underlying member method code with example usage: obj.test_qMS() without return types