Skip to content

Commit

Permalink
Bindings are now immutable and thus thread safe.
Browse files Browse the repository at this point in the history
  • Loading branch information
Kerilk committed Jul 3, 2023
1 parent 5d58f15 commit 529600e
Show file tree
Hide file tree
Showing 28 changed files with 117 additions and 584 deletions.
29 changes: 4 additions & 25 deletions bindings/python/cconfigspace/binding.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,9 @@

ccs_binding_get_context = _ccs_get_function("ccs_binding_get_context", [ccs_binding, ct.POINTER(ccs_context)])
ccs_binding_get_value = _ccs_get_function("ccs_binding_get_value", [ccs_binding, ct.c_size_t, ct.POINTER(Datum)])
ccs_binding_set_value = _ccs_get_function("ccs_binding_set_value", [ccs_binding, ct.c_size_t, DatumFix])
ccs_binding_get_values = _ccs_get_function("ccs_binding_get_values", [ccs_binding, ct.c_size_t, ct.POINTER(Datum), ct.POINTER(ct.c_size_t)])
ccs_binding_set_values = _ccs_get_function("ccs_binding_set_values", [ccs_binding, ct.c_size_t, ct.POINTER(Datum)])
ccs_binding_get_value_by_name = _ccs_get_function("ccs_binding_get_value_by_name", [ccs_binding, ct.c_char_p, ct.POINTER(Datum)])
ccs_binding_set_value_by_name = _ccs_get_function("ccs_binding_set_value_by_name", [ccs_binding, ct.c_char_p, DatumFix])
ccs_binding_get_value_by_parameter = _ccs_get_function("ccs_binding_get_value_by_parameter", [ccs_binding, ccs_parameter, ct.POINTER(Datum)])
ccs_binding_set_value_by_parameter = _ccs_get_function("ccs_binding_set_value_by_parameter", [ccs_binding, ccs_parameter, DatumFix])
ccs_binding_hash = _ccs_get_function("ccs_binding_hash", [ccs_binding, ct.POINTER(ccs_hash)])
ccs_binding_cmp = _ccs_get_function("ccs_binding_cmp", [ccs_binding, ccs_binding, ct.POINTER(ct.c_int)])

Expand All @@ -36,17 +32,6 @@ def num_values(self):
self._num_values = v.value
return self._num_values

def set_value(self, parameter, value):
pv = Datum(value)
v = DatumFix(pv)
if isinstance(parameter, Parameter):
res = ccs_binding_set_value_by_parameter(self.handle, parameter.handle, v)
elif isinstance(parameter, str):
res = ccs_binding_set_value_by_name(self.handle, str.encode(parameter), ct.byref(v))
else:
res = ccs_binding_set_value(self.handle, parameter, v)
Error.check(res)

def value(self, parameter):
v = Datum()
if isinstance(parameter, Parameter):
Expand All @@ -60,22 +45,16 @@ def value(self, parameter):

@property
def values(self):
if hasattr(self, "_values"):
return self._values
sz = self.num_values
if sz == 0:
return []
v = (Datum * sz)()
res = ccs_binding_get_values(self.handle, sz, v, None)
Error.check(res)
return [x.value for x in v]

def set_values(self, values):
sz = len(values)
v = (Datum*sz)()
ss = []
for i in range(sz):
v[i].set_value(values[i], string_store = ss)
res = ccs_binding_set_values(self.handle, sz, v)
Error.check(res)
self._values = tuple(x.value for x in v)
return self._values

