Skip to content

Commit

Permalink
Added distribution space abstraction, allowing configuration space to…
Browse files Browse the repository at this point in the history
… be immutable (except rng).
  • Loading branch information
Kerilk committed Sep 26, 2023
1 parent f672e66 commit 23c5f05
Show file tree
Hide file tree
Showing 41 changed files with 1,667 additions and 788 deletions.
1 change: 1 addition & 0 deletions bindings/python/cconfigspace/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
from .expression_parser import *
from .context import *
from .configuration_space import *
from .distribution_space import *
from .binding import *
from .configuration import *
from .features_space import *
Expand Down
73 changes: 39 additions & 34 deletions bindings/python/cconfigspace/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ def __str__(self):
ccs_parameter = ccs_object
ccs_expression = ccs_object
ccs_context = ccs_object
ccs_distribution_space = ccs_object
ccs_configuration_space = ccs_object
ccs_binding = ccs_object
ccs_configuration = ccs_object
Expand Down Expand Up @@ -154,42 +155,44 @@ class ObjectType(CEnumeration):
'TREE_SPACE',
'TREE_CONFIGURATION',
'TREE_EVALUATION',
'TREE_TUNER' ]
'TREE_TUNER',
'DISTRIBUTION_SPACE' ]

class Result(CEnumeration):
_members_ = [
('AGAIN', 1),
('SUCCESS', 0),
('ERROR_INVALID_OBJECT', -1),
('ERROR_INVALID_VALUE', -2),
('ERROR_INVALID_TYPE', -3),
('ERROR_INVALID_SCALE', -4),
('ERROR_INVALID_DISTRIBUTION', -5),
('ERROR_INVALID_EXPRESSION', -6),
('ERROR_INVALID_PARAMETER', -7),
('ERROR_INVALID_CONFIGURATION', -8),
('ERROR_INVALID_NAME', -9),
('ERROR_INVALID_CONDITION', -10),
('ERROR_INVALID_TUNER', -11),
('ERROR_INVALID_GRAPH', -12),
('ERROR_TYPE_NOT_COMPARABLE', -13),
('ERROR_INVALID_BOUNDS', -14),
('ERROR_OUT_OF_BOUNDS', -15),
('ERROR_SAMPLING_UNSUCCESSFUL', -16),
('ERROR_OUT_OF_MEMORY', -17),
('ERROR_UNSUPPORTED_OPERATION', -18),
('ERROR_INVALID_EVALUATION', -19),
('ERROR_INVALID_FEATURES', -20),
('ERROR_INVALID_FEATURES_TUNER', -21),
('ERROR_INVALID_FILE_PATH', -22),
('ERROR_NOT_ENOUGH_DATA', -23),
('ERROR_DUPLICATE_HANDLE', -24),
('ERROR_INVALID_HANDLE', -25),
('ERROR_SYSTEM', -26),
('ERROR_EXTERNAL', -27),
('ERROR_INVALID_TREE', -28),
('ERROR_INVALID_TREE_SPACE', -29),
('ERROR_INVALID_TREE_TUNER', -30) ]
('AGAIN', 1),
('SUCCESS', 0),
('ERROR_INVALID_OBJECT', -1),
('ERROR_INVALID_VALUE', -2),
('ERROR_INVALID_TYPE', -3),
('ERROR_INVALID_SCALE', -4),
('ERROR_INVALID_DISTRIBUTION', -5),
('ERROR_INVALID_EXPRESSION', -6),
('ERROR_INVALID_PARAMETER', -7),
('ERROR_INVALID_CONFIGURATION', -8),
('ERROR_INVALID_NAME', -9),
('ERROR_INVALID_CONDITION', -10),
('ERROR_INVALID_TUNER', -11),
('ERROR_INVALID_GRAPH', -12),
('ERROR_TYPE_NOT_COMPARABLE', -13),
('ERROR_INVALID_BOUNDS', -14),
('ERROR_OUT_OF_BOUNDS', -15),
('ERROR_SAMPLING_UNSUCCESSFUL', -16),
('ERROR_OUT_OF_MEMORY', -17),
('ERROR_UNSUPPORTED_OPERATION', -18),
('ERROR_INVALID_EVALUATION', -19),
('ERROR_INVALID_FEATURES', -20),
('ERROR_INVALID_FEATURES_TUNER', -21),
('ERROR_INVALID_FILE_PATH', -22),
('ERROR_NOT_ENOUGH_DATA', -23),
('ERROR_DUPLICATE_HANDLE', -24),
('ERROR_INVALID_HANDLE', -25),
('ERROR_SYSTEM', -26),
('ERROR_EXTERNAL', -27),
('ERROR_INVALID_TREE', -28),
('ERROR_INVALID_TREE_SPACE', -29),
('ERROR_INVALID_TREE_TUNER', -30),
('ERROR_INVALID_DISTRIBUTION_SPACE', -31) ]

