Skip to content

Re-index TorchOptConfig.objective_thresholds from (n_outcomes,) to (n_objectives,) (#5018)#5018

Open
saitcakmak wants to merge 1 commit intofacebook:mainfrom
saitcakmak:export-D96391935
Open

Re-index TorchOptConfig.objective_thresholds from (n_outcomes,) to (n_objectives,) (#5018)#5018
saitcakmak wants to merge 1 commit intofacebook:mainfrom
saitcakmak:export-D96391935

Conversation

@saitcakmak
Copy link
Contributor

@saitcakmak saitcakmak commented Mar 13, 2026

Summary:

Re-index objective_thresholds in TorchOptConfig from (n_outcomes,) with NaN
for non-objective outcomes to (n_objectives,) or None. This is a prerequisite
for supporting ScalarizedObjective as a sub-objective of MultiObjective.

Key changes:

  • extract_objective_thresholds returns (n_objectives,) maximization-aligned
    array (sign-flipped for minimize objectives), or None for single-objective.
    Rewritten to use expression-based API (parse_objective_expression /
    extract_metric_weights_from_objective_expr) instead of deprecated
    MultiObjective.objectives / ScalarizedObjective class checks.
  • _untransform_objective_thresholds indexes by objective index and un-flips
    the sign when converting back to raw ObjectiveThreshold.bound.
  • Replaced get_weighted_mc_objective_and_objective_thresholds with
    get_weighted_mc_objective, which only returns the objective (thresholds
    no longer need transformation so callers use them directly).
  • infer_objective_thresholds returns (n_objectives,) maximization-aligned.
  • Removed objective_thresholds from SubsetModelData and subset_model
    (thresholds are per-objective, not per-outcome, so subsetting doesn't apply).
  • Simplified _objective_threshold_to_outcome_constraints and pruning logic.
  • Merged _full_objective_thresholds and _objective_thresholds into single
    _objective_thresholds in the Acquisition class.
  • Pass thresholds directly as ref_point to BoTorch input constructors (using
    the new ref_point parameter from D96473523), avoiding the need to convert
    back to outcome space.
  • Fixed Pyre type errors in test_acquisition.py for Optional[Tensor]
    return from Acquisition.objective_thresholds.

TRBO isolation (axoptics):

  • TRBO uses its own objective_weights and max_reference_point from
    constructor kwargs -- it does NOT use TorchOptConfig from gen().
    Its __init__ expects legacy format: (n_outcomes,) with raw bounds and
    NaN for non-objectives, then handles maximization alignment internally.
  • Replaced the extract_objective_thresholds call in axoptics
    _mk_TRBO_generation_strategy with inline legacy logic that produces the
    (n_outcomes,) raw-bounds format TRBO expects, keeping TRBO isolated from
    the new (n_objectives,) format.
  • Added comments to trbo.py documenting the legacy input contract and
    future refactoring TODO.

Differential Revision: D96391935

@meta-cla meta-cla bot added the CLA Signed Do not delete this pull request or issue due to inactivity. label Mar 13, 2026
@meta-codesync
Copy link

meta-codesync bot commented Mar 13, 2026

@saitcakmak has exported this pull request. If you are a Meta employee, you can view the originating Diff in D96391935.

@codecov-commenter
Copy link

codecov-commenter commented Mar 18, 2026

Codecov Report

❌ Patch coverage is 97.33333% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 96.28%. Comparing base (ef72a7d) to head (90cf05d).

Files with missing lines Patch % Lines
ax/adapter/adapter_utils.py 94.73% 1 Missing ⚠️
...erators/torch/botorch_modular/multi_acquisition.py 0.00% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #5018      +/-   ##
==========================================
- Coverage   96.29%   96.28%   -0.01%     
==========================================
  Files         611      611              
  Lines       67314    67270      -44     
==========================================
- Hits        64822    64773      -49     
- Misses       2492     2497       +5     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@meta-codesync meta-codesync bot changed the title Re-index TorchOptConfig.objective_thresholds from (n_outcomes,) to (n_objectives,) Re-index TorchOptConfig.objective_thresholds from (n_outcomes,) to (n_objectives,) (#5018) Mar 20, 2026
saitcakmak added a commit to saitcakmak/Ax that referenced this pull request Mar 20, 2026
…_objectives,) (facebook#5018)

Summary:

Re-index `objective_thresholds` in `TorchOptConfig` from `(n_outcomes,)` with NaN
for non-objective outcomes to `(n_objectives,)` or `None`. This is a prerequisite
for supporting `ScalarizedObjective` as a sub-objective of `MultiObjective`.

Key changes:
- `extract_objective_thresholds` returns `(n_objectives,)` maximization-aligned
  array (sign-flipped for minimize objectives), or `None` for single-objective.
  Rewritten to use expression-based API (`parse_objective_expression` /
  `extract_metric_weights_from_objective_expr`) instead of deprecated
  `MultiObjective.objectives` / `ScalarizedObjective` class checks.
- `_untransform_objective_thresholds` indexes by objective index and un-flips
  the sign when converting back to raw `ObjectiveThreshold.bound`.
- Replaced `get_weighted_mc_objective_and_objective_thresholds` with
  `get_weighted_mc_objective`, which only returns the objective (thresholds
  no longer need transformation so callers use them directly).
- `infer_objective_thresholds` returns `(n_objectives,)` maximization-aligned.
- Removed `objective_thresholds` from `SubsetModelData` and `subset_model`
  (thresholds are per-objective, not per-outcome, so subsetting doesn't apply).
- Simplified `_objective_threshold_to_outcome_constraints` and pruning logic.
- Merged `_full_objective_thresholds` and `_objective_thresholds` into single
  `_objective_thresholds` in the `Acquisition` class.
- Pass thresholds directly as `ref_point` to BoTorch input constructors (using
  the new `ref_point` parameter from D96473523), avoiding the need to convert
  back to outcome space.
- Fixed Pyre type errors in `test_acquisition.py` for `Optional[Tensor]`
  return from `Acquisition.objective_thresholds`.

TRBO isolation (axoptics):
- TRBO uses its own `objective_weights` and `max_reference_point` from
  constructor kwargs -- it does NOT use `TorchOptConfig` from `gen()`.
  Its `__init__` expects legacy format: `(n_outcomes,)` with raw bounds and
  NaN for non-objectives, then handles maximization alignment internally.
- Replaced the `extract_objective_thresholds` call in axoptics
  `_mk_TRBO_generation_strategy` with inline legacy logic that produces the
  `(n_outcomes,)` raw-bounds format TRBO expects, keeping TRBO isolated from
  the new `(n_objectives,)` format.
- Added comments to `trbo.py` documenting the legacy input contract and
  future refactoring TODO.

Differential Revision: D96391935
…_objectives,) (facebook#5018)

Summary:
Pull Request resolved: facebook#5018

Re-index `objective_thresholds` in `TorchOptConfig` from `(n_outcomes,)` with NaN
for non-objective outcomes to `(n_objectives,)` or `None`. This is a prerequisite
for supporting `ScalarizedObjective` as a sub-objective of `MultiObjective`.

Key changes:
- `extract_objective_thresholds` returns `(n_objectives,)` maximization-aligned
  array (sign-flipped for minimize objectives), or `None` for single-objective.
  Rewritten to use expression-based API (`parse_objective_expression` /
  `extract_metric_weights_from_objective_expr`) instead of deprecated
  `MultiObjective.objectives` / `ScalarizedObjective` class checks.
- `_untransform_objective_thresholds` indexes by objective index and un-flips
  the sign when converting back to raw `ObjectiveThreshold.bound`.
- Replaced `get_weighted_mc_objective_and_objective_thresholds` with
  `get_weighted_mc_objective`, which only returns the objective (thresholds
  no longer need transformation so callers use them directly).
- `infer_objective_thresholds` returns `(n_objectives,)` maximization-aligned.
- Removed `objective_thresholds` from `SubsetModelData` and `subset_model`
  (thresholds are per-objective, not per-outcome, so subsetting doesn't apply).
- Simplified `_objective_threshold_to_outcome_constraints` and pruning logic.
- Merged `_full_objective_thresholds` and `_objective_thresholds` into single
  `_objective_thresholds` in the `Acquisition` class.
- Pass thresholds directly as `ref_point` to BoTorch input constructors (using
  the new `ref_point` parameter from D96473523), avoiding the need to convert
  back to outcome space.
- Fixed Pyre type errors in `test_acquisition.py` for `Optional[Tensor]`
  return from `Acquisition.objective_thresholds`.

TRBO isolation (axoptics):
- TRBO uses its own `objective_weights` and `max_reference_point` from
  constructor kwargs -- it does NOT use `TorchOptConfig` from `gen()`.
  Its `__init__` expects legacy format: `(n_outcomes,)` with raw bounds and
  NaN for non-objectives, then handles maximization alignment internally.
- Replaced the `extract_objective_thresholds` call in axoptics
  `_mk_TRBO_generation_strategy` with inline legacy logic that produces the
  `(n_outcomes,)` raw-bounds format TRBO expects, keeping TRBO isolated from
  the new `(n_objectives,)` format.
- Added comments to `trbo.py` documenting the legacy input contract and
  future refactoring TODO.

Differential Revision: D96391935
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLA Signed Do not delete this pull request or issue due to inactivity. fb-exported meta-exported

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants