botorch
                                
                                 botorch copied to clipboard
                                
                                    botorch copied to clipboard
                            
                            
                            
                        [Bug] [relatively easy fix] `gen_one_shot_kg_initial_conditions` should error when provided inter-point constraints
🐛 Bug
See https://github.com/pytorch/botorch/issues/1220 for context.  optimize_acqf does not support inter-point constraints -- those whose indices are two-dimensional -- when the acquisition function is qKnowledgeGradient. This is because gen_one_shot_kg_initial_conditions does not support inter-point constraints. Since typing constraints correctly is confusing, BoTorch should raise an informative error rather than leaving the user to get a confusing IndexError and wonder if they typed the constraints wrong :)
To reproduce
from botorch.acquisition import qKnowledgeGradient
from botorch.fit import fit_gpytorch_mll
from botorch.models import SingleTaskGP
from gpytorch.mlls import ExactMarginalLogLikelihood
x = torch.rand((20, 2))
y = x.sum(1, keepdim=True) - 1
model = SingleTaskGP(train_X=x, train_Y=y)
mll = ExactMarginalLogLikelihood(model.likelihood, model)
 _ = fit_gpytorch_mll(mll)
bounds = torch.tensor([[0, 0], [1, 1]]).to(x)
q = 2
# should have
# samples[:, 0, 0] * 1 + samples[:, 1, 1] >= 0.5
# where samples is n x q x d
indices = torch.tensor([[0, 0], [1, 1]])
inequality_constraints = [(indices, torch.ones(2).to(x), 0.5)]
acqf = qKnowledgeGradient(model, num_fantasies=8)
candidates, acq_vals = optimize_acqf(
        acq_function=acqf,
        bounds=bounds,
        q=q,
        num_restarts=10,
        raw_samples=64,
        inequality_constraints=inequality_constraints,
)
** Stack trace/error message **
 1) IndexError: index 3 is out of bounds for dimension 0 with size 2
      File "pytorch/botorch/test/optim/test_optimize.py", line 265, in ftest_optimize_acqf_kg_constrained
        candidates, acq_vals = optimize_acqf(
      File "botorch/optim/optimize.py", line 557, in optimize_acqf
        return _optimize_acqf(opt_acqf_inputs)
      File "botorch/optim/optimize.py", line 586, in _optimize_acqf
        return _optimize_acqf_batch(
      File "botorch/optim/optimize.py", line 269, in _optimize_acqf_batch
        batch_initial_conditions = opt_inputs.get_ic_generator()(
      File "botorch/optim/initializers.py", line 570, in gen_one_shot_kg_initial_conditions
        fantasy_cands, fantasy_vals = optimize_acqf(
      File "botorch/optim/optimize.py", line 557, in optimize_acqf
        return _optimize_acqf(opt_acqf_inputs)
      File "botorch/optim/optimize.py", line 586, in _optimize_acqf
        return _optimize_acqf_batch(
      File "botorch/optim/optimize.py", line 269, in _optimize_acqf_batch
        batch_initial_conditions = opt_inputs.get_ic_generator()(
      File "botorch/optim/initializers.py", line 415, in gen_batch_initial_conditions
        X_rnd = sample_q_batches_from_polytope(
      File "botorch/optim/initializers.py", line 272, in sample_q_batches_from_polytope
        samples = get_polytope_samples(
      File "botorch/utils/sampling.py", line 800, in get_polytope_samples
        constraints = normalize_linear_constraints(bounds, inequality_constraints)
      File "botorch/utils/sampling.py", line 754, in normalize_linear_constraints
        lower, upper = bounds[:, index]
Expected Behavior
An informative error should be raised explaining that this is not supported. I think the fix here is that gen_one_shot_kg_initial_conditions should raise an UnsupportedError or NotImplementedError if provided inter-point constraints. However, I'm not 100% sure that gen_one_shot_kg_initial_conditions is the right place for the error, so whoever fixes this should carefully verify that the error is accurate and that usages that don't trigger the error do work.