def cmp(self, other):
v = ct.c_int()
Expand Down
16 changes: 8 additions & 8 deletions bindings/python/cconfigspace/evaluation.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ class Comparison(CEnumeration):
ccs_evaluation_get_objective_space = _ccs_get_function("ccs_evaluation_get_objective_space", [ccs_evaluation, ct.POINTER(ccs_objective_space)])
ccs_evaluation_get_configuration = _ccs_get_function("ccs_evaluation_get_configuration", [ccs_evaluation, ct.POINTER(ccs_configuration)])
ccs_evaluation_get_result = _ccs_get_function("ccs_evaluation_get_result", [ccs_evaluation, ct.POINTER(ccs_evaluation_result)])
ccs_evaluation_set_result = _ccs_get_function("ccs_evaluation_set_result", [ccs_evaluation, ccs_evaluation_result])
ccs_evaluation_get_objective_value = _ccs_get_function("ccs_evaluation_get_objective_value", [ccs_evaluation, ct.c_size_t, ct.POINTER(Datum)])
ccs_evaluation_get_objective_values = _ccs_get_function("ccs_evaluation_get_objective_values", [ccs_evaluation, ct.c_size_t, ct.POINTER(Datum), ct.POINTER(ct.c_size_t)])
ccs_evaluation_compare = _ccs_get_function("ccs_evaluation_compare", [ccs_evaluation, ccs_evaluation, ct.POINTER(Comparison)])
Expand Down Expand Up @@ -67,15 +66,13 @@ def configuration(self):

@property
def result(self):
if hasattr(self, "_result"):
return self._result
v = ccs_evaluation_result()
res = ccs_evaluation_get_result(self.handle, ct.byref(v))
Error.check(res)
return v.value

@result.setter
def result(self, v):
res = ccs_evaluation_set_result(self.handle, v)
Error.check(res)
self._result = v.value
return self._result

@property
def num_objective_values(self):
Expand All @@ -89,13 +86,16 @@ def num_objective_values(self):

@property
def objective_values(self):
if hasattr(self, "_objective_values"):
return self._objective_values
sz = self.num_objective_values
if sz == 0:
return []
v = (Datum * sz)()
res = ccs_evaluation_get_objective_values(self.handle, sz, v, None)
Error.check(res)
return [x.value for x in v]
self._objective_values = tuple(x.value for x in v)
return self._objective_values

def compare(self, other):
v = Comparison(0)
Expand Down
16 changes: 8 additions & 8 deletions bindings/python/cconfigspace/features_evaluation.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
ccs_features_evaluation_get_configuration = _ccs_get_function("ccs_features_evaluation_get_configuration", [ccs_features_evaluation, ct.POINTER(ccs_configuration)])
ccs_features_evaluation_get_features = _ccs_get_function("ccs_features_evaluation_get_features", [ccs_features_evaluation, ct.POINTER(ccs_features)])
ccs_features_evaluation_get_result = _ccs_get_function("ccs_features_evaluation_get_result", [ccs_features_evaluation, ct.POINTER(ccs_evaluation_result)])
ccs_features_evaluation_set_result = _ccs_get_function("ccs_features_evaluation_set_result", [ccs_features_evaluation, ccs_evaluation_result])
ccs_features_evaluation_get_objective_value = _ccs_get_function("ccs_features_evaluation_get_objective_value", [ccs_features_evaluation, ct.c_size_t, ct.POINTER(Datum)])
ccs_features_evaluation_get_objective_values = _ccs_get_function("ccs_features_evaluation_get_objective_values", [ccs_features_evaluation, ct.c_size_t, ct.POINTER(Datum), ct.POINTER(ct.c_size_t)])
ccs_features_evaluation_compare = _ccs_get_function("ccs_features_evaluation_compare", [ccs_features_evaluation, ccs_features_evaluation, ct.POINTER(Comparison)])
Expand Down Expand Up @@ -77,15 +76,13 @@ def features(self):

@property
def result(self):
if hasattr(self, "_result"):
return self._result
v = ccs_evaluation_result()
res = ccs_features_evaluation_get_result(self.handle, ct.byref(v))
Error.check(res)
return v.value

@result.setter
def result(self, v):
res = ccs_features_evaluation_set_result(self.handle, v)
Error.check(res)
self._result = v.value
return self._result

