diff --git a/botorch/optim/optimize.py b/botorch/optim/optimize.py index ae745be1e6..1fc7cfc482 100644 --- a/botorch/optim/optimize.py +++ b/botorch/optim/optimize.py @@ -156,6 +156,24 @@ def ic_gen(self) -> TGenInitialConditions: return gen_batch_initial_conditions +def _raise_deprecation_warning_if_kwargs(fn_name: str, kwargs: Dict[str, Any]) -> None: + """ + Raise a warning if kwargs are provided. + + Some functions used to support **kwargs. The applicable parameters have now been + refactored to be named arguments, so no warning will be raised for users passing + the expected arguments. However, if a user had been passing an inapplicable + keyword argument, this will now raise a warning whereas in the past it did + nothing. + """ + if len(kwargs) > 0: + warnings.warn( + f"`{fn_name}` does not support arguments {list(kwargs.keys())}. In " + "the future, this will become an error.", + DeprecationWarning, + ) + + def _optimize_acqf_all_features_fixed( *, bounds: Tensor, @@ -830,6 +848,7 @@ def optimize_acqf_mixed( "are currently not supported when `q > 1`. This is needed to " "compute the joint acquisition value." ) + _raise_deprecation_warning_if_kwargs("optimize_acqf_mixed", kwargs) if q == 1: ff_candidate_list, ff_acq_value_list = [], [] @@ -932,6 +951,7 @@ def optimize_acqf_discrete( ) if choices.numel() == 0: raise InputDataError("`choices` must be non-emtpy.") + _raise_deprecation_warning_if_kwargs("optimize_acqf_discrete", kwargs) choices_batched = choices.unsqueeze(-2) if q > 1: candidate_list, acq_value_list = [], [] @@ -1091,6 +1111,7 @@ def optimize_acqf_discrete_local_search( - a `q x d`-dim tensor of generated candidates. - an associated acquisition value. """ + _raise_deprecation_warning_if_kwargs("optimize_acqf_discrete_local_search", kwargs) candidate_list = [] base_X_pending = acq_function.X_pending if q > 1 else None base_X_avoid = X_avoid diff --git a/test/optim/test_optimize.py b/test/optim/test_optimize.py index 421467ef7c..5b8937e565 100644 --- a/test/optim/test_optimize.py +++ b/test/optim/test_optimize.py @@ -1394,7 +1394,6 @@ def test_optimize_acqf_discrete(self): mock_acq_function = SquaredAcquisitionFunction() mock_acq_function.set_X_pending(None) - # ensure proper raising of errors if no choices with self.assertRaisesRegex(InputDataError, "`choices` must be non-emtpy."): optimize_acqf_discrete( @@ -1404,6 +1403,17 @@ def test_optimize_acqf_discrete(self): ) choices = torch.rand(5, 2, **tkwargs) + + # warning for unsupported keyword arguments + with self.assertWarnsRegex( + DeprecationWarning, + r"`optimize_acqf_discrete` does not support arguments " + r"\['num_restarts'\]. In the future, this will become an error.", + ): + optimize_acqf_discrete( + acq_function=mock_acq_function, q=q, choices=choices, num_restarts=8 + ) + exp_acq_vals = mock_acq_function(choices) # test unique