class DataType(CEnumeration):
_members_ = [
Expand Down Expand Up @@ -748,6 +751,7 @@ def _ccs_get_id():
from .parameter import Parameter
from .expression import Expression
from .configuration_space import ConfigurationSpace
from .distribution_space import DistributionSpace
from .configuration import Configuration
from .features_space import FeaturesSpace
from .features import Features
Expand Down Expand Up @@ -784,7 +788,8 @@ def _ccs_get_id():
ObjectType.TREE_SPACE: TreeSpace,
ObjectType.TREE_CONFIGURATION: TreeConfiguration,
ObjectType.TREE_EVALUATION: TreeEvaluation,
ObjectType.TREE_TUNER: TreeTuner
ObjectType.TREE_TUNER: TreeTuner,
ObjectType.DISTRIBUTION_SPACE: DistributionSpace
})


43 changes: 7 additions & 36 deletions bindings/python/cconfigspace/configuration_space.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import ctypes as ct
from .base import Object, Error, Result, _ccs_get_function, ccs_context, ccs_parameter, ccs_configuration_space, ccs_configuration, ccs_rng, ccs_distribution, ccs_expression, Datum, ccs_bool
from .base import Object, Error, Result, _ccs_get_function, ccs_context, ccs_parameter, ccs_configuration_space, ccs_configuration, ccs_rng, ccs_expression, Datum, ccs_bool, ccs_distribution_space
from .context import Context
from .distribution import Distribution
from .parameter import Parameter
Expand All @@ -11,8 +11,6 @@
ccs_create_configuration_space = _ccs_get_function("ccs_create_configuration_space", [ct.c_char_p, ct.c_size_t, ct.POINTER(ccs_parameter), ct.POINTER(ccs_configuration_space)])
ccs_configuration_space_set_rng = _ccs_get_function("ccs_configuration_space_set_rng", [ccs_configuration_space, ccs_rng])
ccs_configuration_space_get_rng = _ccs_get_function("ccs_configuration_space_get_rng", [ccs_configuration_space, ct.POINTER(ccs_rng)])
ccs_configuration_space_set_distribution = _ccs_get_function("ccs_configuration_space_set_distribution", [ccs_configuration_space, ccs_distribution, ct.POINTER(ct.c_size_t)])
ccs_configuration_space_get_parameter_distribution = _ccs_get_function("ccs_configuration_space_get_parameter_distribution", [ccs_configuration_space, ct.c_size_t, ct.POINTER(ccs_distribution), ct.POINTER(ct.c_size_t)])
ccs_configuration_space_set_condition = _ccs_get_function("ccs_configuration_space_set_condition", [ccs_configuration_space, ct.c_size_t, ccs_expression])
ccs_configuration_space_get_condition = _ccs_get_function("ccs_configuration_space_get_condition", [ccs_configuration_space, ct.c_size_t, ct.POINTER(ccs_expression)])
ccs_configuration_space_get_conditions = _ccs_get_function("ccs_configuration_space_get_conditions", [ccs_configuration_space, ct.c_size_t, ct.POINTER(ccs_expression), ct.POINTER(ct.c_size_t)])
Expand All @@ -23,8 +21,8 @@
ccs_configuration_space_check_configuration = _ccs_get_function("ccs_configuration_space_check_configuration", [ccs_configuration_space, ccs_configuration, ct.POINTER(ccs_bool)])
ccs_configuration_space_check_configuration_values = _ccs_get_function("ccs_configuration_space_check_configuration_values", [ccs_configuration_space, ct.c_size_t, ct.POINTER(Datum), ct.POINTER(ccs_bool)])
ccs_configuration_space_get_default_configuration = _ccs_get_function("ccs_configuration_space_get_default_configuration", [ccs_configuration_space, ct.POINTER(ccs_configuration)])
ccs_configuration_space_sample = _ccs_get_function("ccs_configuration_space_sample", [ccs_configuration_space, ct.POINTER(ccs_configuration)])
ccs_configuration_space_samples = _ccs_get_function("ccs_configuration_space_samples", [ccs_configuration_space, ct.c_size_t, ct.POINTER(ccs_configuration)])
ccs_configuration_space_sample = _ccs_get_function("ccs_configuration_space_sample", [ccs_configuration_space, ccs_distribution_space, ct.POINTER(ccs_configuration)])
ccs_configuration_space_samples = _ccs_get_function("ccs_configuration_space_samples", [ccs_configuration_space, ccs_distribution_space, ct.c_size_t, ct.POINTER(ccs_configuration)])