@property
def num_objective_values(self):
Expand All @@ -99,13 +96,16 @@ def num_objective_values(self):

@property
def objective_values(self):
if hasattr(self, "_objective_values"):
return self._objective_values
sz = self.num_objective_values
if sz == 0:
return []
v = (Datum * sz)()
res = ccs_features_evaluation_get_objective_values(self.handle, sz, v, None)
Error.check(res)
return [x.value for x in v]
self._objective_values = tuple(x.value for x in v)
return self._objective_values

def compare(self, other):
v = Comparison(0)
Expand Down
16 changes: 8 additions & 8 deletions bindings/python/cconfigspace/tree_evaluation.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
ccs_tree_evaluation_get_objective_space = _ccs_get_function("ccs_tree_evaluation_get_objective_space", [ccs_tree_evaluation, ct.POINTER(ccs_objective_space)])
ccs_tree_evaluation_get_configuration = _ccs_get_function("ccs_tree_evaluation_get_configuration", [ccs_tree_evaluation, ct.POINTER(ccs_tree_configuration)])
ccs_tree_evaluation_get_result = _ccs_get_function("ccs_tree_evaluation_get_result", [ccs_tree_evaluation, ct.POINTER(ccs_evaluation_result)])
ccs_tree_evaluation_set_result = _ccs_get_function("ccs_tree_evaluation_set_result", [ccs_tree_evaluation, ccs_evaluation_result])
ccs_tree_evaluation_get_objective_value = _ccs_get_function("ccs_tree_evaluation_get_objective_value", [ccs_tree_evaluation, ct.c_size_t, ct.POINTER(Datum)])
ccs_tree_evaluation_get_objective_values = _ccs_get_function("ccs_tree_evaluation_get_objective_values", [ccs_tree_evaluation, ct.c_size_t, ct.POINTER(Datum), ct.POINTER(ct.c_size_t)])
ccs_tree_evaluation_compare = _ccs_get_function("ccs_tree_evaluation_compare", [ccs_tree_evaluation, ccs_tree_evaluation, ct.POINTER(Comparison)])
Expand Down Expand Up @@ -61,15 +60,13 @@ def configuration(self):

@property
def result(self):
if hasattr(self, "_result"):
return self._result
v = ccs_evaluation_result()
res = ccs_tree_evaluation_get_result(self.handle, ct.byref(v))
Error.check(res)
return v.value

@result.setter
def result(self, v):
res = ccs_tree_evaluation_set_result(self.handle, v)
Error.check(res)
self._result = v.value
return self._result

@property
def num_objective_values(self):
Expand All @@ -83,13 +80,16 @@ def num_objective_values(self):

@property
def objective_values(self):
if hasattr(self, "_objective_values"):
return self._objective_values
sz = self.num_objective_values
if sz == 0:
return []
v = (Datum * sz)()
res = ccs_tree_evaluation_get_objective_values(self.handle, sz, v, None)
Error.check(res)
return [x.value for x in v]
self._objective_values = tuple(x.value for x in v)
return self._objective_values

