Skip to content

Commit

Permalink
Tunable fixups (microsoft#623)
Browse files Browse the repository at this point in the history
Improvements on microsoft#549 

- Handles the case where the default for a tunable is `False` (else it
wouldn't be converted to a `str`).
- Adds more details during debug and error output to make
troubleshooting easier
bpkroth authored Jan 3, 2024

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
1 parent e02c036 commit 564df0e
Showing 2 changed files with 21 additions and 10 deletions.
Original file line number Diff line number Diff line change
@@ -28,6 +28,11 @@ def test_tunable_categorical_types() -> None:
"values": [True, False],
"default": True,
},
"false-bool-cat": {
"type": "categorical",
"values": [True, False],
"default": False,
},
"str-cat": {
"type": "categorical",
"values": ["a", "b", "c"],
@@ -47,6 +52,10 @@ def test_tunable_categorical_types() -> None:
assert isinstance(bool_cat.value, str)
assert bool_cat.value == "True"

false_bool_cat, _ = tunable_groups.get_tunable("false-bool-cat")
assert isinstance(false_bool_cat.value, str)
assert false_bool_cat.value == "False"

str_cat, _ = tunable_groups.get_tunable("str-cat")
assert isinstance(str_cat.value, str)
assert str_cat.value == "a"
22 changes: 12 additions & 10 deletions mlos_bench/mlos_bench/tunables/tunable.py
Original file line number Diff line number Diff line change
@@ -68,7 +68,7 @@ def __init__(self, name: str, config: TunableDict):
self._default = self.dtype(self._default) if self._default is not None else self._default
self._values = config.get("values")
if self._values:
self._values = [str(v) if v else v for v in self._values]
self._values = [str(v) if v is not None else v for v in self._values]
self._meta: Dict[str, Any] = config.get("meta", {})
self._range: Optional[Union[Tuple[int, int], Tuple[float, float]]] = None
config_range = config.get("range")
@@ -87,22 +87,22 @@ def _sanity_check(self) -> None:
"""
if self.is_categorical:
if not (self._values and isinstance(self._values, collections.abc.Iterable)):
raise ValueError("Must specify values for the categorical type")
raise ValueError(f"Must specify values for the categorical type tunable {self}")
if self._range is not None:
raise ValueError("Range must be None for the categorical type")
raise ValueError(f"Range must be None for the categorical type tunable {self}")
if len(set(self._values)) != len(self._values):
raise ValueError("Values must be unique for the categorical type")
raise ValueError(f"Values must be unique for the categorical type tunable {self}")
if self._special is not None:
raise ValueError("Special values must be None for the categorical type")
raise ValueError(f"Special values must be None for the categorical type tunable {self}")
elif self.is_numerical:
if self._values is not None:
raise ValueError("Values must be None for the numerical type")
raise ValueError(f"Values must be None for the numerical type tunable {self}")
if not self._range or len(self._range) != 2 or self._range[0] >= self._range[1]:
raise ValueError(f"Invalid range: {self._range}")
raise ValueError(f"Invalid range for tunable {self}: {self._range}")
else:
raise ValueError(f"Invalid parameter type: {self._type}")
raise ValueError(f"Invalid parameter type for tunable {self}: {self._type}")
if not self.is_valid(self.default):
raise ValueError(f"Invalid default value: {self.default}")
raise ValueError(f"Invalid default value for tunable {self}: {self.default}")

def __repr__(self) -> str:
"""
@@ -113,7 +113,9 @@ def __repr__(self) -> str:
string : str
A human-readable version of the Tunable.
"""
return f"{self._name}={self._current_value}"
if self.is_categorical:
return f"{self._name}[{self._type}]({self._values}:{self._default})={self._current_value}"
return f"{self._name}[{self._type}]({self._range}:{self._default})={self._current_value}"

def __eq__(self, other: object) -> bool:
"""

0 comments on commit 564df0e

Please sign in to comment.