class ConfigurationSpace(Context):
def __init__(self, handle = None, retain = False, auto_release = True,
Expand Down Expand Up @@ -55,33 +53,6 @@ def rng(self, r):
res = ccs_configuration_space_set_rng(self.handle, r.handle)
Error.check(res)

def set_distribution(self, distribution, parameters):
count = distribution.dimension
if count != len(parameters):
raise Error(Result(Result.ERROR_INVALID_VALUE))
hyps = []
for h in parameters:
if isinstance(h, Parameter):
hyps.append(self.parameter_index(h))
elif isinstance(h, str):
hyps.append(self.parameter_index_by_name(h))
else:
hyps.append(h)
v = (ct.c_size_t * count)(*hyps)
res = ccs_configuration_space_set_distribution(self.handle, distribution.handle, v)
Error.check(res)

def get_parameter_distribution(self, parameter):
if isinstance(parameter, Parameter):
parameter = self.parameter_index(parameter)
elif isinstance(parameter, str):
parameter = self.parameter_index_by_name(parameter)
v1 = ccs_distribution()
v2 = ct.c_size_t()
res = ccs_configuration_space_get_parameter_distribution(self.handle, parameter, ct.byref(v1), ct.byref(v2))
Error.check(res)
return [Distribution.from_handle(v1), v2.value]

def set_condition(self, parameter, expression):
if isinstance(expression, str):
expression = parser.parse(expression, context = PContext(extra=self))
Expand Down Expand Up @@ -191,15 +162,15 @@ def default_configuration(self):
Error.check(res)
return Configuration(handle = v, retain = False)

def sample(self):
def sample(self, distribution_space = None):
v = ccs_configuration()
res = ccs_configuration_space_sample(self.handle, ct.byref(v))
res = ccs_configuration_space_sample(self.handle, distribution_space.handle if distribution_space is not None else None, ct.byref(v))
Error.check(res)
return Configuration(handle = v, retain = False)

def samples(self, count):
def samples(self, count, distribution_space = None):
v = (ccs_configuration * count)()
res = ccs_configuration_space_samples(self.handle, count, v)
res = ccs_configuration_space_samples(self.handle, distribution_space.handle if distribution_space is not None else None, count, v)
Error.check(res)
return [Configuration(handle = ccs_configuration(x), retain = False) for x in v]

Expand Down
61 changes: 61 additions & 0 deletions bindings/python/cconfigspace/distribution_space.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import ctypes as ct
from .base import Object, Error, Result, _ccs_get_function, ccs_configuration_space, ccs_distribution, ccs_distribution_space
from .distribution import Distribution
from .parameter import Parameter
from .configuration_space import ConfigurationSpace

ccs_create_distribution_space = _ccs_get_function("ccs_create_distribution_space", [ccs_configuration_space, ct.POINTER(ccs_distribution_space)])
ccs_distribution_space_get_configuration_space = _ccs_get_function("ccs_distribution_space_get_configuration_space", [ccs_distribution_space, ct.POINTER(ccs_configuration_space)])
ccs_distribution_space_set_distribution = _ccs_get_function("ccs_distribution_space_set_distribution", [ccs_distribution_space, ccs_distribution, ct.POINTER(ct.c_size_t)])
ccs_distribution_space_get_parameter_distribution = _ccs_get_function("ccs_distribution_space_get_parameter_distribution", [ccs_distribution_space, ct.c_size_t, ct.POINTER(ccs_distribution), ct.POINTER(ct.c_size_t)])

class DistributionSpace(Object):

@property
def configuration_space(self):
if hasattr(self, "_configuration_space"):
return self._configuration_space
v = ccs_configuration_space()
res = ccs_distribution_space_get_configuration_space(self.handle, ct.byref(v))
Error.check(res)
self._configuration_space = ConfigurationSpace.from_handle(v)
return self._configuration_space

def __init__(self, handle = None, retain = False, auto_release = True,
configuration_space = None):
if handle is None:
handle = ccs_distribution_space()
res = ccs_create_distribution_space(configuration_space.handle, ct.byref(handle))
Error.check(res)
super().__init__(handle = handle, retain = False)
else:
super().__init__(handle = handle, retain = retain, auto_release = auto_release)

def set_distribution(self, distribution, parameters):
count = distribution.dimension
if count != len(parameters):
raise Error(Result(Result.ERROR_INVALID_VALUE))
hyps = []
for h in parameters:
if isinstance(h, Parameter):
hyps.append(self.configuration_space.parameter_index(h))
elif isinstance(h, str):
hyps.append(self.configuration_space.parameter_index_by_name(h))
else:
hyps.append(h)
v = (ct.c_size_t * count)(*hyps)
res = ccs_distribution_space_set_distribution(self.handle, distribution.handle, v)
Error.check(res)

def get_parameter_distribution(self, parameter):
if isinstance(parameter, Parameter):
parameter = self.configuration_space.parameter_index(parameter)
elif isinstance(parameter, str):
parameter = self.configuration_space.parameter_index_by_name(parameter)
v1 = ccs_distribution()
v2 = ct.c_size_t()
res = ccs_distribution_space_get_parameter_distribution(self.handle, parameter, ct.byref(v1), ct.byref(v2))
Error.check(res)
return [Distribution.from_handle(v1), v2.value]


13 changes: 7 additions & 6 deletions bindings/python/test/test_configuration_space.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,21 +36,22 @@ def test_set_distribution(self):
h2 = ccs.NumericalParameter.Float()
h3 = ccs.NumericalParameter.Float()
cs = ccs.ConfigurationSpace(name = "space", parameters = [h1, h2, h3])
ds = ccs.DistributionSpace(configuration_space = cs)
distributions = [ ccs.UniformDistribution.Float(lower = 0.1, upper = 0.3),
ccs.UniformDistribution.Float(lower = 0.2, upper = 0.6) ]
d = ccs.MultivariateDistribution(distributions = distributions)
cs.set_distribution(d, [h1, h2])
(dist, indx) = cs.get_parameter_distribution(h1)
ds.set_distribution(d, [h1, h2])
(dist, indx) = ds.get_parameter_distribution(h1)
self.assertEqual( d.handle.value, dist.handle.value )
self.assertEqual( 0, indx )
(dist, indx) = cs.get_parameter_distribution(h2)
(dist, indx) = ds.get_parameter_distribution(h2)
self.assertEqual( d.handle.value, dist.handle.value )
self.assertEqual( 1, indx )
cs.set_distribution(d, [h3, h1])
(dist, indx) = cs.get_parameter_distribution(h1)
ds.set_distribution(d, [h3, h1])
(dist, indx) = ds.get_parameter_distribution(h1)
self.assertEqual( d.handle.value, dist.handle.value )
self.assertEqual( 1, indx )
(dist, indx) = cs.get_parameter_distribution(h3)
(dist, indx) = ds.get_parameter_distribution(h3)
self.assertEqual( d.handle.value, dist.handle.value )
self.assertEqual( 0, indx )

Expand Down
1 change: 1 addition & 0 deletions bindings/ruby/lib/cconfigspace.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
require_relative 'cconfigspace/expression_parser'
require_relative 'cconfigspace/context'
require_relative 'cconfigspace/configuration_space'
require_relative 'cconfigspace/distribution_space'
require_relative 'cconfigspace/binding'
require_relative 'cconfigspace/configuration'
require_relative 'cconfigspace/features_space'
Expand Down
73 changes: 39 additions & 34 deletions bindings/ruby/lib/cconfigspace/base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ class Version < FFI::Struct
typedef :ccs_object_t, :ccs_parameter_t
typedef :ccs_object_t, :ccs_expression_t
typedef :ccs_object_t, :ccs_context_t
typedef :ccs_object_t, :ccs_distribution_space_t
typedef :ccs_object_t, :ccs_configuration_space_t
typedef :ccs_object_t, :ccs_binding_t
typedef :ccs_object_t, :ccs_configuration_t
Expand All @@ -120,6 +121,7 @@ class MemoryPointer
alias read_ccs_parameter_t read_ccs_object_t
alias read_ccs_expression_t read_ccs_object_t
alias read_ccs_context_t read_ccs_object_t
alias read_ccs_distribution_space_t read_ccs_object_t
alias read_ccs_configuration_space_t read_ccs_object_t
alias read_ccs_binding_t read_ccs_object_t
alias read_ccs_configuration_t read_ccs_object_t
Expand Down Expand Up @@ -159,41 +161,43 @@ class MemoryPointer
:CCS_OBJECT_TYPE_TREE_SPACE,
:CCS_OBJECT_TYPE_TREE_CONFIGURATION,
:CCS_OBJECT_TYPE_TREE_EVALUATION,
:CCS_OBJECT_TYPE_TREE_TUNER ]
:CCS_OBJECT_TYPE_TREE_TUNER,
:CCS_OBJECT_TYPE_DISTRIBUTION_SPACE ]