def compare(self, other):
v = Comparison(0)
Expand Down
20 changes: 9 additions & 11 deletions bindings/python/test/test_evaluation.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,23 +17,21 @@ def test_create(self):
e1 = ccs.Expression.Variable(parameter = v1)
e2 = ccs.Expression.Variable(parameter = v2)
os.add_objectives( { e1: ccs.ObjectiveType.MAXIMIZE, e2: ccs.ObjectiveType.MINIMIZE } )
ev1 = ccs.Evaluation(objective_space = os, configuration = cs.sample())
ev1.set_value(0, 0.5)
ev1.set_value(v2, 0.6)
self.assertEqual( [0.5, 0.6], ev1.values )
self.assertEqual( [0.5, 0.6], ev1.objective_values )
ev1 = ccs.Evaluation(objective_space = os, configuration = cs.sample(), values = [0.5, 0.6])
self.assertEqual( (0.5, 0.6), ev1.values )
self.assertEqual( (0.5, 0.6), ev1.objective_values )
self.assertTrue( ev1.check )
self.assertTrue( os.check_values(ev1.values) )
ev2 = ccs.Evaluation(objective_space = os, configuration = cs.sample(), values = [0.5, 0.6])
self.assertEqual( [0.5, 0.6], ev2.values )
self.assertEqual( [0.5, 0.6], ev2.objective_values )
self.assertEqual( (0.5, 0.6), ev2.values )
self.assertEqual( (0.5, 0.6), ev2.objective_values )
self.assertEqual( ccs.Comparison.EQUIVALENT, ev1.compare(ev2) )
ev3 = ccs.Evaluation(objective_space = os, configuration = cs.sample(), values = [0.6, 0.5])
self.assertEqual( [0.6, 0.5], ev3.objective_values )
self.assertEqual( (0.6, 0.5), ev3.objective_values )
self.assertEqual( ccs.Comparison.WORSE, ev1.compare(ev3) )
self.assertEqual( ccs.Comparison.BETTER, ev3.compare(ev1) )
ev4 = ccs.Evaluation(objective_space = os, configuration = cs.sample(), values = [0.6, 0.7])
self.assertEqual( [0.6, 0.7], ev4.objective_values )
self.assertEqual( (0.6, 0.7), ev4.objective_values )
self.assertEqual( ccs.Comparison.NOT_COMPARABLE, ev1.compare(ev4) )
self.assertEqual( ccs.Comparison.NOT_COMPARABLE, ev4.compare(ev1) )

Expand All @@ -56,8 +54,8 @@ def test_serialize(self):
ev = ccs.deserialize(buffer = buff, handle_map = handle_map)
self.assertEqual( cs.handle.value, ev.configuration.configuration_space.handle.value)
self.assertEqual( os.handle.value, ev.objective_space.handle.value)
self.assertEqual( [0.5, 0.6], ev.values )
self.assertEqual( [0.5, 0.6], ev.objective_values )
self.assertEqual( (0.5, 0.6), ev.values )
self.assertEqual( (0.5, 0.6), ev.objective_values )

if __name__ == '__main__':
unittest.main()
20 changes: 9 additions & 11 deletions bindings/python/test/test_tree_evaluation.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,23 +24,21 @@ def test_create(self):
e1 = ccs.Expression.Variable(parameter = v1)
e2 = ccs.Expression.Variable(parameter = v2)
os.add_objectives( { e1: ccs.ObjectiveType.MAXIMIZE, e2: ccs.ObjectiveType.MINIMIZE } )
ev1 = ccs.TreeEvaluation(objective_space = os, configuration = ts.sample())
ev1.set_value(0, 0.5)
ev1.set_value(v2, 0.6)
self.assertEqual( [0.5, 0.6], ev1.values )
self.assertEqual( [0.5, 0.6], ev1.objective_values )
ev1 = ccs.TreeEvaluation(objective_space = os, configuration = ts.sample(), values = [0.5, 0.6])
self.assertEqual( (0.5, 0.6), ev1.values )
self.assertEqual( (0.5, 0.6), ev1.objective_values )
self.assertTrue( ev1.check )
self.assertTrue( os.check_values(ev1.values) )
ev2 = ccs.TreeEvaluation(objective_space = os, configuration = ts.sample(), values = [0.5, 0.6])
self.assertEqual( [0.5, 0.6], ev2.values )
self.assertEqual( [0.5, 0.6], ev2.objective_values )
self.assertEqual( (0.5, 0.6), ev2.values )
self.assertEqual( (0.5, 0.6), ev2.objective_values )
self.assertEqual( ccs.Comparison.EQUIVALENT, ev1.compare(ev2) )
ev3 = ccs.TreeEvaluation(objective_space = os, configuration = ts.sample(), values = [0.6, 0.5])
self.assertEqual( [0.6, 0.5], ev3.objective_values )
self.assertEqual( (0.6, 0.5), ev3.objective_values )
self.assertEqual( ccs.Comparison.WORSE, ev1.compare(ev3) )
self.assertEqual( ccs.Comparison.BETTER, ev3.compare(ev1) )
ev4 = ccs.TreeEvaluation(objective_space = os, configuration = ts.sample(), values = [0.6, 0.7])
self.assertEqual( [0.6, 0.7], ev4.objective_values )
self.assertEqual( (0.6, 0.7), ev4.objective_values )
self.assertEqual( ccs.Comparison.NOT_COMPARABLE, ev1.compare(ev4) )
self.assertEqual( ccs.Comparison.NOT_COMPARABLE, ev4.compare(ev1) )

