Skip to content

Commit

Permalink
Construct MapMetrics by default
Browse files Browse the repository at this point in the history
Summary:
As titled. This should negate some logspam.

Also change MapKeyInfo fusion to consider nan == nan because previously MapKeyInfo(step, nan) fusing with itself would look like a conflict

Differential Revision: D67412730
  • Loading branch information
mpolson64 authored and facebook-github-bot committed Dec 18, 2024
1 parent c5e038a commit 4e9de3d
Show file tree
Hide file tree
Showing 3 changed files with 15 additions and 11 deletions.
5 changes: 4 additions & 1 deletion ax/core/map_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,10 @@ def from_multiple_map_data(
unique_map_key_infos = []
for mki in (mki for datum in data for mki in datum.map_key_infos):
if any(
mki.key == unique.key and mki.default_value != unique.default_value
mki.key == unique.key
and not np.isclose(
mki.default_value, unique.default_value, equal_nan=True
)
for unique in unique_map_key_infos
):
logger.warning(f"MapKeyInfo conflict for {mki.key}, eliding {mki}.")
Expand Down
8 changes: 4 additions & 4 deletions ax/preview/api/tests/test_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
from ax.core.experiment import Experiment
from ax.core.formatting_utils import DataType
from ax.core.map_data import MapData
from ax.core.metric import Metric
from ax.core.map_metric import MapMetric
from ax.core.objective import MultiObjective, Objective, ScalarizedObjective
from ax.core.optimization_config import OptimizationConfig
from ax.core.outcome_constraint import ComparisonOp, OutcomeConstraint
Expand Down Expand Up @@ -160,10 +160,10 @@ def test_configure_optimization(self) -> None:
self.assertEqual(
client._experiment.optimization_config,
OptimizationConfig(
objective=Objective(metric=Metric(name="ne"), minimize=True),
objective=Objective(metric=MapMetric(name="ne"), minimize=True),
outcome_constraints=[
OutcomeConstraint(
metric=Metric(name="qps"),
metric=MapMetric(name="qps"),
op=ComparisonOp.GEQ,
bound=0.0,
relative=False,
Expand Down Expand Up @@ -259,7 +259,7 @@ def test_configure_metric(self) -> None:
client.configure_optimization(
objective="foo",
)
client._experiment.add_tracking_metric(metric=Metric("custom"))
client._experiment.add_tracking_metric(metric=MapMetric("custom"))
client.configure_metrics(metrics=[custom_metric])

self.assertEqual(
Expand Down
13 changes: 7 additions & 6 deletions ax/preview/api/utils/instantiation/from_string.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@

from typing import Sequence

from ax.core.metric import Metric
from ax.core.map_metric import MapMetric

from ax.core.objective import MultiObjective, Objective, ScalarizedObjective
from ax.core.optimization_config import (
MultiObjectiveOptimizationConfig,
Expand Down Expand Up @@ -181,15 +182,15 @@ def parse_outcome_constraint(constraint_str: str) -> OutcomeConstraint:
term, coefficient = next(iter(constraint_dict.items()))

return OutcomeConstraint(
metric=Metric(name=term),
metric=MapMetric(name=term),
op=ComparisonOp.LEQ if coefficient > 0 else ComparisonOp.GEQ,
bound=bound / coefficient,
relative=is_relative,
)

names, coefficients = zip(*constraint_dict.items())
return ScalarizedOutcomeConstraint(
metrics=[Metric(name=name) for name in names],
metrics=[MapMetric(name=name) for name in names],
op=ComparisonOp.LEQ,
weights=[*coefficients],
bound=bound,
Expand All @@ -206,7 +207,7 @@ def _create_single_objective(expression: Expr) -> Objective:

# If the expression is a just a Symbol it represents a single metric objective
if isinstance(expression, Symbol):
return Objective(metric=Metric(name=str(expression.name)), minimize=False)
return Objective(metric=MapMetric(name=str(expression.name)), minimize=False)

# If the expression is a Mul it likely represents a single metric objective but
# some additional validation is required
Expand All @@ -221,13 +222,13 @@ def _create_single_objective(expression: Expr) -> Objective:
# the sign from the coefficient rather than its value
minimize = bool(expression.as_coefficient(symbol) < 0)

return Objective(metric=Metric(name=str(symbol)), minimize=minimize)
return Objective(metric=MapMetric(name=str(symbol)), minimize=minimize)

# If the expression is an Add it represents a scalarized objective
elif isinstance(expression, Add):
names, coefficients = zip(*expression.as_coefficients_dict().items())
return ScalarizedObjective(
metrics=[Metric(name=str(name)) for name in names],
metrics=[MapMetric(name=str(name)) for name in names],
weights=[float(coefficient) for coefficient in coefficients],
minimize=False,
)
Expand Down

0 comments on commit 4e9de3d

Please sign in to comment.