Skip to content

Commit

Permalink
Add singledispatch to make to_orionspace work for any registered types
Browse files Browse the repository at this point in the history
  • Loading branch information
Delaunay committed Mar 18, 2022
1 parent acd5a46 commit 3acd64d
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 18 deletions.
23 changes: 18 additions & 5 deletions src/orion/algo/space/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,11 @@
"""
import copy
from functools import singledispatch
import logging
import numbers
from typing import Generic, TypeVar
from typing import Generic, TypeVar, Any


import numpy
from scipy.stats import distributions
Expand Down Expand Up @@ -96,16 +98,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


Expand Down Expand Up @@ -1138,3 +1140,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()
19 changes: 10 additions & 9 deletions src/orion/algo/space/configspace.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
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, Integer, Real, Space, Visitor, Fidelity, to_orionspace

try:
from ConfigSpace import ConfigurationSpace
Expand Down Expand Up @@ -50,7 +50,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
Expand Down Expand Up @@ -80,7 +80,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
Expand Down Expand Up @@ -110,15 +110,15 @@ 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,
choices=dim.categories,
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

Expand All @@ -137,7 +137,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
Expand All @@ -150,7 +150,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):
Expand Down Expand Up @@ -195,7 +195,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
Expand All @@ -206,7 +207,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
8 changes: 4 additions & 4 deletions tests/unittests/algo/test_configspace.py
Original file line number Diff line number Diff line change
@@ -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")
Expand All @@ -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
Expand Down

0 comments on commit 3acd64d

Please sign in to comment.