Expand All @@ -61,8 +59,8 @@ def test_serialize(self):
ev = ccs.deserialize(buffer = buff, handle_map = handle_map)
self.assertEqual( ts.handle.value, ev.configuration.tree_space.handle.value)
self.assertEqual( os.handle.value, ev.objective_space.handle.value)
self.assertEqual( [0.5, 0.6], ev.values )
self.assertEqual( [0.5, 0.6], ev.objective_values )
self.assertEqual( (0.5, 0.6), ev.values )
self.assertEqual( (0.5, 0.6), ev.objective_values )

if __name__ == '__main__':
unittest.main()
44 changes: 7 additions & 37 deletions bindings/ruby/lib/cconfigspace/binding.rb
Original file line number Diff line number Diff line change
@@ -1,13 +1,9 @@
module CCS
attach_function :ccs_binding_get_context, [:ccs_binding_t, :pointer], :ccs_result_t
attach_function :ccs_binding_get_value, [:ccs_binding_t, :size_t, :pointer], :ccs_result_t
attach_function :ccs_binding_set_value, [:ccs_binding_t, :size_t, :ccs_datum_t], :ccs_result_t
attach_function :ccs_binding_get_values, [:ccs_binding_t, :size_t, :pointer, :pointer], :ccs_result_t
attach_function :ccs_binding_set_values, [:ccs_binding_t, :size_t, :pointer], :ccs_result_t
attach_function :ccs_binding_get_value_by_name, [:ccs_binding_t, :string, :pointer], :ccs_result_t
attach_function :ccs_binding_set_value_by_name, [:ccs_binding_t, :string, :ccs_datum_t], :ccs_result_t
attach_function :ccs_binding_get_value_by_parameter, [:ccs_binding_t, :ccs_parameter_t, :pointer], :ccs_result_t
attach_function :ccs_binding_set_value_by_parameter, [:ccs_binding_t, :ccs_parameter_t, :ccs_datum_t], :ccs_result_t
attach_function :ccs_binding_hash, [:ccs_binding_t, :pointer], :ccs_result_t
attach_function :ccs_binding_cmp, [:ccs_binding_t, :ccs_binding_t, :pointer], :ccs_result_t

Expand All @@ -16,24 +12,6 @@ class Binding < Object
add_property :hash, :ccs_hash_t, :ccs_binding_hash, memoize: false
add_handle_property :context, :ccs_context_t, :ccs_binding_get_context, memoize: true

def set_value(parameter, value)
d = Datum.from_value(value)
case parameter
when String
CCS.error_check CCS.ccs_binding_set_value_by_name(@handle, parameter, d)
when Symbol
name = parameter.inspect
CCS.error_check CCS.ccs_binding_set_value_by_name(@handle, name, d)
when Parameter
CCS.error_check CCS.ccs_binding_set_value_by_parameter(@handle, parameter.handle, d)
when Integer
CCS.error_check CCS.ccs_binding_set_value(@handle, parameter, d)
else
raise CCSError, :CCS_RESULT_ERROR_INVALID_VALUE
end
self
end

