Skip to content

Commit

Permalink
fix X_observed check when constructing objective (#3444)
Browse files Browse the repository at this point in the history
Summary:
Pull Request resolved: #3444

This check is not needed for SampleReducingMCAcquisitionFunction and blocks generation when there is no X_baseline

Reviewed By: Balandat, SebastianAment

Differential Revision: D70446607

fbshipit-source-id: 12be60bb8e40f27df98a6c92163c8bc163a950e7
  • Loading branch information
sdaulton authored and facebook-github-bot committed Mar 3, 2025
1 parent b3c32a0 commit edbdff2
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 10 deletions.
10 changes: 10 additions & 0 deletions ax/models/tests/test_torch_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,16 @@ def test_get_botorch_objective(self, _) -> None:
)
self.assertIsInstance(obj, GenericMCObjective)
self.assertIsNone(tf)
# test no X_observed (e.g., if there are no feasible points) with qLogNEI
obj, tf = get_botorch_objective_and_transform(
botorch_acqf_class=qLogNoisyExpectedImprovement,
model=self.mock_botorch_model,
outcome_constraints=self.outcome_constraints,
objective_weights=self.objective_weights,
X_observed=None,
)
self.assertIsInstance(obj, GenericMCObjective)
self.assertIsNone(tf)

# By default, `ScalarizedPosteriorTransform` should be picked in absence of
# outcome constraints.
Expand Down
20 changes: 10 additions & 10 deletions ax/models/torch/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -464,10 +464,6 @@ def get_botorch_objective_and_transform(
# We are doing multi-objective optimization.
return _get_weighted_mo_objective(objective_weights=objective_weights), None
if outcome_constraints:
if X_observed is None:
raise UnsupportedError(
"X_observed is required to construct a constrained BoTorch objective."
)
# If there are outcome constraints, we use MC Acquisition functions.
obj_tf: Callable[[Tensor, Tensor | None], Tensor] = (
get_objective_weights_transform(objective_weights)
Expand All @@ -481,13 +477,17 @@ def objective(samples: Tensor, X: Tensor | None = None) -> Tensor:
# Acquisition object.
if issubclass(botorch_acqf_class, SampleReducingMCAcquisitionFunction):
return GenericMCObjective(objective=objective), None
else: # this is still used by KG
con_tfs = get_outcome_constraint_transforms(outcome_constraints)
inf_cost = get_infeasible_cost(X=X_observed, model=model, objective=obj_tf)
objective = ConstrainedMCObjective(
objective=objective, constraints=con_tfs or [], infeasible_cost=inf_cost
# this is still used by KG
if X_observed is None:
raise UnsupportedError(
"X_observed is required to construct a constrained BoTorch objective."
)
return objective, None
con_tfs = get_outcome_constraint_transforms(outcome_constraints)
inf_cost = get_infeasible_cost(X=X_observed, model=model, objective=obj_tf)
objective = ConstrainedMCObjective(
objective=objective, constraints=con_tfs or [], infeasible_cost=inf_cost
)
return objective, None
# Case of linear weights - use ScalarizedPosteriorTransform
transform = ScalarizedPosteriorTransform(weights=objective_weights)
return None, transform
Expand Down

0 comments on commit edbdff2

Please sign in to comment.