Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion flaml/tune/searcher/flow2.py
Original file line number Diff line number Diff line change
Expand Up @@ -674,5 +674,8 @@ def reach(self, other: Searcher) -> bool:
# unordered cat choice is hard to reach by chance
if config1[key] != config2.get(key):
return False
delta = np.array([incumbent1[key] - incumbent2.get(key, np.inf) for key in self._tunable_keys])
try:
delta = np.array([incumbent1[key] - incumbent2.get(key, np.inf) for key in self._tunable_keys])
except TypeError:
return False
return np.linalg.norm(delta) <= self.step
22 changes: 22 additions & 0 deletions test/tune/test_searcher.py
Original file line number Diff line number Diff line change
Expand Up @@ -345,5 +345,27 @@ def test_unresolved_search_space(caplog):
), "BlendSearch should not produce warning about unresolved search space"


def test_flow2_reach_mixed_type_incumbents():
"""Regression test for #903.

FLOW2.reach() must return False instead of raising TypeError when conditional choice parameters lead to mixed-type incumbents.
"""
from flaml.tune.searcher.flow2 import FLOW2

f1 = FLOW2.__new__(FLOW2)
f1.best_config = {"x": 1.0}
f1.incumbent = {"x": 1.0}
f1._resource = None
f1._unordered_cat_hp = {}
f1._tunable_keys = ["x"]
f1.step = 0.5

f2 = FLOW2.__new__(FLOW2)
f2.best_config = {"x": "None"}
f2.incumbent = {"x": "None"}

assert f1.reach(f2) is False


if __name__ == "__main__":
test_unresolved_search_space(None)
Loading