From 3883fc2185fe397b97b12019c74d6e93ea6969d8 Mon Sep 17 00:00:00 2001 From: Setepenre Date: Wed, 16 Mar 2022 13:28:51 -0400 Subject: [PATCH 01/45] Add configspace conversion --- .../algo/{space.py => space/__init__.py} | 47 +++++ src/orion/algo/space/configspace.py | 173 ++++++++++++++++++ tests/unittests/algo/test_configspace.py | 39 ++++ 3 files changed, 259 insertions(+) rename src/orion/algo/{space.py => space/__init__.py} (97%) create mode 100644 src/orion/algo/space/configspace.py create mode 100644 tests/unittests/algo/test_configspace.py diff --git a/src/orion/algo/space.py b/src/orion/algo/space/__init__.py similarity index 97% rename from src/orion/algo/space.py rename to src/orion/algo/space/__init__.py index 31ce2192a..f3171cc04 100644 --- a/src/orion/algo/space.py +++ b/src/orion/algo/space/__init__.py @@ -67,6 +67,49 @@ def __repr__(self): return "..." + +def _to_snake_case(name): + """Transform a class name ``MyClassName`` to snakecase ``my_class_name``""" + frags = [] + + frag = [] + for c in name: + if c.isupper() and frag: + frags.append(''.join(frag).lower()) + frag = [] + + frag.append(c) + + if frag: + frags.append(''.join(frag).lower()) + + return '_'.join(frags) + + + +class Visitor: + def visit(self, dim): + return dim.visit(self) + + def dimension(self, dim): + pass + + def real(self, dim): + pass + + def integer(self, dim): + pass + + def categorical(self, dim): + pass + + def fidelity(self, dim): + pass + + def space(self, dim): + pass + + class Dimension: """Base class for search space dimensions. @@ -337,6 +380,10 @@ def cardinality(self): """ return numpy.inf + def visit(self, visitor): + """Returns a configspace dimension""" + return getattr(visitor, _to_snake_case(self.__class__.__name__))(self) + def _is_numeric_array(point): """Test whether a point is numerical object or an array containing only numerical objects""" diff --git a/src/orion/algo/space/configspace.py b/src/orion/algo/space/configspace.py new file mode 100644 index 000000000..a15221d8a --- /dev/null +++ b/src/orion/algo/space/configspace.py @@ -0,0 +1,173 @@ +try: + import ConfigSpace as cs + import ConfigSpace.hyperparameters as csh + + IMPORT_ERROR = None +except ImportError as err: + IMPORT_ERROR = err + +from cmath import log10 +from orion.algo.space import Visitor, Space, Real, Integer, Categorical + + +def _qantization(dim): + """Convert precision to the quantization factor""" + if dim.precision: + return 10 ** (- dim.precision) + return None + + +class ToConfigSpace(Visitor): + """Convert an Orion space into a configspace""" + + def __init__(self) -> None: + if IMPORT_ERROR is not None: + raise IMPORT_ERROR + + def dimension(self, dim): + """Raise an error if the visitor is called on an abstract class""" + raise NotImplementedError() + + def real(self, dim): + """Convert a real dimension into a configspace equivalent""" + if dim.prior_name == ('loguniform', 'reciprocal', 'uniform'): + a, b = dim._args + + return csh.UniformFloatHyperparameter( + name=dim.name, + lower=a, + upper=b, + default_value=dim.default_value, + q=_qantization(dim), + log=dim.prior_name == 'reciprocal', + ) + + if dim.prior_name in ('normal', 'norm'): + a, b = dim._args + + return csh.NormalFloatHyperparameter( + name=dim.name, + mu=a, + sigma=b, + default_value=dim.default_value, + q=_qantization(dim), + log=False, + lower=dim.low if hasattr(dim, 'low') else None, + upper=dim.high if hasattr(dim, 'high') else None, + ) + + return + + def integer(self, dim): + """Convert a integer dimension into a configspace equivalent""" + if dim.prior_name == ('int_uniform', 'int_reciprocal'): + a, b = dim._args + + return csh.UniformIntegerHyperparameter( + name=dim.name, + lower=a, + upper=b, + default_value=dim.default_value, + q=_qantization(dim), + log=dim.prior_name == 'int_reciprocal', + ) + + if dim.prior_name in ('norm', 'normal'): + a, b = dim._args + + return csh.NormalIntegerHyperparameter( + name=dim.name, + mu=a, + sigma=b, + default_value=dim.default_value, + q=_qantization(dim), + log=False, + lower=dim.low if hasattr(dim, 'low') else None, + upper=dim.high if hasattr(dim, 'high') else None + ) + + return None + + def categorical(self, dim): + """Convert a categorical dimension into a configspace equivalent""" + return csh.CategoricalHyperparameter( + name=dim.name, + choices=dim.categories, + weights=dim._probs, + ) + + def fidelity(self, dim): + """Ignores fidelity dimension as configspace does not have an equivalent""" + return None + + def space(self, space): + """Convert orion space to configspace""" + cspace = cs.ConfigurationSpace() + dims = [] + + for _, dim in space.items(): + cdim = self.visit(dim) + + if cdim: + dims.append(cdim) + + cspace.add_hyperparameters(dims) + return cspace + + +def toconfigspace(space): + """Convert orion space to configspace""" + conversion = ToConfigSpace() + return conversion.space(space) + + +def tooriondim(dim): + """Convert a config space dimension to an orion dimension""" + klass = Integer + args = [] + kwargs = dict( + # default_value=dim.default_value + ) + + if isinstance(dim, (csh.UniformFloatHyperparameter, csh.UniformIntegerHyperparameter)): + if isinstance(dim, csh.UniformFloatHyperparameter): + klass = Real + + dist = 'uniform' + args.append(dim.lower) + args.append(dim.upper) + # kwargs['prevision'] = log10(-dim.q) + + if dim.log: + dist = 'reciprocal' + + if isinstance(dim, (csh.NormalFloatHyperparameter, csh.NormalIntegerHyperparameter)): + if isinstance(dim, csh.NormalFloatHyperparameter): + klass = Real + + dist = 'norm' + args.append(dim.mu) + args.append(dim.sigma) + # kwargs['precision'] = log10(-dim.q) + + if dim.lower: + kwargs['low'] = dim.lower + kwargs['high'] = dim.upper + + if isinstance(dim, csh.CategoricalHyperparameter): + klass = Categorical + choices = {k: w for k, w in zip(dim.choices, dim.probabilities)} + return klass(dim.name, choices) + + return klass(dim.name, dist, *args, **kwargs) + + +def toorionspace(cspace): + """Convert from orion space to configspace""" + space = Space() + + for _, cdim in cspace.get_hyperparameters_dict().items(): + odim = tooriondim(cdim) + space.register(odim) + + return space diff --git a/tests/unittests/algo/test_configspace.py b/tests/unittests/algo/test_configspace.py new file mode 100644 index 000000000..f6b0b066e --- /dev/null +++ b/tests/unittests/algo/test_configspace.py @@ -0,0 +1,39 @@ +import pytest + + +from orion.algo.space import Space, Real, Integer, Categorical, Fidelity +from orion.algo.space.configspace import toconfigspace, toorionspace, IMPORT_ERROR + + +@pytest.mark.skipif(IMPORT_ERROR, reason="Running without ConfigSpace") +def test_orion_configspace(): + space = Space() + + space.register(Integer("r1i", "reciprocal", 1, 6)) + space.register(Integer("u1i", "uniform", -3, 6)) + space.register(Integer("u2i", "uniform", -3, 6)) + + space.register(Real("r1f", "reciprocal", 1, 6)) + space.register(Real("u1f", "uniform", -3, 6)) + space.register(Real("u2f", "uniform", -3, 6)) + + space.register(Categorical("c1", ("asdfa", 2))) + space.register(Categorical("c2", dict(a=0.2, b=0.8))) + space.register(Fidelity("f1", 1, 9, 3)) + + space.register(Real("n1", "norm", 0.9, 0.1, precision=6)) + space.register(Real("n2", "norm", 0.9, 0.1, precision=None)) + space.register(Real("n3", "norm", 0.9, 0.1)) + + newspace = toconfigspace(space) + + roundtrip = toorionspace(newspace) + + for k, original in space.items(): + if k == 'f1': + continue + + converted = roundtrip[k] + + assert type(original) == type(converted) + assert original == converted From e2dbae9cbdb95bb5675815a392c72d05d69ea079 Mon Sep 17 00:00:00 2001 From: Setepenre Date: Thu, 17 Mar 2022 12:49:45 -0400 Subject: [PATCH 02/45] Add precision --- src/orion/algo/space/__init__.py | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/src/orion/algo/space/__init__.py b/src/orion/algo/space/__init__.py index f3171cc04..50d9afb67 100644 --- a/src/orion/algo/space/__init__.py +++ b/src/orion/algo/space/__init__.py @@ -31,6 +31,7 @@ import copy import logging import numbers +from typing import Generic, TypeVar import numpy from scipy.stats import distributions @@ -67,7 +68,6 @@ def __repr__(self): return "..." - def _to_snake_case(name): """Transform a class name ``MyClassName`` to snakecase ``my_class_name``""" frags = [] @@ -75,38 +75,41 @@ def _to_snake_case(name): frag = [] for c in name: if c.isupper() and frag: - frags.append(''.join(frag).lower()) + frags.append("".join(frag).lower()) frag = [] frag.append(c) if frag: - frags.append(''.join(frag).lower()) + frags.append("".join(frag).lower()) + + return "_".join(frags) - return '_'.join(frags) +T = TypeVar("T") +S = TypeVar("S") -class Visitor: - def visit(self, dim): +class Visitor(Generic[T, S]): + def visit(self, dim: "Dimension") -> T: return dim.visit(self) - def dimension(self, dim): + def dimension(self, dim: "Dimension") -> T: pass - def real(self, dim): + def real(self, dim: "Dimension") -> T: pass - def integer(self, dim): + def integer(self, dim: "Dimension") -> T: pass - def categorical(self, dim): + def categorical(self, dim: "Dimension") -> T: pass - def fidelity(self, dim): + def fidelity(self, dim: "Dimension") -> T: pass - def space(self, dim): + def space(self, dim: "Dimension") -> S: pass @@ -380,7 +383,7 @@ def cardinality(self): """ return numpy.inf - def visit(self, visitor): + def visit(self, visitor: Visitor[T, S]) -> Any: """Returns a configspace dimension""" return getattr(visitor, _to_snake_case(self.__class__.__name__))(self) From fa2663dc2dc7802ebd95ed43664e1d68d258e4cc Mon Sep 17 00:00:00 2001 From: Setepenre Date: Thu, 17 Mar 2022 12:52:14 -0400 Subject: [PATCH 03/45] Isort tweak --- src/orion/algo/space/__init__.py | 6 +- src/orion/algo/space/configspace.py | 126 ++++++++++++++--------- tests/unittests/algo/test_configspace.py | 7 +- 3 files changed, 82 insertions(+), 57 deletions(-) diff --git a/src/orion/algo/space/__init__.py b/src/orion/algo/space/__init__.py index 50d9afb67..576c07519 100644 --- a/src/orion/algo/space/__init__.py +++ b/src/orion/algo/space/__init__.py @@ -68,7 +68,7 @@ def __repr__(self): return "..." -def _to_snake_case(name): +def _to_snake_case(name: str) -> str: """Transform a class name ``MyClassName`` to snakecase ``my_class_name``""" frags = [] @@ -383,8 +383,8 @@ def cardinality(self): """ return numpy.inf - def visit(self, visitor: Visitor[T, S]) -> Any: - """Returns a configspace dimension""" + def visit(self, visitor: Visitor[T, S]) -> T: + """Execute a visitor on the given dimension""" return getattr(visitor, _to_snake_case(self.__class__.__name__))(self) diff --git a/src/orion/algo/space/configspace.py b/src/orion/algo/space/configspace.py index a15221d8a..2e3f3c94e 100644 --- a/src/orion/algo/space/configspace.py +++ b/src/orion/algo/space/configspace.py @@ -1,108 +1,130 @@ +from math import log10 +from typing import Optional + +from orion.algo.space import Categorical, Dimension, Integer, Real, Space, Visitor + try: - import ConfigSpace as cs - import ConfigSpace.hyperparameters as csh + from ConfigSpace import ConfigurationSpace + from ConfigSpace.hyperparameters import ( + CategoricalHyperparameter, + FloatHyperparameter, + Hyperparameter, + IntegerHyperparameter, + NormalFloatHyperparameter, + NormalIntegerHyperparameter, + UniformFloatHyperparameter, + UniformIntegerHyperparameter, + ) IMPORT_ERROR = None + except ImportError as err: IMPORT_ERROR = err -from cmath import log10 -from orion.algo.space import Visitor, Space, Real, Integer, Categorical + IntegerHyperparameter = object() + FloatHyperparameter = object() + ConfigurationSpace = object() + Hyperparameter = object() + UniformFloatHyperparameter = object() + NormalFloatHyperparameter = object() + UniformIntegerHyperparameter = object() + NormalIntegerHyperparameter = object() + CategoricalHyperparamete = object() -def _qantization(dim): +def _qantization(dim: Dimension) -> float: """Convert precision to the quantization factor""" if dim.precision: - return 10 ** (- dim.precision) + return 10 ** (-dim.precision) return None -class ToConfigSpace(Visitor): +class ToConfigSpace(Visitor[Optional[Hyperparameter], ConfigurationSpace]): """Convert an Orion space into a configspace""" def __init__(self) -> None: if IMPORT_ERROR is not None: raise IMPORT_ERROR - def dimension(self, dim): + def dimension(self, dim: Dimension) -> None: """Raise an error if the visitor is called on an abstract class""" raise NotImplementedError() - def real(self, dim): + def real(self, dim: Dimension) -> Optional[FloatHyperparameter]: """Convert a real dimension into a configspace equivalent""" - if dim.prior_name == ('loguniform', 'reciprocal', 'uniform'): + if dim.prior_name == ("reciprocal", "uniform"): a, b = dim._args - return csh.UniformFloatHyperparameter( + return UniformFloatHyperparameter( name=dim.name, lower=a, upper=b, default_value=dim.default_value, q=_qantization(dim), - log=dim.prior_name == 'reciprocal', + log=dim.prior_name == "reciprocal", ) - if dim.prior_name in ('normal', 'norm'): + if dim.prior_name in ("normal", "norm"): a, b = dim._args - return csh.NormalFloatHyperparameter( + return NormalFloatHyperparameter( name=dim.name, mu=a, sigma=b, default_value=dim.default_value, q=_qantization(dim), log=False, - lower=dim.low if hasattr(dim, 'low') else None, - upper=dim.high if hasattr(dim, 'high') else None, + lower=dim.low if hasattr(dim, "low") else None, + upper=dim.high if hasattr(dim, "high") else None, ) return - def integer(self, dim): + def integer(self, dim: Dimension) -> Optional[IntegerHyperparameter]: """Convert a integer dimension into a configspace equivalent""" - if dim.prior_name == ('int_uniform', 'int_reciprocal'): + if dim.prior_name == ("int_uniform", "int_reciprocal"): a, b = dim._args - return csh.UniformIntegerHyperparameter( + return UniformIntegerHyperparameter( name=dim.name, lower=a, upper=b, default_value=dim.default_value, q=_qantization(dim), - log=dim.prior_name == 'int_reciprocal', + log=dim.prior_name == "int_reciprocal", ) - if dim.prior_name in ('norm', 'normal'): + if dim.prior_name in ("norm", "normal"): a, b = dim._args - return csh.NormalIntegerHyperparameter( + return NormalIntegerHyperparameter( name=dim.name, mu=a, sigma=b, default_value=dim.default_value, q=_qantization(dim), log=False, - lower=dim.low if hasattr(dim, 'low') else None, - upper=dim.high if hasattr(dim, 'high') else None + lower=dim.low if hasattr(dim, "low") else None, + upper=dim.high if hasattr(dim, "high") else None, ) return None - def categorical(self, dim): + def categorical(self, dim: Dimension) -> Optional[CategoricalHyperparameter]: """Convert a categorical dimension into a configspace equivalent""" - return csh.CategoricalHyperparameter( + return CategoricalHyperparameter( name=dim.name, choices=dim.categories, weights=dim._probs, ) - def fidelity(self, dim): + def fidelity(self, dim: Dimension) -> None: """Ignores fidelity dimension as configspace does not have an equivalent""" return None - def space(self, space): + def space(self, space: Space) -> ConfigurationSpace: """Convert orion space to configspace""" - cspace = cs.ConfigurationSpace() + cspace = ConfigurationSpace() dims = [] for _, dim in space.items(): @@ -110,59 +132,63 @@ def space(self, space): if cdim: dims.append(cdim) + else: + print(dim) cspace.add_hyperparameters(dims) return cspace -def toconfigspace(space): +def toconfigspace(space: Space) -> ConfigurationSpace: """Convert orion space to configspace""" conversion = ToConfigSpace() return conversion.space(space) -def tooriondim(dim): - """Convert a config space dimension to an orion dimension""" +def tooriondim(dim: Hyperparameter) -> Dimension: + """Convert a config space hyperparameter to an orion dimension""" + + if isinstance(dim, CategoricalHyperparameter): + choices = {k: w for k, w in zip(dim.choices, dim.probabilities)} + return Categorical(dim.name, choices) + klass = Integer args = [] kwargs = dict( # default_value=dim.default_value ) - if isinstance(dim, (csh.UniformFloatHyperparameter, csh.UniformIntegerHyperparameter)): - if isinstance(dim, csh.UniformFloatHyperparameter): + if isinstance(dim, (UniformFloatHyperparameter, UniformIntegerHyperparameter)): + if isinstance(dim, UniformFloatHyperparameter): klass = Real + else: + kwargs["precision"] = int(-log10(dim.q)) if dim.q else 4 - dist = 'uniform' + dist = "uniform" args.append(dim.lower) - args.append(dim.upper) - # kwargs['prevision'] = log10(-dim.q) + args.apend(dim.upper) if dim.log: - dist = 'reciprocal' + dist = "reciprocal" - if isinstance(dim, (csh.NormalFloatHyperparameter, csh.NormalIntegerHyperparameter)): - if isinstance(dim, csh.NormalFloatHyperparameter): + if isinstance(dim, (NormalFloatHyperparameter, NormalIntegerHyperparameter)): + if isinstance(dim, NormalFloatHyperparameter): klass = Real + else: + kwargs["precision"] = int(-log10(dim.q)) if dim.q else 4 - dist = 'norm' + dist = "norm" args.append(dim.mu) args.append(dim.sigma) - # kwargs['precision'] = log10(-dim.q) if dim.lower: - kwargs['low'] = dim.lower - kwargs['high'] = dim.upper - - if isinstance(dim, csh.CategoricalHyperparameter): - klass = Categorical - choices = {k: w for k, w in zip(dim.choices, dim.probabilities)} - return klass(dim.name, choices) + kwargs["low"] = dim.lower + kwargs["high"] = dim.upper return klass(dim.name, dist, *args, **kwargs) -def toorionspace(cspace): +def toorionspace(cspace: ConfigurationSpace) -> Space: """Convert from orion space to configspace""" space = Space() diff --git a/tests/unittests/algo/test_configspace.py b/tests/unittests/algo/test_configspace.py index f6b0b066e..a6f130613 100644 --- a/tests/unittests/algo/test_configspace.py +++ b/tests/unittests/algo/test_configspace.py @@ -1,8 +1,7 @@ import pytest - -from orion.algo.space import Space, Real, Integer, Categorical, Fidelity -from orion.algo.space.configspace import toconfigspace, toorionspace, IMPORT_ERROR +from orion.algo.space import Categorical, Fidelity, Integer, Real, Space +from orion.algo.space.configspace import IMPORT_ERROR, toconfigspace, toorionspace @pytest.mark.skipif(IMPORT_ERROR, reason="Running without ConfigSpace") @@ -30,7 +29,7 @@ def test_orion_configspace(): roundtrip = toorionspace(newspace) for k, original in space.items(): - if k == 'f1': + if k == "f1": continue converted = roundtrip[k] From 4c6811dbc9e18ee4d339dc3ea7885d233a7f7cfe Mon Sep 17 00:00:00 2001 From: Setepenre Date: Thu, 17 Mar 2022 13:00:35 -0400 Subject: [PATCH 04/45] Remove S type from visitor --- src/orion/algo/space/__init__.py | 8 ++------ src/orion/algo/space/configspace.py | 6 ++++-- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/src/orion/algo/space/__init__.py b/src/orion/algo/space/__init__.py index 576c07519..89c49ba47 100644 --- a/src/orion/algo/space/__init__.py +++ b/src/orion/algo/space/__init__.py @@ -87,10 +87,9 @@ def _to_snake_case(name: str) -> str: T = TypeVar("T") -S = TypeVar("S") -class Visitor(Generic[T, S]): +class Visitor(Generic[T]): def visit(self, dim: "Dimension") -> T: return dim.visit(self) @@ -109,9 +108,6 @@ def categorical(self, dim: "Dimension") -> T: def fidelity(self, dim: "Dimension") -> T: pass - def space(self, dim: "Dimension") -> S: - pass - class Dimension: """Base class for search space dimensions. @@ -383,7 +379,7 @@ def cardinality(self): """ return numpy.inf - def visit(self, visitor: Visitor[T, S]) -> T: + def visit(self, visitor: Visitor[T]) -> T: """Execute a visitor on the given dimension""" return getattr(visitor, _to_snake_case(self.__class__.__name__))(self) diff --git a/src/orion/algo/space/configspace.py b/src/orion/algo/space/configspace.py index 2e3f3c94e..40ba00d83 100644 --- a/src/orion/algo/space/configspace.py +++ b/src/orion/algo/space/configspace.py @@ -39,7 +39,7 @@ def _qantization(dim: Dimension) -> float: return None -class ToConfigSpace(Visitor[Optional[Hyperparameter], ConfigurationSpace]): +class ToConfigSpace(Visitor[Optional[Hyperparameter]]): """Convert an Orion space into a configspace""" def __init__(self) -> None: @@ -155,7 +155,9 @@ def tooriondim(dim: Hyperparameter) -> Dimension: klass = Integer args = [] kwargs = dict( - # default_value=dim.default_value + # NOTE: Config space always has a config value + # so orion-space would get it as well + default_value=dim.default_value ) if isinstance(dim, (UniformFloatHyperparameter, UniformIntegerHyperparameter)): From 442c95e0f52d0efa565ac6b3b63964f4368d5c1e Mon Sep 17 00:00:00 2001 From: Setepenre Date: Thu, 17 Mar 2022 13:41:27 -0400 Subject: [PATCH 05/45] Fix typo --- src/orion/algo/space/configspace.py | 25 +++++++++++++++++------- tests/unittests/algo/test_configspace.py | 1 + 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/src/orion/algo/space/configspace.py b/src/orion/algo/space/configspace.py index 40ba00d83..7f459d648 100644 --- a/src/orion/algo/space/configspace.py +++ b/src/orion/algo/space/configspace.py @@ -52,7 +52,7 @@ def dimension(self, dim: Dimension) -> None: def real(self, dim: Dimension) -> Optional[FloatHyperparameter]: """Convert a real dimension into a configspace equivalent""" - if dim.prior_name == ("reciprocal", "uniform"): + if dim.prior_name in ("reciprocal", "uniform"): a, b = dim._args return UniformFloatHyperparameter( @@ -82,7 +82,7 @@ def real(self, dim: Dimension) -> Optional[FloatHyperparameter]: def integer(self, dim: Dimension) -> Optional[IntegerHyperparameter]: """Convert a integer dimension into a configspace equivalent""" - if dim.prior_name == ("int_uniform", "int_reciprocal"): + if dim.prior_name in ("int_uniform", "int_reciprocal"): a, b = dim._args return UniformIntegerHyperparameter( @@ -132,15 +132,20 @@ def space(self, space: Space) -> ConfigurationSpace: if cdim: dims.append(cdim) - else: - print(dim) cspace.add_hyperparameters(dims) return cspace def toconfigspace(space: Space) -> ConfigurationSpace: - """Convert orion space to configspace""" + """Convert orion space to configspace + + Notes + ----- + ``ConfigurationSpace`` will set its own default values + if not set inside ``Space`` + + """ conversion = ToConfigSpace() return conversion.space(space) @@ -168,7 +173,7 @@ def tooriondim(dim: Hyperparameter) -> Dimension: dist = "uniform" args.append(dim.lower) - args.apend(dim.upper) + args.append(dim.upper) if dim.log: dist = "reciprocal" @@ -191,7 +196,13 @@ def tooriondim(dim: Hyperparameter) -> Dimension: def toorionspace(cspace: ConfigurationSpace) -> Space: - """Convert from orion space to configspace""" + """Convert from orion space to configspace + + Notes + ----- + ``ConfigurationSpace`` will set default values for each dimensions of ``Space`` + + """ space = Space() for _, cdim in cspace.get_hyperparameters_dict().items(): diff --git a/tests/unittests/algo/test_configspace.py b/tests/unittests/algo/test_configspace.py index a6f130613..994399668 100644 --- a/tests/unittests/algo/test_configspace.py +++ b/tests/unittests/algo/test_configspace.py @@ -34,5 +34,6 @@ def test_orion_configspace(): converted = roundtrip[k] + converted._default_value = None assert type(original) == type(converted) assert original == converted From 061708d21e5f4495a42d1bdd76776403fbe7c47d Mon Sep 17 00:00:00 2001 From: Setepenre Date: Thu, 17 Mar 2022 13:44:05 -0400 Subject: [PATCH 06/45] Add default_value case --- tests/unittests/algo/test_configspace.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/tests/unittests/algo/test_configspace.py b/tests/unittests/algo/test_configspace.py index 994399668..c335fd4cd 100644 --- a/tests/unittests/algo/test_configspace.py +++ b/tests/unittests/algo/test_configspace.py @@ -11,6 +11,7 @@ def test_orion_configspace(): space.register(Integer("r1i", "reciprocal", 1, 6)) space.register(Integer("u1i", "uniform", -3, 6)) space.register(Integer("u2i", "uniform", -3, 6)) + space.register(Integer("u3i", "uniform", -3, 6, default_value=2)) space.register(Real("r1f", "reciprocal", 1, 6)) space.register(Real("u1f", "uniform", -3, 6)) @@ -34,6 +35,10 @@ def test_orion_configspace(): converted = roundtrip[k] - converted._default_value = None + # Orion space did not have default values + # but ConfigSpace always set them + if not original.default_value: + converted._default_value = None + assert type(original) == type(converted) assert original == converted From acd5a46b51fd4e659344fb63c894ff4c7127f9d7 Mon Sep 17 00:00:00 2001 From: Setepenre Date: Thu, 17 Mar 2022 13:49:21 -0400 Subject: [PATCH 07/45] Add ConfigSpace as an optional dependency --- setup.py | 1 + tests/unittests/algo/test_configspace.py | 1 + 2 files changed, 2 insertions(+) diff --git a/setup.py b/setup.py index 90eb194d9..346aafff0 100644 --- a/setup.py +++ b/setup.py @@ -32,6 +32,7 @@ "dask": ["dask[complete]"], "track": ["track @ git+https://github.com/Delaunay/track"], "profet": ["emukit", "GPy", "torch", "pybnn"], + "configspace": ["ConfigSpace"] } extras_require["all"] = list(set(sum(extras_require.values(), []))) diff --git a/tests/unittests/algo/test_configspace.py b/tests/unittests/algo/test_configspace.py index c335fd4cd..3dfe6f1fa 100644 --- a/tests/unittests/algo/test_configspace.py +++ b/tests/unittests/algo/test_configspace.py @@ -30,6 +30,7 @@ def test_orion_configspace(): roundtrip = toorionspace(newspace) for k, original in space.items(): + # ConfigSpace does not have a fidelity dimension if k == "f1": continue From 12c656bd0071d545c715905de9a89fec4a1c4d81 Mon Sep 17 00:00:00 2001 From: Setepenre Date: Fri, 18 Mar 2022 11:05:30 -0400 Subject: [PATCH 08/45] Add singledispatch to make to_orionspace work for any registered types --- src/orion/algo/space/__init__.py | 22 ++++++++++++++----- src/orion/algo/space/configspace.py | 28 ++++++++++++++++-------- tests/unittests/algo/test_configspace.py | 8 +++---- 3 files changed, 40 insertions(+), 18 deletions(-) diff --git a/src/orion/algo/space/__init__.py b/src/orion/algo/space/__init__.py index 89c49ba47..ed81a13d7 100644 --- a/src/orion/algo/space/__init__.py +++ b/src/orion/algo/space/__init__.py @@ -31,7 +31,8 @@ import copy import logging import numbers -from typing import Generic, TypeVar +from functools import singledispatch +from typing import Any, Generic, TypeVar import numpy from scipy.stats import distributions @@ -96,16 +97,16 @@ def visit(self, dim: "Dimension") -> T: def dimension(self, dim: "Dimension") -> T: pass - def real(self, dim: "Dimension") -> T: + def real(self, dim: "Real") -> T: pass - def integer(self, dim: "Dimension") -> T: + def integer(self, dim: "Integer") -> T: pass - def categorical(self, dim: "Dimension") -> T: + def categorical(self, dim: "Categorical") -> T: pass - def fidelity(self, dim: "Dimension") -> T: + def fidelity(self, dim: "Fidelity") -> T: pass @@ -1138,3 +1139,14 @@ def cardinality(self): for dim in self.values(): capacities *= dim.cardinality return capacities + + +@singledispatch +def to_orionspace(space: Any) -> Space: + """Convert a third party search space into an Orion compatible space + + Raises + ------ + NotImplementedError if no conversion was registered + """ + raise NotImplementedError() diff --git a/src/orion/algo/space/configspace.py b/src/orion/algo/space/configspace.py index 7f459d648..c6e253b71 100644 --- a/src/orion/algo/space/configspace.py +++ b/src/orion/algo/space/configspace.py @@ -1,7 +1,16 @@ from math import log10 from typing import Optional -from orion.algo.space import Categorical, Dimension, Integer, Real, Space, Visitor +from orion.algo.space import ( + Categorical, + Dimension, + Fidelity, + Integer, + Real, + Space, + Visitor, + to_orionspace, +) try: from ConfigSpace import ConfigurationSpace @@ -50,7 +59,7 @@ def dimension(self, dim: Dimension) -> None: """Raise an error if the visitor is called on an abstract class""" raise NotImplementedError() - def real(self, dim: Dimension) -> Optional[FloatHyperparameter]: + def real(self, dim: Real) -> Optional[FloatHyperparameter]: """Convert a real dimension into a configspace equivalent""" if dim.prior_name in ("reciprocal", "uniform"): a, b = dim._args @@ -80,7 +89,7 @@ def real(self, dim: Dimension) -> Optional[FloatHyperparameter]: return - def integer(self, dim: Dimension) -> Optional[IntegerHyperparameter]: + def integer(self, dim: Integer) -> Optional[IntegerHyperparameter]: """Convert a integer dimension into a configspace equivalent""" if dim.prior_name in ("int_uniform", "int_reciprocal"): a, b = dim._args @@ -110,7 +119,7 @@ def integer(self, dim: Dimension) -> Optional[IntegerHyperparameter]: return None - def categorical(self, dim: Dimension) -> Optional[CategoricalHyperparameter]: + def categorical(self, dim: Categorical) -> Optional[CategoricalHyperparameter]: """Convert a categorical dimension into a configspace equivalent""" return CategoricalHyperparameter( name=dim.name, @@ -118,7 +127,7 @@ def categorical(self, dim: Dimension) -> Optional[CategoricalHyperparameter]: weights=dim._probs, ) - def fidelity(self, dim: Dimension) -> None: + def fidelity(self, dim: Fidelity) -> None: """Ignores fidelity dimension as configspace does not have an equivalent""" return None @@ -137,7 +146,7 @@ def space(self, space: Space) -> ConfigurationSpace: return cspace -def toconfigspace(space: Space) -> ConfigurationSpace: +def to_configspace(space: Space) -> ConfigurationSpace: """Convert orion space to configspace Notes @@ -150,7 +159,7 @@ def toconfigspace(space: Space) -> ConfigurationSpace: return conversion.space(space) -def tooriondim(dim: Hyperparameter) -> Dimension: +def to_oriondim(dim: Hyperparameter) -> Dimension: """Convert a config space hyperparameter to an orion dimension""" if isinstance(dim, CategoricalHyperparameter): @@ -195,7 +204,8 @@ def tooriondim(dim: Hyperparameter) -> Dimension: return klass(dim.name, dist, *args, **kwargs) -def toorionspace(cspace: ConfigurationSpace) -> Space: +@to_orionspace.register +def configpsace_to_orionspace(cspace: ConfigurationSpace) -> Space: """Convert from orion space to configspace Notes @@ -206,7 +216,7 @@ def toorionspace(cspace: ConfigurationSpace) -> Space: space = Space() for _, cdim in cspace.get_hyperparameters_dict().items(): - odim = tooriondim(cdim) + odim = to_oriondim(cdim) space.register(odim) return space diff --git a/tests/unittests/algo/test_configspace.py b/tests/unittests/algo/test_configspace.py index 3dfe6f1fa..b0f7e4665 100644 --- a/tests/unittests/algo/test_configspace.py +++ b/tests/unittests/algo/test_configspace.py @@ -1,7 +1,7 @@ import pytest -from orion.algo.space import Categorical, Fidelity, Integer, Real, Space -from orion.algo.space.configspace import IMPORT_ERROR, toconfigspace, toorionspace +from orion.algo.space import Categorical, Fidelity, Integer, Real, Space, to_orionspace +from orion.algo.space.configspace import IMPORT_ERROR, to_configspace @pytest.mark.skipif(IMPORT_ERROR, reason="Running without ConfigSpace") @@ -25,9 +25,9 @@ def test_orion_configspace(): space.register(Real("n2", "norm", 0.9, 0.1, precision=None)) space.register(Real("n3", "norm", 0.9, 0.1)) - newspace = toconfigspace(space) + newspace = to_configspace(space) - roundtrip = toorionspace(newspace) + roundtrip = to_orionspace(newspace) for k, original in space.items(): # ConfigSpace does not have a fidelity dimension From 746970b5b5018edf377ba5cee4a1f98a465eedc2 Mon Sep 17 00:00:00 2001 From: Setepenre Date: Fri, 18 Mar 2022 11:26:33 -0400 Subject: [PATCH 09/45] Add docstrings --- src/orion/algo/space/__init__.py | 17 +++++++++++++++++ tests/unittests/algo/test_configspace.py | 1 + 2 files changed, 18 insertions(+) diff --git a/src/orion/algo/space/__init__.py b/src/orion/algo/space/__init__.py index ed81a13d7..68823354a 100644 --- a/src/orion/algo/space/__init__.py +++ b/src/orion/algo/space/__init__.py @@ -91,24 +91,41 @@ def _to_snake_case(name: str) -> str: class Visitor(Generic[T]): + """Visitor interface to iterate over an Orion search space. + This can be used to implement new features for ``orion.algo.space.Space`` + outside of Orion's code base. + + """ + def visit(self, dim: "Dimension") -> T: + """Make dimension call its handler""" return dim.visit(self) def dimension(self, dim: "Dimension") -> T: + """Called when the dimension does not have a decicated handler""" pass def real(self, dim: "Real") -> T: + """Called by real dimension""" pass def integer(self, dim: "Integer") -> T: + """Called by integer dimension""" pass def categorical(self, dim: "Categorical") -> T: + """Called by categorical dimension""" pass def fidelity(self, dim: "Fidelity") -> T: + """Called by fidelity dimension""" pass + def space(self, space: "Space") -> None: + """Iterate through a research space and visit each dimensions""" + for _, dim in space.items(): + self.visit(dim) + class Dimension: """Base class for search space dimensions. diff --git a/tests/unittests/algo/test_configspace.py b/tests/unittests/algo/test_configspace.py index b0f7e4665..ce4bee4bf 100644 --- a/tests/unittests/algo/test_configspace.py +++ b/tests/unittests/algo/test_configspace.py @@ -16,6 +16,7 @@ def test_orion_configspace(): space.register(Real("r1f", "reciprocal", 1, 6)) space.register(Real("u1f", "uniform", -3, 6)) space.register(Real("u2f", "uniform", -3, 6)) + space.register(Real("name.u2f", "uniform", -3, 6)) space.register(Categorical("c1", ("asdfa", 2))) space.register(Categorical("c2", dict(a=0.2, b=0.8))) From 3f77f710b0dedf4f5f3ad5ca2d6d6a30a5646ec7 Mon Sep 17 00:00:00 2001 From: Setepenre Date: Fri, 18 Mar 2022 11:52:14 -0400 Subject: [PATCH 10/45] - --- docs/requirements.txt | 1 + docs/src/conf.py | 1 + 2 files changed, 2 insertions(+) diff --git a/docs/requirements.txt b/docs/requirements.txt index 0555874f0..38bd1e244 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -3,6 +3,7 @@ sphinx_rtd_theme sphinxcontrib.httpdomain sphinx-autoapi sphinx_gallery +sphinx-autodoc-typehints numpydoc plotly matplotlib diff --git a/docs/src/conf.py b/docs/src/conf.py index e1b336760..6673024b4 100644 --- a/docs/src/conf.py +++ b/docs/src/conf.py @@ -55,6 +55,7 @@ "sphinx.ext.todo", "sphinx.ext.viewcode", "sphinx.ext.intersphinx", + "sphinx_autodoc_typehints", ] ) From 674c84ea76f3a63ecbbd025f4a6b96959c14ad1b Mon Sep 17 00:00:00 2001 From: Setepenre Date: Fri, 18 Mar 2022 11:56:59 -0400 Subject: [PATCH 11/45] Document typevar --- docs/requirements.txt | 1 - docs/src/code/algo/space.rst | 1 + docs/src/conf.py | 1 - src/orion/algo/space/__init__.py | 29 +++++++++++++---------------- src/orion/algo/space/configspace.py | 2 +- 5 files changed, 15 insertions(+), 19 deletions(-) diff --git a/docs/requirements.txt b/docs/requirements.txt index 38bd1e244..0555874f0 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -3,7 +3,6 @@ sphinx_rtd_theme sphinxcontrib.httpdomain sphinx-autoapi sphinx_gallery -sphinx-autodoc-typehints numpydoc plotly matplotlib diff --git a/docs/src/code/algo/space.rst b/docs/src/code/algo/space.rst index 7e0cd1595..4584cfb4a 100644 --- a/docs/src/code/algo/space.rst +++ b/docs/src/code/algo/space.rst @@ -1,5 +1,6 @@ Space search ============ + .. automodule:: orion.algo.space :members: diff --git a/docs/src/conf.py b/docs/src/conf.py index 6673024b4..e1b336760 100644 --- a/docs/src/conf.py +++ b/docs/src/conf.py @@ -55,7 +55,6 @@ "sphinx.ext.todo", "sphinx.ext.viewcode", "sphinx.ext.intersphinx", - "sphinx_autodoc_typehints", ] ) diff --git a/src/orion/algo/space/__init__.py b/src/orion/algo/space/__init__.py index 68823354a..edf04e82e 100644 --- a/src/orion/algo/space/__init__.py +++ b/src/orion/algo/space/__init__.py @@ -32,7 +32,7 @@ import logging import numbers from functools import singledispatch -from typing import Any, Generic, TypeVar +from typing import Any import numpy from scipy.stats import distributions @@ -87,39 +87,36 @@ def _to_snake_case(name: str) -> str: return "_".join(frags) -T = TypeVar("T") - - -class Visitor(Generic[T]): +class Visitor: """Visitor interface to iterate over an Orion search space. This can be used to implement new features for ``orion.algo.space.Space`` outside of Orion's code base. """ - def visit(self, dim: "Dimension") -> T: + def visit(self, dim: "Dimension") -> Any: """Make dimension call its handler""" return dim.visit(self) - def dimension(self, dim: "Dimension") -> T: + def dimension(self, dim: "Dimension") -> Any: """Called when the dimension does not have a decicated handler""" - pass + raise NotImplementedError() - def real(self, dim: "Real") -> T: + def real(self, dim: "Real") -> Any: """Called by real dimension""" - pass + raise NotImplementedError() - def integer(self, dim: "Integer") -> T: + def integer(self, dim: "Integer") -> Any: """Called by integer dimension""" - pass + raise NotImplementedError() - def categorical(self, dim: "Categorical") -> T: + def categorical(self, dim: "Categorical") -> Any: """Called by categorical dimension""" - pass + raise NotImplementedError() - def fidelity(self, dim: "Fidelity") -> T: + def fidelity(self, dim: "Fidelity") -> Any: """Called by fidelity dimension""" - pass + raise NotImplementedError() def space(self, space: "Space") -> None: """Iterate through a research space and visit each dimensions""" diff --git a/src/orion/algo/space/configspace.py b/src/orion/algo/space/configspace.py index c6e253b71..e76e8dcf5 100644 --- a/src/orion/algo/space/configspace.py +++ b/src/orion/algo/space/configspace.py @@ -48,7 +48,7 @@ def _qantization(dim: Dimension) -> float: return None -class ToConfigSpace(Visitor[Optional[Hyperparameter]]): +class ToConfigSpace(Visitor): """Convert an Orion space into a configspace""" def __init__(self) -> None: From 6bf751837181f251a38327e3bb34d430273bb681 Mon Sep 17 00:00:00 2001 From: Setepenre Date: Fri, 18 Mar 2022 12:40:18 -0400 Subject: [PATCH 12/45] __all__ without T --- src/orion/algo/space/__init__.py | 42 ++++++++++++++++++++--------- src/orion/algo/space/configspace.py | 2 +- 2 files changed, 30 insertions(+), 14 deletions(-) diff --git a/src/orion/algo/space/__init__.py b/src/orion/algo/space/__init__.py index edf04e82e..05ed7b28a 100644 --- a/src/orion/algo/space/__init__.py +++ b/src/orion/algo/space/__init__.py @@ -32,7 +32,7 @@ import logging import numbers from functools import singledispatch -from typing import Any +from typing import Any, Generic, TypeVar import numpy from scipy.stats import distributions @@ -43,6 +43,19 @@ logger = logging.getLogger(__name__) +__all__ = [ + "check_random_state", + "Visitor", + "Dimension", + "Real", + "Integer", + "Categorical", + "Fidelity", + "Space", + "to_orionspace", +] + + def check_random_state(seed): """Return numpy global rng or RandomState if seed is specified""" if seed is None or seed is numpy.random: @@ -87,36 +100,39 @@ def _to_snake_case(name: str) -> str: return "_".join(frags) -class Visitor: +T = TypeVar("T") + + +class Visitor(Generic[T]): """Visitor interface to iterate over an Orion search space. This can be used to implement new features for ``orion.algo.space.Space`` outside of Orion's code base. """ - def visit(self, dim: "Dimension") -> Any: + def visit(self, dim: "Dimension") -> T: """Make dimension call its handler""" return dim.visit(self) - def dimension(self, dim: "Dimension") -> Any: + def dimension(self, dim: "Dimension") -> T: """Called when the dimension does not have a decicated handler""" - raise NotImplementedError() + pass - def real(self, dim: "Real") -> Any: + def real(self, dim: "Real") -> T: """Called by real dimension""" - raise NotImplementedError() + pass - def integer(self, dim: "Integer") -> Any: + def integer(self, dim: "Integer") -> T: """Called by integer dimension""" - raise NotImplementedError() + pass - def categorical(self, dim: "Categorical") -> Any: + def categorical(self, dim: "Categorical") -> T: """Called by categorical dimension""" - raise NotImplementedError() + pass - def fidelity(self, dim: "Fidelity") -> Any: + def fidelity(self, dim: "Fidelity") -> T: """Called by fidelity dimension""" - raise NotImplementedError() + pass def space(self, space: "Space") -> None: """Iterate through a research space and visit each dimensions""" diff --git a/src/orion/algo/space/configspace.py b/src/orion/algo/space/configspace.py index e76e8dcf5..c6e253b71 100644 --- a/src/orion/algo/space/configspace.py +++ b/src/orion/algo/space/configspace.py @@ -48,7 +48,7 @@ def _qantization(dim: Dimension) -> float: return None -class ToConfigSpace(Visitor): +class ToConfigSpace(Visitor[Optional[Hyperparameter]]): """Convert an Orion space into a configspace""" def __init__(self) -> None: From a14d8c6a15776dc07f1b1578ed6518ca2f748b44 Mon Sep 17 00:00:00 2001 From: Setepenre Date: Fri, 18 Mar 2022 13:00:00 -0400 Subject: [PATCH 13/45] Revert --- docs/requirements.txt | 1 + docs/src/conf.py | 1 + src/orion/algo/space/__init__.py | 13 ------------- 3 files changed, 2 insertions(+), 13 deletions(-) diff --git a/docs/requirements.txt b/docs/requirements.txt index 0555874f0..38bd1e244 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -3,6 +3,7 @@ sphinx_rtd_theme sphinxcontrib.httpdomain sphinx-autoapi sphinx_gallery +sphinx-autodoc-typehints numpydoc plotly matplotlib diff --git a/docs/src/conf.py b/docs/src/conf.py index e1b336760..6673024b4 100644 --- a/docs/src/conf.py +++ b/docs/src/conf.py @@ -55,6 +55,7 @@ "sphinx.ext.todo", "sphinx.ext.viewcode", "sphinx.ext.intersphinx", + "sphinx_autodoc_typehints", ] ) diff --git a/src/orion/algo/space/__init__.py b/src/orion/algo/space/__init__.py index 05ed7b28a..68823354a 100644 --- a/src/orion/algo/space/__init__.py +++ b/src/orion/algo/space/__init__.py @@ -43,19 +43,6 @@ logger = logging.getLogger(__name__) -__all__ = [ - "check_random_state", - "Visitor", - "Dimension", - "Real", - "Integer", - "Categorical", - "Fidelity", - "Space", - "to_orionspace", -] - - def check_random_state(seed): """Return numpy global rng or RandomState if seed is specified""" if seed is None or seed is numpy.random: From 64555ed5cc927b64cec97118fbe0c0f37ffac695 Mon Sep 17 00:00:00 2001 From: Setepenre Date: Sat, 19 Mar 2022 15:12:58 -0400 Subject: [PATCH 14/45] Update src/orion/algo/space/configspace.py Co-authored-by: Fabrice Normandin --- src/orion/algo/space/configspace.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/orion/algo/space/configspace.py b/src/orion/algo/space/configspace.py index c6e253b71..a4a241987 100644 --- a/src/orion/algo/space/configspace.py +++ b/src/orion/algo/space/configspace.py @@ -205,7 +205,7 @@ def to_oriondim(dim: Hyperparameter) -> Dimension: @to_orionspace.register -def configpsace_to_orionspace(cspace: ConfigurationSpace) -> Space: +def configspace_to_orionspace(cspace: ConfigurationSpace) -> Space: """Convert from orion space to configspace Notes From c7b5a46ec12c4db4c3adf88a9f7806d96ba8f33c Mon Sep 17 00:00:00 2001 From: Setepenre Date: Mon, 21 Mar 2022 13:06:00 -0400 Subject: [PATCH 15/45] Try to fix doc generation bypassing typing --- src/orion/benchmark/task/profet/forrester.py | 6 ++---- src/orion/benchmark/task/profet/svm.py | 5 ++--- src/orion/typing/__init__.py | 19 +++++++++++++++++++ 3 files changed, 23 insertions(+), 7 deletions(-) create mode 100644 src/orion/typing/__init__.py diff --git a/src/orion/benchmark/task/profet/forrester.py b/src/orion/benchmark/task/profet/forrester.py index fea1cebdf..c7d6d51e9 100644 --- a/src/orion/benchmark/task/profet/forrester.py +++ b/src/orion/benchmark/task/profet/forrester.py @@ -7,15 +7,13 @@ with different values of alpha and beta. This meta-model can then be used to sample "fake" points from a given forrester function. """ -import typing from dataclasses import dataclass -from typing import Any, Callable, ClassVar, Dict, List, Tuple +from typing import Callable, ClassVar, Dict, List, Tuple from orion.benchmark.task.profet.model_utils import get_architecture_forrester from orion.benchmark.task.profet.profet_task import ProfetTask -if typing.TYPE_CHECKING: - import torch +from orion.typing import torch class ProfetForresterTask(ProfetTask): diff --git a/src/orion/benchmark/task/profet/svm.py b/src/orion/benchmark/task/profet/svm.py index 74d14e080..fe681262f 100644 --- a/src/orion/benchmark/task/profet/svm.py +++ b/src/orion/benchmark/task/profet/svm.py @@ -1,6 +1,6 @@ """ Simulated Task consisting in training a Support Vector Machine (SVM). """ -import typing + from dataclasses import dataclass from functools import partial from typing import Callable, ClassVar, Dict, List, Tuple @@ -8,8 +8,7 @@ from orion.benchmark.task.profet.model_utils import get_default_architecture from orion.benchmark.task.profet.profet_task import ProfetTask -if typing.TYPE_CHECKING: - import torch +from orion.typing import torch class ProfetSvmTask(ProfetTask): diff --git a/src/orion/typing/__init__.py b/src/orion/typing/__init__.py new file mode 100644 index 000000000..abbc99b72 --- /dev/null +++ b/src/orion/typing/__init__.py @@ -0,0 +1,19 @@ +import typing + +try: + + if typing.TYPE_CHECKING: + import torch + +except ImportError as err: + + class torch: + """torch module stub""" + class nn: + """toch nn module stub""" + class Module: + """torch module stub""" + pass + + def __getattr__(self) -> None: + raise err From 18f7395ce29eadb682c5801c615511890f4cb353 Mon Sep 17 00:00:00 2001 From: Setepenre Date: Tue, 22 Mar 2022 13:31:05 -0400 Subject: [PATCH 16/45] Mock uninstalled imports, handle py3.6 for configspace --- docs/src/conf.py | 14 ++++++++---- setup.py | 1 - src/orion/algo/space/configspace.py | 19 ++++++++++++++-- src/orion/benchmark/task/profet/forrester.py | 7 ++++-- src/orion/benchmark/task/profet/svm.py | 6 +++-- src/orion/typing/__init__.py | 23 -------------------- 6 files changed, 36 insertions(+), 34 deletions(-) delete mode 100644 src/orion/typing/__init__.py diff --git a/docs/src/conf.py b/docs/src/conf.py index 6673024b4..52544e1a3 100644 --- a/docs/src/conf.py +++ b/docs/src/conf.py @@ -55,7 +55,6 @@ "sphinx.ext.todo", "sphinx.ext.viewcode", "sphinx.ext.intersphinx", - "sphinx_autodoc_typehints", ] ) @@ -216,7 +215,7 @@ # -- Autodoc configuration ----------------------------------------------- -autodoc_mock_imports = ["_version", "utils._appdirs"] +autodoc_mock_imports = ["_version", "utils._appdirs", "torch"] # -- Gallery configuration ----------------------------------------------- @@ -279,7 +278,7 @@ # Enable nitpicky mode - which ensures that all references in the docs # resolve. -ignore_algo_attr = [ +ignore_attr = [ "configuration", "is_done", "should_suspend", @@ -299,8 +298,15 @@ "AlreadyReleased", ] +type_hints = [ + "orion.algo.space.T", +] + nitpicky = True -nitpick_ignore = [("py:obj", attr) for attr in ignore_algo_attr] +nitpick_ignore = ( + [("py:obj", attr) for attr in ignore_attr] + + [("py:class", attr) for attr in type_hints] +) ################################################################################ # Numpy Doc Extension # diff --git a/setup.py b/setup.py index 8538aad4e..346aafff0 100644 --- a/setup.py +++ b/setup.py @@ -25,7 +25,6 @@ "orion.serving", "orion.storage", "orion.testing", - "orion.typing", ] extras_require = { diff --git a/src/orion/algo/space/configspace.py b/src/orion/algo/space/configspace.py index 6186b4805..7e40d3228 100644 --- a/src/orion/algo/space/configspace.py +++ b/src/orion/algo/space/configspace.py @@ -1,3 +1,4 @@ +import sys from math import log10 from typing import Optional @@ -81,7 +82,8 @@ def real(self, dim: Real) -> Optional[FloatHyperparameter]: if dim.prior_name in ("normal", "norm"): a, b = dim._args - return NormalFloatHyperparameter( + # TODO: #845 remove python 3.6 special case + kwargs = dict( name=dim.name, mu=a, sigma=b, @@ -92,6 +94,12 @@ def real(self, dim: Real) -> Optional[FloatHyperparameter]: upper=dim.high if hasattr(dim, "high") else None, ) + if sys.version_info.major == 3 and sys.version_info.minor <= 6: + kwargs.pop("lower") + kwargs.pop("upper") + + return NormalFloatHyperparameter(**kwargs) + return def integer(self, dim: Integer) -> Optional[IntegerHyperparameter]: @@ -111,7 +119,8 @@ def integer(self, dim: Integer) -> Optional[IntegerHyperparameter]: if dim.prior_name in ("norm", "normal"): a, b = dim._args - return NormalIntegerHyperparameter( + # TODO: #845 remove python 3.6 special case + kwargs = dict( name=dim.name, mu=a, sigma=b, @@ -122,6 +131,12 @@ def integer(self, dim: Integer) -> Optional[IntegerHyperparameter]: upper=dim.high if hasattr(dim, "high") else None, ) + if sys.version_info.major == 3 and sys.version_info.minor <= 6: + kwargs.pop("lower") + kwargs.pop("upper") + + return NormalIntegerHyperparameter(**kwargs) + return None def categorical(self, dim: Categorical) -> Optional[CategoricalHyperparameter]: diff --git a/src/orion/benchmark/task/profet/forrester.py b/src/orion/benchmark/task/profet/forrester.py index e14704b50..fea1cebdf 100644 --- a/src/orion/benchmark/task/profet/forrester.py +++ b/src/orion/benchmark/task/profet/forrester.py @@ -7,12 +7,15 @@ with different values of alpha and beta. This meta-model can then be used to sample "fake" points from a given forrester function. """ +import typing from dataclasses import dataclass -from typing import Callable, ClassVar, Dict, List, Tuple +from typing import Any, Callable, ClassVar, Dict, List, Tuple from orion.benchmark.task.profet.model_utils import get_architecture_forrester from orion.benchmark.task.profet.profet_task import ProfetTask -from orion.typing import torch + +if typing.TYPE_CHECKING: + import torch class ProfetForresterTask(ProfetTask): diff --git a/src/orion/benchmark/task/profet/svm.py b/src/orion/benchmark/task/profet/svm.py index 78f60135a..74d14e080 100644 --- a/src/orion/benchmark/task/profet/svm.py +++ b/src/orion/benchmark/task/profet/svm.py @@ -1,13 +1,15 @@ """ Simulated Task consisting in training a Support Vector Machine (SVM). """ - +import typing from dataclasses import dataclass from functools import partial from typing import Callable, ClassVar, Dict, List, Tuple from orion.benchmark.task.profet.model_utils import get_default_architecture from orion.benchmark.task.profet.profet_task import ProfetTask -from orion.typing import torch + +if typing.TYPE_CHECKING: + import torch class ProfetSvmTask(ProfetTask): diff --git a/src/orion/typing/__init__.py b/src/orion/typing/__init__.py deleted file mode 100644 index f465db5fd..000000000 --- a/src/orion/typing/__init__.py +++ /dev/null @@ -1,23 +0,0 @@ -try: - import torch - - HAS_TORCH = True - TORCH_ERROR = None - -except ImportError as err: - TORCH_ERROR = err - HAS_TORCH = False - - class torch: - """torch module stub""" - - class nn: - """toch nn module stub""" - - class Module: - """torch module stub""" - - pass - - def __getattr__(self) -> None: - raise TORCH_ERROR From 72002cc7984aba2c454c54693718eafd74dfdc46 Mon Sep 17 00:00:00 2001 From: Setepenre Date: Thu, 24 Mar 2022 13:36:25 -0400 Subject: [PATCH 17/45] Fix tests for 3.6 --- tests/unittests/algo/test_configspace.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/unittests/algo/test_configspace.py b/tests/unittests/algo/test_configspace.py index ce4bee4bf..76903a07c 100644 --- a/tests/unittests/algo/test_configspace.py +++ b/tests/unittests/algo/test_configspace.py @@ -1,7 +1,7 @@ import pytest -from orion.algo.space import Categorical, Fidelity, Integer, Real, Space, to_orionspace -from orion.algo.space.configspace import IMPORT_ERROR, to_configspace +from orion.algo.space import Categorical, Fidelity, Integer, Real, Space +from orion.algo.space.configspace import IMPORT_ERROR, to_configspace, configspace_to_orionspace @pytest.mark.skipif(IMPORT_ERROR, reason="Running without ConfigSpace") @@ -28,7 +28,7 @@ def test_orion_configspace(): newspace = to_configspace(space) - roundtrip = to_orionspace(newspace) + roundtrip = configspace_to_orionspace(newspace) for k, original in space.items(): # ConfigSpace does not have a fidelity dimension From 8c7dac91fc203ad8169f75d9b1e2067a4d404ad3 Mon Sep 17 00:00:00 2001 From: Setepenre Date: Thu, 24 Mar 2022 13:38:04 -0400 Subject: [PATCH 18/45] Remove python3.6 hacks --- src/orion/algo/space/configspace.py | 9 --------- tests/unittests/algo/test_configspace.py | 6 +++--- 2 files changed, 3 insertions(+), 12 deletions(-) diff --git a/src/orion/algo/space/configspace.py b/src/orion/algo/space/configspace.py index 7e40d3228..738868d5f 100644 --- a/src/orion/algo/space/configspace.py +++ b/src/orion/algo/space/configspace.py @@ -1,4 +1,3 @@ -import sys from math import log10 from typing import Optional @@ -94,10 +93,6 @@ def real(self, dim: Real) -> Optional[FloatHyperparameter]: upper=dim.high if hasattr(dim, "high") else None, ) - if sys.version_info.major == 3 and sys.version_info.minor <= 6: - kwargs.pop("lower") - kwargs.pop("upper") - return NormalFloatHyperparameter(**kwargs) return @@ -131,10 +126,6 @@ def integer(self, dim: Integer) -> Optional[IntegerHyperparameter]: upper=dim.high if hasattr(dim, "high") else None, ) - if sys.version_info.major == 3 and sys.version_info.minor <= 6: - kwargs.pop("lower") - kwargs.pop("upper") - return NormalIntegerHyperparameter(**kwargs) return None diff --git a/tests/unittests/algo/test_configspace.py b/tests/unittests/algo/test_configspace.py index 76903a07c..ce4bee4bf 100644 --- a/tests/unittests/algo/test_configspace.py +++ b/tests/unittests/algo/test_configspace.py @@ -1,7 +1,7 @@ import pytest -from orion.algo.space import Categorical, Fidelity, Integer, Real, Space -from orion.algo.space.configspace import IMPORT_ERROR, to_configspace, configspace_to_orionspace +from orion.algo.space import Categorical, Fidelity, Integer, Real, Space, to_orionspace +from orion.algo.space.configspace import IMPORT_ERROR, to_configspace @pytest.mark.skipif(IMPORT_ERROR, reason="Running without ConfigSpace") @@ -28,7 +28,7 @@ def test_orion_configspace(): newspace = to_configspace(space) - roundtrip = configspace_to_orionspace(newspace) + roundtrip = to_orionspace(newspace) for k, original in space.items(): # ConfigSpace does not have a fidelity dimension From a5a4ac6416f7bf52cb160bd3e872872373011480 Mon Sep 17 00:00:00 2001 From: Setepenre Date: Thu, 24 Mar 2022 15:20:25 -0400 Subject: [PATCH 19/45] Use single dispatch --- src/orion/algo/space/configspace.py | 72 +++++++++++++++++++---------- 1 file changed, 48 insertions(+), 24 deletions(-) diff --git a/src/orion/algo/space/configspace.py b/src/orion/algo/space/configspace.py index 738868d5f..ffb02988d 100644 --- a/src/orion/algo/space/configspace.py +++ b/src/orion/algo/space/configspace.py @@ -1,3 +1,4 @@ +from functools import singledispatch from math import log10 from typing import Optional @@ -170,12 +171,23 @@ def to_configspace(space: Space) -> ConfigurationSpace: return conversion.space(space) +@singledispatch def to_oriondim(dim: Hyperparameter) -> Dimension: """Convert a config space hyperparameter to an orion dimension""" + raise NotImplementedError() - if isinstance(dim, CategoricalHyperparameter): - choices = {k: w for k, w in zip(dim.choices, dim.probabilities)} - return Categorical(dim.name, choices) + +@to_oriondim.register(CategoricalHyperparameter) +def from_categorical(dim: CategoricalHyperparameter) -> Dimension: + """Builds a categorical dimension from a categorical hyperparameter""" + choices = {k: w for k, w in zip(dim.choices, dim.probabilities)} + return Categorical(dim.name, choices) + + +@to_oriondim.register(UniformIntegerHyperparameter) +@to_oriondim.register(UniformFloatHyperparameter) +def from_uniform(dim: Hyperparameter) -> Dimension: + """Builds a uniform dimension from a uniform hyperparameter""" klass = Integer args = [] @@ -185,32 +197,44 @@ def to_oriondim(dim: Hyperparameter) -> Dimension: default_value=dim.default_value ) - if isinstance(dim, (UniformFloatHyperparameter, UniformIntegerHyperparameter)): - if isinstance(dim, UniformFloatHyperparameter): - klass = Real - else: - kwargs["precision"] = int(-log10(dim.q)) if dim.q else 4 + if isinstance(dim, UniformFloatHyperparameter): + klass = Real + else: + kwargs["precision"] = int(-log10(dim.q)) if dim.q else 4 + + dist = "uniform" + args.append(dim.lower) + args.append(dim.upper) - dist = "uniform" - args.append(dim.lower) - args.append(dim.upper) + if dim.log: + dist = "reciprocal" - if dim.log: - dist = "reciprocal" - if isinstance(dim, (NormalFloatHyperparameter, NormalIntegerHyperparameter)): - if isinstance(dim, NormalFloatHyperparameter): - klass = Real - else: - kwargs["precision"] = int(-log10(dim.q)) if dim.q else 4 +@to_oriondim.register(NormalFloatHyperparameter) +@to_oriondim.register(NormalIntegerHyperparameter) +def from_normal(dim: Hyperparameter) -> Dimension: + """Builds a normal dimension from a normal hyperparameter""" + + klass = Integer + args = [] + kwargs = dict( + # NOTE: Config space always has a config value + # so orion-space would get it as well + default_value=dim.default_value + ) + + if isinstance(dim, NormalFloatHyperparameter): + klass = Real + else: + kwargs["precision"] = int(-log10(dim.q)) if dim.q else 4 - dist = "norm" - args.append(dim.mu) - args.append(dim.sigma) + dist = "norm" + args.append(dim.mu) + args.append(dim.sigma) - if dim.lower: - kwargs["low"] = dim.lower - kwargs["high"] = dim.upper + if dim.lower: + kwargs["low"] = dim.lower + kwargs["high"] = dim.upper return klass(dim.name, dist, *args, **kwargs) From e4f6c56f3d919f0fe0df62cfb4605bcd06ae0f91 Mon Sep 17 00:00:00 2001 From: Setepenre Date: Thu, 24 Mar 2022 16:04:18 -0400 Subject: [PATCH 20/45] Missing return --- src/orion/algo/space/configspace.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/orion/algo/space/configspace.py b/src/orion/algo/space/configspace.py index ffb02988d..1a9dec9bf 100644 --- a/src/orion/algo/space/configspace.py +++ b/src/orion/algo/space/configspace.py @@ -177,7 +177,7 @@ def to_oriondim(dim: Hyperparameter) -> Dimension: raise NotImplementedError() -@to_oriondim.register(CategoricalHyperparameter) +@to_oriondim.register def from_categorical(dim: CategoricalHyperparameter) -> Dimension: """Builds a categorical dimension from a categorical hyperparameter""" choices = {k: w for k, w in zip(dim.choices, dim.probabilities)} @@ -209,6 +209,8 @@ def from_uniform(dim: Hyperparameter) -> Dimension: if dim.log: dist = "reciprocal" + return klass(dim.name, dist, *args, **kwargs) + @to_oriondim.register(NormalFloatHyperparameter) @to_oriondim.register(NormalIntegerHyperparameter) @@ -252,6 +254,8 @@ def configspace_to_orionspace(cspace: ConfigurationSpace) -> Space: for _, cdim in cspace.get_hyperparameters_dict().items(): odim = to_oriondim(cdim) + print(cdim, odim) + assert odim is not None space.register(odim) return space From 5b8a2c06557afb44985a150657f185c6b2425126 Mon Sep 17 00:00:00 2001 From: Setepenre Date: Fri, 25 Mar 2022 14:11:35 -0400 Subject: [PATCH 21/45] Update src/orion/algo/space/configspace.py Co-authored-by: Xavier Bouthillier --- src/orion/algo/space/configspace.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/orion/algo/space/configspace.py b/src/orion/algo/space/configspace.py index 1a9dec9bf..e331f4a57 100644 --- a/src/orion/algo/space/configspace.py +++ b/src/orion/algo/space/configspace.py @@ -254,7 +254,6 @@ def configspace_to_orionspace(cspace: ConfigurationSpace) -> Space: for _, cdim in cspace.get_hyperparameters_dict().items(): odim = to_oriondim(cdim) - print(cdim, odim) assert odim is not None space.register(odim) From 107e5bd79210906e3fdd1f35b95b4d222a43458b Mon Sep 17 00:00:00 2001 From: Setepenre Date: Fri, 25 Mar 2022 14:29:40 -0400 Subject: [PATCH 22/45] Add unsupported ConfigSpace priors --- src/orion/algo/space/configspace.py | 7 ++----- tests/unittests/algo/test_configspace.py | 13 +++++++++++++ 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/src/orion/algo/space/configspace.py b/src/orion/algo/space/configspace.py index 1a9dec9bf..163ce2630 100644 --- a/src/orion/algo/space/configspace.py +++ b/src/orion/algo/space/configspace.py @@ -82,7 +82,6 @@ def real(self, dim: Real) -> Optional[FloatHyperparameter]: if dim.prior_name in ("normal", "norm"): a, b = dim._args - # TODO: #845 remove python 3.6 special case kwargs = dict( name=dim.name, mu=a, @@ -112,10 +111,9 @@ def integer(self, dim: Integer) -> Optional[IntegerHyperparameter]: log=dim.prior_name == "int_reciprocal", ) - if dim.prior_name in ("norm", "normal"): + if dim.prior_name in ("int_norm", "normal"): a, b = dim._args - # TODO: #845 remove python 3.6 special case kwargs = dict( name=dim.name, mu=a, @@ -174,7 +172,7 @@ def to_configspace(space: Space) -> ConfigurationSpace: @singledispatch def to_oriondim(dim: Hyperparameter) -> Dimension: """Convert a config space hyperparameter to an orion dimension""" - raise NotImplementedError() + raise NotImplementedError(f"Dimension {dim} is not supported by Orion") @to_oriondim.register @@ -254,7 +252,6 @@ def configspace_to_orionspace(cspace: ConfigurationSpace) -> Space: for _, cdim in cspace.get_hyperparameters_dict().items(): odim = to_oriondim(cdim) - print(cdim, odim) assert odim is not None space.register(odim) diff --git a/tests/unittests/algo/test_configspace.py b/tests/unittests/algo/test_configspace.py index ce4bee4bf..fe0cb61b0 100644 --- a/tests/unittests/algo/test_configspace.py +++ b/tests/unittests/algo/test_configspace.py @@ -25,6 +25,7 @@ def test_orion_configspace(): space.register(Real("n1", "norm", 0.9, 0.1, precision=6)) space.register(Real("n2", "norm", 0.9, 0.1, precision=None)) space.register(Real("n3", "norm", 0.9, 0.1)) + space.register(Integer("n4", "norm", 1, 2)) newspace = to_configspace(space) @@ -44,3 +45,15 @@ def test_orion_configspace(): assert type(original) == type(converted) assert original == converted + + +@pytest.mark.skipif(IMPORT_ERROR, reason="Running without ConfigSpace") +def test_configspace_to_orion_unsupported(): + from ConfigSpace import ConfigurationSpace + from ConfigSpace.hyperparameters import OrdinalHyperparameter + + cspace = ConfigurationSpace() + cspace.add_hyperparameters([OrdinalHyperparameter("a", (1, 2, 0, 3))]) + + with pytest.raises(NotImplementedError): + _ = to_orionspace(cspace) From fd58aa17e22c79da0af34e2bfba23b21df79f732 Mon Sep 17 00:00:00 2001 From: Setepenre Date: Mon, 28 Mar 2022 12:45:33 -0400 Subject: [PATCH 23/45] Add unsupported prior --- src/orion/algo/space/configspace.py | 1 - tests/unittests/algo/test_configspace.py | 6 +++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/orion/algo/space/configspace.py b/src/orion/algo/space/configspace.py index 163ce2630..a9bbd2d60 100644 --- a/src/orion/algo/space/configspace.py +++ b/src/orion/algo/space/configspace.py @@ -252,7 +252,6 @@ def configspace_to_orionspace(cspace: ConfigurationSpace) -> Space: for _, cdim in cspace.get_hyperparameters_dict().items(): odim = to_oriondim(cdim) - assert odim is not None space.register(odim) return space diff --git a/tests/unittests/algo/test_configspace.py b/tests/unittests/algo/test_configspace.py index fe0cb61b0..0485ed894 100644 --- a/tests/unittests/algo/test_configspace.py +++ b/tests/unittests/algo/test_configspace.py @@ -27,13 +27,17 @@ def test_orion_configspace(): space.register(Real("n3", "norm", 0.9, 0.1)) space.register(Integer("n4", "norm", 1, 2)) + # Unsupported prior + space.register(Integer("a1i", "alpha", 1, 6)) + newspace = to_configspace(space) roundtrip = to_orionspace(newspace) for k, original in space.items(): # ConfigSpace does not have a fidelity dimension - if k == "f1": + # or the alpha prior + if k in ("f1", "a1i"): continue converted = roundtrip[k] From 8e8b47b0adbff5b142f6ea3f4bac6dc51dd3f52c Mon Sep 17 00:00:00 2001 From: Setepenre Date: Mon, 28 Mar 2022 13:59:13 -0400 Subject: [PATCH 24/45] - --- src/orion/algo/space/configspace.py | 8 ++++++-- tests/unittests/algo/test_configspace.py | 13 ++++++++++--- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/src/orion/algo/space/configspace.py b/src/orion/algo/space/configspace.py index a9bbd2d60..24b18b937 100644 --- a/src/orion/algo/space/configspace.py +++ b/src/orion/algo/space/configspace.py @@ -47,6 +47,10 @@ class DummyType: CategoricalHyperparameter = DummyType +class UnsupportedPrior(Exception): + pass + + def _qantization(dim: Dimension) -> float: """Convert precision to the quantization factor""" if dim.precision: @@ -95,7 +99,7 @@ def real(self, dim: Real) -> Optional[FloatHyperparameter]: return NormalFloatHyperparameter(**kwargs) - return + raise UnsupportedPrior(f'Prior "{dim.prior_name}" is not supported') def integer(self, dim: Integer) -> Optional[IntegerHyperparameter]: """Convert a integer dimension into a configspace equivalent""" @@ -127,7 +131,7 @@ def integer(self, dim: Integer) -> Optional[IntegerHyperparameter]: return NormalIntegerHyperparameter(**kwargs) - return None + raise UnsupportedPrior(f'Prior "{dim.prior_name}" is not supported') def categorical(self, dim: Categorical) -> Optional[CategoricalHyperparameter]: """Convert a categorical dimension into a configspace equivalent""" diff --git a/tests/unittests/algo/test_configspace.py b/tests/unittests/algo/test_configspace.py index 0485ed894..ad2b5bc25 100644 --- a/tests/unittests/algo/test_configspace.py +++ b/tests/unittests/algo/test_configspace.py @@ -1,7 +1,7 @@ import pytest from orion.algo.space import Categorical, Fidelity, Integer, Real, Space, to_orionspace -from orion.algo.space.configspace import IMPORT_ERROR, to_configspace +from orion.algo.space.configspace import IMPORT_ERROR, to_configspace, UnsupportedPrior @pytest.mark.skipif(IMPORT_ERROR, reason="Running without ConfigSpace") @@ -27,8 +27,6 @@ def test_orion_configspace(): space.register(Real("n3", "norm", 0.9, 0.1)) space.register(Integer("n4", "norm", 1, 2)) - # Unsupported prior - space.register(Integer("a1i", "alpha", 1, 6)) newspace = to_configspace(space) @@ -61,3 +59,12 @@ def test_configspace_to_orion_unsupported(): with pytest.raises(NotImplementedError): _ = to_orionspace(cspace) + + +@pytest.mark.skipif(IMPORT_ERROR, reason="Running without ConfigSpace") +def test_orion_configspace_unsupported(): + space = Space() + space.register(Integer("a1i", "alpha", 1, 6)) + + with pytest.raises(UnsupportedPrior): + _ = to_configspace(space) From a8f04257fc9a4dcfde9d21b4c5d269f7ad58cacd Mon Sep 17 00:00:00 2001 From: Setepenre Date: Mon, 28 Mar 2022 14:11:22 -0400 Subject: [PATCH 25/45] - --- src/orion/algo/space/__init__.py | 14 +++++--------- src/orion/algo/space/configspace.py | 6 +++--- tests/unittests/algo/test_configspace.py | 3 +-- 3 files changed, 9 insertions(+), 14 deletions(-) diff --git a/src/orion/algo/space/__init__.py b/src/orion/algo/space/__init__.py index 68823354a..7dc4ff8bf 100644 --- a/src/orion/algo/space/__init__.py +++ b/src/orion/algo/space/__init__.py @@ -90,16 +90,16 @@ def _to_snake_case(name: str) -> str: T = TypeVar("T") -class Visitor(Generic[T]): - """Visitor interface to iterate over an Orion search space. +class SpaceConverter(Generic[T]): + """SpaceConverter iterates over an Orion search space. This can be used to implement new features for ``orion.algo.space.Space`` outside of Orion's code base. """ - def visit(self, dim: "Dimension") -> T: - """Make dimension call its handler""" - return dim.visit(self) + def convert_dimension(self, dimension: "Dimension") -> T: + """Call the dimension conversion handler""" + return getattr(self, _to_snake_case(type(dimension).__name__))(dimension) def dimension(self, dim: "Dimension") -> T: """Called when the dimension does not have a decicated handler""" @@ -397,10 +397,6 @@ def cardinality(self): """ return numpy.inf - def visit(self, visitor: Visitor[T]) -> T: - """Execute a visitor on the given dimension""" - return getattr(visitor, _to_snake_case(self.__class__.__name__))(self) - def _is_numeric_array(point): """Test whether a point is numerical object or an array containing only numerical objects""" diff --git a/src/orion/algo/space/configspace.py b/src/orion/algo/space/configspace.py index 24b18b937..407c988ff 100644 --- a/src/orion/algo/space/configspace.py +++ b/src/orion/algo/space/configspace.py @@ -9,7 +9,7 @@ Integer, Real, Space, - Visitor, + SpaceConverter, to_orionspace, ) @@ -58,7 +58,7 @@ def _qantization(dim: Dimension) -> float: return None -class ToConfigSpace(Visitor[Optional[Hyperparameter]]): +class ToConfigSpace(SpaceConverter[Optional[Hyperparameter]]): """Convert an Orion space into a configspace""" def __init__(self) -> None: @@ -151,7 +151,7 @@ def space(self, space: Space) -> ConfigurationSpace: dims = [] for _, dim in space.items(): - cdim = self.visit(dim) + cdim = self.convert_dimension(dim) if cdim: dims.append(cdim) diff --git a/tests/unittests/algo/test_configspace.py b/tests/unittests/algo/test_configspace.py index ad2b5bc25..32286494c 100644 --- a/tests/unittests/algo/test_configspace.py +++ b/tests/unittests/algo/test_configspace.py @@ -1,7 +1,7 @@ import pytest from orion.algo.space import Categorical, Fidelity, Integer, Real, Space, to_orionspace -from orion.algo.space.configspace import IMPORT_ERROR, to_configspace, UnsupportedPrior +from orion.algo.space.configspace import IMPORT_ERROR, UnsupportedPrior, to_configspace @pytest.mark.skipif(IMPORT_ERROR, reason="Running without ConfigSpace") @@ -27,7 +27,6 @@ def test_orion_configspace(): space.register(Real("n3", "norm", 0.9, 0.1)) space.register(Integer("n4", "norm", 1, 2)) - newspace = to_configspace(space) roundtrip = to_orionspace(newspace) From 8abd4fb4263db9c45aa1fc0f3abe7218e0d093a9 Mon Sep 17 00:00:00 2001 From: Setepenre Date: Mon, 28 Mar 2022 14:13:56 -0400 Subject: [PATCH 26/45] - --- src/orion/algo/space/configspace.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/orion/algo/space/configspace.py b/src/orion/algo/space/configspace.py index 407c988ff..1b3aef8b4 100644 --- a/src/orion/algo/space/configspace.py +++ b/src/orion/algo/space/configspace.py @@ -58,7 +58,7 @@ def _qantization(dim: Dimension) -> float: return None -class ToConfigSpace(SpaceConverter[Optional[Hyperparameter]]): +class ToConfigSpace(SpaceConverter[Hyperparameter]): """Convert an Orion space into a configspace""" def __init__(self) -> None: @@ -69,7 +69,7 @@ def dimension(self, dim: Dimension) -> None: """Raise an error if the visitor is called on an abstract class""" raise NotImplementedError() - def real(self, dim: Real) -> Optional[FloatHyperparameter]: + def real(self, dim: Real) -> FloatHyperparameter: """Convert a real dimension into a configspace equivalent""" if dim.prior_name in ("reciprocal", "uniform"): a, b = dim._args @@ -101,7 +101,7 @@ def real(self, dim: Real) -> Optional[FloatHyperparameter]: raise UnsupportedPrior(f'Prior "{dim.prior_name}" is not supported') - def integer(self, dim: Integer) -> Optional[IntegerHyperparameter]: + def integer(self, dim: Integer) -> IntegerHyperparameter: """Convert a integer dimension into a configspace equivalent""" if dim.prior_name in ("int_uniform", "int_reciprocal"): a, b = dim._args @@ -133,7 +133,7 @@ def integer(self, dim: Integer) -> Optional[IntegerHyperparameter]: raise UnsupportedPrior(f'Prior "{dim.prior_name}" is not supported') - def categorical(self, dim: Categorical) -> Optional[CategoricalHyperparameter]: + def categorical(self, dim: Categorical) -> CategoricalHyperparameter: """Convert a categorical dimension into a configspace equivalent""" return CategoricalHyperparameter( name=dim.name, From eb57c585c5491fea813b22755b2fce6f1f188397 Mon Sep 17 00:00:00 2001 From: Setepenre Date: Mon, 28 Mar 2022 14:33:05 -0400 Subject: [PATCH 27/45] Update src/orion/algo/space/configspace.py Co-authored-by: Fabrice Normandin --- src/orion/algo/space/configspace.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/orion/algo/space/configspace.py b/src/orion/algo/space/configspace.py index 1b3aef8b4..a73cf6cd7 100644 --- a/src/orion/algo/space/configspace.py +++ b/src/orion/algo/space/configspace.py @@ -216,7 +216,7 @@ def from_uniform(dim: Hyperparameter) -> Dimension: @to_oriondim.register(NormalFloatHyperparameter) @to_oriondim.register(NormalIntegerHyperparameter) -def from_normal(dim: Hyperparameter) -> Dimension: +def from_normal(dim: Hyperparameter) -> Integer | Real: """Builds a normal dimension from a normal hyperparameter""" klass = Integer From fec66c350259f92476b776cdcf54cce073788b96 Mon Sep 17 00:00:00 2001 From: Setepenre Date: Mon, 28 Mar 2022 14:33:16 -0400 Subject: [PATCH 28/45] Update src/orion/algo/space/__init__.py Co-authored-by: Fabrice Normandin --- src/orion/algo/space/__init__.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/orion/algo/space/__init__.py b/src/orion/algo/space/__init__.py index 7dc4ff8bf..29168be8f 100644 --- a/src/orion/algo/space/__init__.py +++ b/src/orion/algo/space/__init__.py @@ -28,6 +28,7 @@ unless noted otherwise! """ +from __future__ import annotations import copy import logging import numbers From ebc988692cca798ad9b3ed29774f1f9f91506740 Mon Sep 17 00:00:00 2001 From: Setepenre Date: Mon, 28 Mar 2022 14:33:33 -0400 Subject: [PATCH 29/45] Update src/orion/algo/space/__init__.py Co-authored-by: Fabrice Normandin --- src/orion/algo/space/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/orion/algo/space/__init__.py b/src/orion/algo/space/__init__.py index 29168be8f..60993ea8b 100644 --- a/src/orion/algo/space/__init__.py +++ b/src/orion/algo/space/__init__.py @@ -122,7 +122,7 @@ def fidelity(self, dim: "Fidelity") -> T: """Called by fidelity dimension""" pass - def space(self, space: "Space") -> None: + def space(self, space: Space) -> None: """Iterate through a research space and visit each dimensions""" for _, dim in space.items(): self.visit(dim) From 0087ef8ebe4f1d476f40f0c26a38493b9fc640aa Mon Sep 17 00:00:00 2001 From: Setepenre Date: Mon, 28 Mar 2022 14:33:39 -0400 Subject: [PATCH 30/45] Update src/orion/algo/space/__init__.py Co-authored-by: Fabrice Normandin --- src/orion/algo/space/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/orion/algo/space/__init__.py b/src/orion/algo/space/__init__.py index 60993ea8b..1c8ea0f4f 100644 --- a/src/orion/algo/space/__init__.py +++ b/src/orion/algo/space/__init__.py @@ -118,7 +118,7 @@ def categorical(self, dim: "Categorical") -> T: """Called by categorical dimension""" pass - def fidelity(self, dim: "Fidelity") -> T: + def fidelity(self, dim: Fidelity) -> T: """Called by fidelity dimension""" pass From 016a6d2a028247b0eeb3b47f3dd6c12a2e451165 Mon Sep 17 00:00:00 2001 From: Setepenre Date: Mon, 28 Mar 2022 14:33:44 -0400 Subject: [PATCH 31/45] Update src/orion/algo/space/__init__.py Co-authored-by: Fabrice Normandin --- src/orion/algo/space/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/orion/algo/space/__init__.py b/src/orion/algo/space/__init__.py index 1c8ea0f4f..92e0d622c 100644 --- a/src/orion/algo/space/__init__.py +++ b/src/orion/algo/space/__init__.py @@ -114,7 +114,7 @@ def integer(self, dim: "Integer") -> T: """Called by integer dimension""" pass - def categorical(self, dim: "Categorical") -> T: + def categorical(self, dim: Categorical) -> T: """Called by categorical dimension""" pass From 5ff9d8e6484abf90b050afebc4a98148b93a8c58 Mon Sep 17 00:00:00 2001 From: Setepenre Date: Mon, 28 Mar 2022 14:33:50 -0400 Subject: [PATCH 32/45] Update src/orion/algo/space/__init__.py Co-authored-by: Fabrice Normandin --- src/orion/algo/space/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/orion/algo/space/__init__.py b/src/orion/algo/space/__init__.py index 92e0d622c..c63d475d2 100644 --- a/src/orion/algo/space/__init__.py +++ b/src/orion/algo/space/__init__.py @@ -110,7 +110,7 @@ def real(self, dim: "Real") -> T: """Called by real dimension""" pass - def integer(self, dim: "Integer") -> T: + def integer(self, dim: Integer) -> T: """Called by integer dimension""" pass From 59bdad212c67a104acc862a932a33e12e131eff4 Mon Sep 17 00:00:00 2001 From: Setepenre Date: Mon, 28 Mar 2022 14:34:02 -0400 Subject: [PATCH 33/45] Update src/orion/algo/space/configspace.py Co-authored-by: Fabrice Normandin --- src/orion/algo/space/configspace.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/orion/algo/space/configspace.py b/src/orion/algo/space/configspace.py index a73cf6cd7..f002913ac 100644 --- a/src/orion/algo/space/configspace.py +++ b/src/orion/algo/space/configspace.py @@ -1,3 +1,4 @@ +from __future__ import annotations from functools import singledispatch from math import log10 from typing import Optional From 0709f8dfc451d4d6f8999790f745c336d9016d8c Mon Sep 17 00:00:00 2001 From: Setepenre Date: Mon, 28 Mar 2022 14:35:18 -0400 Subject: [PATCH 34/45] Update src/orion/algo/space/__init__.py Co-authored-by: Fabrice Normandin --- src/orion/algo/space/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/orion/algo/space/__init__.py b/src/orion/algo/space/__init__.py index c63d475d2..6e1b2a200 100644 --- a/src/orion/algo/space/__init__.py +++ b/src/orion/algo/space/__init__.py @@ -102,7 +102,7 @@ def convert_dimension(self, dimension: "Dimension") -> T: """Call the dimension conversion handler""" return getattr(self, _to_snake_case(type(dimension).__name__))(dimension) - def dimension(self, dim: "Dimension") -> T: + def dimension(self, dim: Dimension) -> T: """Called when the dimension does not have a decicated handler""" pass From 17af4cea19bc765bb619a5cf27e5a532a30f83d2 Mon Sep 17 00:00:00 2001 From: Setepenre Date: Mon, 28 Mar 2022 14:35:30 -0400 Subject: [PATCH 35/45] Update src/orion/algo/space/__init__.py Co-authored-by: Fabrice Normandin --- src/orion/algo/space/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/orion/algo/space/__init__.py b/src/orion/algo/space/__init__.py index 6e1b2a200..8ca60fd34 100644 --- a/src/orion/algo/space/__init__.py +++ b/src/orion/algo/space/__init__.py @@ -106,7 +106,7 @@ def dimension(self, dim: Dimension) -> T: """Called when the dimension does not have a decicated handler""" pass - def real(self, dim: "Real") -> T: + def real(self, dim: Real) -> T: """Called by real dimension""" pass From 38c1ae52533147f155ed8acbf104130296efd211 Mon Sep 17 00:00:00 2001 From: Setepenre Date: Mon, 28 Mar 2022 14:37:14 -0400 Subject: [PATCH 36/45] - --- src/orion/algo/space/__init__.py | 2 +- src/orion/algo/space/configspace.py | 6 +++--- tests/unittests/algo/test_configspace.py | 6 +++--- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/orion/algo/space/__init__.py b/src/orion/algo/space/__init__.py index 7dc4ff8bf..a1b829221 100644 --- a/src/orion/algo/space/__init__.py +++ b/src/orion/algo/space/__init__.py @@ -97,7 +97,7 @@ class SpaceConverter(Generic[T]): """ - def convert_dimension(self, dimension: "Dimension") -> T: + def convert_dimension(self, dimension: Dimension) -> T: """Call the dimension conversion handler""" return getattr(self, _to_snake_case(type(dimension).__name__))(dimension) diff --git a/src/orion/algo/space/configspace.py b/src/orion/algo/space/configspace.py index 1b3aef8b4..5327f1dbd 100644 --- a/src/orion/algo/space/configspace.py +++ b/src/orion/algo/space/configspace.py @@ -180,7 +180,7 @@ def to_oriondim(dim: Hyperparameter) -> Dimension: @to_oriondim.register -def from_categorical(dim: CategoricalHyperparameter) -> Dimension: +def _from_categorical(dim: CategoricalHyperparameter) -> Dimension: """Builds a categorical dimension from a categorical hyperparameter""" choices = {k: w for k, w in zip(dim.choices, dim.probabilities)} return Categorical(dim.name, choices) @@ -188,7 +188,7 @@ def from_categorical(dim: CategoricalHyperparameter) -> Dimension: @to_oriondim.register(UniformIntegerHyperparameter) @to_oriondim.register(UniformFloatHyperparameter) -def from_uniform(dim: Hyperparameter) -> Dimension: +def _from_uniform(dim: Hyperparameter) -> Dimension: """Builds a uniform dimension from a uniform hyperparameter""" klass = Integer @@ -216,7 +216,7 @@ def from_uniform(dim: Hyperparameter) -> Dimension: @to_oriondim.register(NormalFloatHyperparameter) @to_oriondim.register(NormalIntegerHyperparameter) -def from_normal(dim: Hyperparameter) -> Dimension: +def _from_normal(dim: Hyperparameter) -> Dimension: """Builds a normal dimension from a normal hyperparameter""" klass = Integer diff --git a/tests/unittests/algo/test_configspace.py b/tests/unittests/algo/test_configspace.py index 32286494c..2a71ad2f2 100644 --- a/tests/unittests/algo/test_configspace.py +++ b/tests/unittests/algo/test_configspace.py @@ -4,7 +4,9 @@ from orion.algo.space.configspace import IMPORT_ERROR, UnsupportedPrior, to_configspace -@pytest.mark.skipif(IMPORT_ERROR, reason="Running without ConfigSpace") +pytest.mark.skip(IMPORT_ERROR, reason="Running without ConfigSpace", allow_module_level=True) + + def test_orion_configspace(): space = Space() @@ -48,7 +50,6 @@ def test_orion_configspace(): assert original == converted -@pytest.mark.skipif(IMPORT_ERROR, reason="Running without ConfigSpace") def test_configspace_to_orion_unsupported(): from ConfigSpace import ConfigurationSpace from ConfigSpace.hyperparameters import OrdinalHyperparameter @@ -60,7 +61,6 @@ def test_configspace_to_orion_unsupported(): _ = to_orionspace(cspace) -@pytest.mark.skipif(IMPORT_ERROR, reason="Running without ConfigSpace") def test_orion_configspace_unsupported(): space = Space() space.register(Integer("a1i", "alpha", 1, 6)) From 534ab5e2ae1d3c8f5df4af1c25e5d6248e092dba Mon Sep 17 00:00:00 2001 From: Setepenre Date: Mon, 28 Mar 2022 14:41:24 -0400 Subject: [PATCH 37/45] - --- src/orion/algo/space/configspace.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/orion/algo/space/configspace.py b/src/orion/algo/space/configspace.py index da231ebc7..0435ada81 100644 --- a/src/orion/algo/space/configspace.py +++ b/src/orion/algo/space/configspace.py @@ -2,7 +2,6 @@ from functools import singledispatch from math import log10 -from typing import Optional from orion.algo.space import ( Categorical, From 192f31cf94670385ae4b49ed677b1ac1fa47a990 Mon Sep 17 00:00:00 2001 From: Setepenre Date: Mon, 28 Mar 2022 15:40:41 -0400 Subject: [PATCH 38/45] Update src/orion/algo/space/configspace.py Co-authored-by: Fabrice Normandin --- src/orion/algo/space/configspace.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/orion/algo/space/configspace.py b/src/orion/algo/space/configspace.py index 0435ada81..8861febf7 100644 --- a/src/orion/algo/space/configspace.py +++ b/src/orion/algo/space/configspace.py @@ -181,7 +181,7 @@ def to_oriondim(dim: Hyperparameter) -> Dimension: @to_oriondim.register -def _from_categorical(dim: CategoricalHyperparameter) -> Dimension: +def _from_categorical(dim: CategoricalHyperparameter) -> Categorical """Builds a categorical dimension from a categorical hyperparameter""" choices = {k: w for k, w in zip(dim.choices, dim.probabilities)} return Categorical(dim.name, choices) From a1042559ae7f4d51c8c9456d7ca8f8b64e773691 Mon Sep 17 00:00:00 2001 From: Setepenre Date: Mon, 28 Mar 2022 15:40:46 -0400 Subject: [PATCH 39/45] Update src/orion/algo/space/configspace.py Co-authored-by: Fabrice Normandin --- src/orion/algo/space/configspace.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/orion/algo/space/configspace.py b/src/orion/algo/space/configspace.py index 8861febf7..de7b71ad9 100644 --- a/src/orion/algo/space/configspace.py +++ b/src/orion/algo/space/configspace.py @@ -189,7 +189,7 @@ def _from_categorical(dim: CategoricalHyperparameter) -> Categorical @to_oriondim.register(UniformIntegerHyperparameter) @to_oriondim.register(UniformFloatHyperparameter) -def _from_uniform(dim: Hyperparameter) -> Dimension: +def _from_uniform(dim: Hyperparameter) -> Integer | Real: """Builds a uniform dimension from a uniform hyperparameter""" klass = Integer From f60858a894e6e7557952816c4e422df7b2511dc9 Mon Sep 17 00:00:00 2001 From: Setepenre Date: Mon, 28 Mar 2022 15:40:54 -0400 Subject: [PATCH 40/45] Update src/orion/algo/space/configspace.py Co-authored-by: Fabrice Normandin --- src/orion/algo/space/configspace.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/orion/algo/space/configspace.py b/src/orion/algo/space/configspace.py index de7b71ad9..a4e3416b2 100644 --- a/src/orion/algo/space/configspace.py +++ b/src/orion/algo/space/configspace.py @@ -255,7 +255,7 @@ def configspace_to_orionspace(cspace: ConfigurationSpace) -> Space: """ space = Space() - for _, cdim in cspace.get_hyperparameters_dict().items(): + for cdim in cspace.get_hyperparameters_dict().values(): odim = to_oriondim(cdim) space.register(odim) From 65b6f7df91a5f5ed434e523d24d41e5cb0f25394 Mon Sep 17 00:00:00 2001 From: Setepenre Date: Mon, 28 Mar 2022 15:48:35 -0400 Subject: [PATCH 41/45] - --- src/orion/algo/space/configspace.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/orion/algo/space/configspace.py b/src/orion/algo/space/configspace.py index a4e3416b2..a76eca270 100644 --- a/src/orion/algo/space/configspace.py +++ b/src/orion/algo/space/configspace.py @@ -181,7 +181,7 @@ def to_oriondim(dim: Hyperparameter) -> Dimension: @to_oriondim.register -def _from_categorical(dim: CategoricalHyperparameter) -> Categorical +def _from_categorical(dim: CategoricalHyperparameter) -> Categorical: """Builds a categorical dimension from a categorical hyperparameter""" choices = {k: w for k, w in zip(dim.choices, dim.probabilities)} return Categorical(dim.name, choices) From a14a47ba861f33869c23c5656ae68a933e6759ab Mon Sep 17 00:00:00 2001 From: Setepenre Date: Fri, 1 Apr 2022 23:36:34 -0400 Subject: [PATCH 42/45] Update tests/unittests/algo/test_configspace.py Co-authored-by: Xavier Bouthillier --- tests/unittests/algo/test_configspace.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/tests/unittests/algo/test_configspace.py b/tests/unittests/algo/test_configspace.py index e78111484..aa5d32ed0 100644 --- a/tests/unittests/algo/test_configspace.py +++ b/tests/unittests/algo/test_configspace.py @@ -3,9 +3,10 @@ from orion.algo.space import Categorical, Fidelity, Integer, Real, Space, to_orionspace from orion.algo.space.configspace import IMPORT_ERROR, UnsupportedPrior, to_configspace -pytest.mark.skip( - IMPORT_ERROR, reason="Running without ConfigSpace", allow_module_level=True -) +if IMPORT_ERROR: + pytest.skip( + "Running without ConfigSpace", allow_module_level=True + ) def test_orion_configspace(): From 9de07add2fae6bde03cbaafbe70e136be945ee3a Mon Sep 17 00:00:00 2001 From: Setepenre Date: Tue, 12 Apr 2022 12:19:01 -0400 Subject: [PATCH 43/45] - --- tests/unittests/algo/test_configspace.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/tests/unittests/algo/test_configspace.py b/tests/unittests/algo/test_configspace.py index aa5d32ed0..b3084d758 100644 --- a/tests/unittests/algo/test_configspace.py +++ b/tests/unittests/algo/test_configspace.py @@ -4,9 +4,7 @@ from orion.algo.space.configspace import IMPORT_ERROR, UnsupportedPrior, to_configspace if IMPORT_ERROR: - pytest.skip( - "Running without ConfigSpace", allow_module_level=True - ) + pytest.skip("Running without ConfigSpace", allow_module_level=True) def test_orion_configspace(): From 5648f03601faf9a208a8e528f60577051b723a6f Mon Sep 17 00:00:00 2001 From: Setepenre Date: Tue, 12 Apr 2022 14:05:26 -0400 Subject: [PATCH 44/45] - --- docs/src/conf.py | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/src/conf.py b/docs/src/conf.py index 9337f3446..70bcde00f 100644 --- a/docs/src/conf.py +++ b/docs/src/conf.py @@ -302,6 +302,7 @@ "orion.core.utils.tree.T", "orion.core.utils.tree.NodeType", "orion.core.utils.tree.Self", + "orion.algo.space.T", "Self", "AlgoType", "T", From bd9680f5d485b6fba7a155f2a187a1b70547c3cf Mon Sep 17 00:00:00 2001 From: Xavier Bouthillier Date: Wed, 27 Jul 2022 12:20:39 -0400 Subject: [PATCH 45/45] black --- src/orion/algo/space/configspace.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/orion/algo/space/configspace.py b/src/orion/algo/space/configspace.py index a76eca270..f36980490 100644 --- a/src/orion/algo/space/configspace.py +++ b/src/orion/algo/space/configspace.py @@ -35,8 +35,6 @@ class DummyType: """Dummy type for type hints""" - pass - IntegerHyperparameter = DummyType FloatHyperparameter = DummyType ConfigurationSpace = DummyType