Error = enum FFI::Type::INT32, :ccs_result_t, [
:CCS_RESULT_AGAIN, 1,
:CCS_RESULT_SUCCESS, 0,
:CCS_RESULT_ERROR_INVALID_OBJECT, -1,
:CCS_RESULT_ERROR_INVALID_VALUE, -2,
:CCS_RESULT_ERROR_INVALID_TYPE, -3,
:CCS_RESULT_ERROR_INVALID_SCALE, -4,
:CCS_RESULT_ERROR_INVALID_DISTRIBUTION, -5,
:CCS_RESULT_ERROR_INVALID_EXPRESSION, -6,
:CCS_RESULT_ERROR_INVALID_PARAMETER, -7,
:CCS_RESULT_ERROR_INVALID_CONFIGURATION, -8,
:CCS_RESULT_ERROR_INVALID_NAME, -9,
:CCS_RESULT_ERROR_INVALID_CONDITION, -10,
:CCS_RESULT_ERROR_INVALID_TUNER, -11,
:CCS_RESULT_ERROR_INVALID_GRAPH, -12,
:CCS_RESULT_ERROR_TYPE_NOT_COMPARABLE, -13,
:CCS_RESULT_ERROR_INVALID_BOUNDS, -14,
:CCS_RESULT_ERROR_OUT_OF_BOUNDS, -15,
:CCS_RESULT_ERROR_SAMPLING_UNSUCCESSFUL, -16,
:CCS_RESULT_ERROR_OUT_OF_MEMORY, -17,
:CCS_RESULT_ERROR_UNSUPPORTED_OPERATION, -18,
:CCS_RESULT_ERROR_INVALID_EVALUATION, -19,
:CCS_RESULT_ERROR_INVALID_FEATURES, -20,
:CCS_RESULT_ERROR_INVALID_FEATURES_TUNER, -21,
:CCS_RESULT_ERROR_INVALID_FILE_PATH, -22,
:CCS_RESULT_ERROR_NOT_ENOUGH_DATA, -23,
:CCS_RESULT_ERROR_DUPLICATE_HANDLE, -24,
:CCS_RESULT_ERROR_INVALID_HANDLE, -25,
:CCS_RESULT_ERROR_SYSTEM, -26,
:CCS_RESULT_ERROR_EXTERNAL, -27,
:CCS_RESULT_ERROR_INVALID_TREE, -28,
:CCS_RESULT_ERROR_INVALID_TREE_SPACE, -29,
:CCS_RESULT_ERROR_INVALID_TREE_TUNER, -30 ]
:CCS_RESULT_AGAIN, 1,
:CCS_RESULT_SUCCESS, 0,
:CCS_RESULT_ERROR_INVALID_OBJECT, -1,
:CCS_RESULT_ERROR_INVALID_VALUE, -2,
:CCS_RESULT_ERROR_INVALID_TYPE, -3,
:CCS_RESULT_ERROR_INVALID_SCALE, -4,
:CCS_RESULT_ERROR_INVALID_DISTRIBUTION, -5,
:CCS_RESULT_ERROR_INVALID_EXPRESSION, -6,
:CCS_RESULT_ERROR_INVALID_PARAMETER, -7,
:CCS_RESULT_ERROR_INVALID_CONFIGURATION, -8,
:CCS_RESULT_ERROR_INVALID_NAME, -9,
:CCS_RESULT_ERROR_INVALID_CONDITION, -10,
:CCS_RESULT_ERROR_INVALID_TUNER, -11,
:CCS_RESULT_ERROR_INVALID_GRAPH, -12,
:CCS_RESULT_ERROR_TYPE_NOT_COMPARABLE, -13,
:CCS_RESULT_ERROR_INVALID_BOUNDS, -14,
:CCS_RESULT_ERROR_OUT_OF_BOUNDS, -15,
:CCS_RESULT_ERROR_SAMPLING_UNSUCCESSFUL, -16,
:CCS_RESULT_ERROR_OUT_OF_MEMORY, -17,
:CCS_RESULT_ERROR_UNSUPPORTED_OPERATION, -18,
:CCS_RESULT_ERROR_INVALID_EVALUATION, -19,
:CCS_RESULT_ERROR_INVALID_FEATURES, -20,
:CCS_RESULT_ERROR_INVALID_FEATURES_TUNER, -21,
:CCS_RESULT_ERROR_INVALID_FILE_PATH, -22,
:CCS_RESULT_ERROR_NOT_ENOUGH_DATA, -23,
:CCS_RESULT_ERROR_DUPLICATE_HANDLE, -24,
:CCS_RESULT_ERROR_INVALID_HANDLE, -25,
:CCS_RESULT_ERROR_SYSTEM, -26,
:CCS_RESULT_ERROR_EXTERNAL, -27,
:CCS_RESULT_ERROR_INVALID_TREE, -28,
:CCS_RESULT_ERROR_INVALID_TREE_SPACE, -29,
:CCS_RESULT_ERROR_INVALID_TREE_TUNER, -30,
:CCS_RESULT_ERROR_INVALID_DISTRIBUTION_SPACE, -31 ]

class MemoryPointer
def read_ccs_object_type_t
Expand Down Expand Up @@ -587,7 +591,8 @@ def self.class_map
CCS_OBJECT_TYPE_TREE_SPACE: CCS::TreeSpace,
CCS_OBJECT_TYPE_TREE_CONFIGURATION: CCS::TreeConfiguration,
CCS_OBJECT_TYPE_TREE_EVALUATION: CCS::TreeEvaluation,
CCS_OBJECT_TYPE_TREE_TUNER: CCS::TreeTuner
CCS_OBJECT_TYPE_TREE_TUNER: CCS::TreeTuner,
CCS_OBJECT_TYPE_DISTRIBUTION_SPACE: CCS::DistributionSpace
}
end

Expand Down
Loading

0 comments on commit 23c5f05

Please sign in to comment.