def value(parameter)
ptr = MemoryPointer::new(:ccs_datum_t)
case parameter
Expand All @@ -53,21 +31,13 @@ def value(parameter)
end

def values
count = num_values
return [] if count == 0
values = MemoryPointer::new(:ccs_datum_t, count)
CCS.error_check CCS.ccs_binding_get_values(@handle, count, values, nil)
count.times.collect { |i| Datum::new(values[i]).value }
end

def set_values(values)
count = values.size
raise CCSError, :CCS_RESULT_ERROR_INVALID_VALUE if count == 0
ss = []
vals = MemoryPointer::new(:ccs_datum_t, count)
values.each_with_index{ |v, i| Datum::new(vals[i]).set_value(v, string_store: ss) }
CCS.error_check CCS.ccs_binding_set_values(@handle, count, vals)
self
@values ||= begin
count = num_values
return [] if count == 0
values = MemoryPointer::new(:ccs_datum_t, count)
CCS.error_check CCS.ccs_binding_get_values(@handle, count, values, nil)
count.times.collect { |i| Datum::new(values[i]).value }.freeze
end
end

def num_values
Expand Down
20 changes: 8 additions & 12 deletions bindings/ruby/lib/cconfigspace/evaluation.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,14 @@ def read_ccs_comparison_t
attach_function :ccs_create_evaluation, [:ccs_objective_space_t, :ccs_configuration_t, :ccs_evaluation_result_t, :size_t, :pointer, :pointer], :ccs_result_t
attach_function :ccs_evaluation_get_configuration, [:ccs_evaluation_t, :pointer], :ccs_result_t
attach_function :ccs_evaluation_get_result, [:ccs_evaluation_t, :pointer], :ccs_result_t
attach_function :ccs_evaluation_set_result, [:ccs_evaluation_t, :ccs_evaluation_result_t], :ccs_result_t
attach_function :ccs_evaluation_get_objective_values, [:ccs_evaluation_t, :size_t, :pointer, :pointer], :ccs_result_t
attach_function :ccs_evaluation_compare, [:ccs_evaluation_t, :ccs_evaluation_t, :pointer], :ccs_result_t
attach_function :ccs_evaluation_check, [:ccs_evaluation_t, :pointer], :ccs_result_t

class Evaluation < Binding
alias objective_space context
add_handle_property :configuration, :ccs_configuration_t, :ccs_evaluation_get_configuration, memoize: true
add_property :result, :ccs_evaluation_result_t, :ccs_evaluation_get_result, memoize: false
add_property :result, :ccs_evaluation_result_t, :ccs_evaluation_get_result, memoize: true

def initialize(handle = nil, retain: false, auto_release: true,
objective_space: nil, configuration: nil, result: :CCS_RESULT_SUCCESS, values: nil)
Expand Down Expand Up @@ -51,11 +50,6 @@ def self.from_handle(handle, retain: true, auto_release: true)
self::new(handle, retain: retain, auto_release: auto_release)
end

def result=(res)
CCS.error_check CCS.ccs_evaluation_set_result(@handle, res)
res
end

def num_objective_values
@num_objective_values ||= begin
ptr = MemoryPointer::new(:size_t)
Expand All @@ -65,11 +59,13 @@ def num_objective_values
end

def objective_values
count = num_objective_values
return [] if count == 0
values = MemoryPointer::new(:ccs_datum_t, count)
CCS.error_check CCS.ccs_evaluation_get_objective_values(@handle, count, values, nil)
count.times.collect { |i| Datum::new(values[i]).value }
@objective_values ||= begin
count = num_objective_values
return [] if count == 0
values = MemoryPointer::new(:ccs_datum_t, count)
CCS.error_check CCS.ccs_evaluation_get_objective_values(@handle, count, values, nil)
count.times.collect { |i| Datum::new(values[i]).value }.freeze
end
end

def check
Expand Down
Loading

0 comments on commit 529600e

Please sign in to comment.