From 1c501b039e310b73736b851632a4d7a52b3622c4 Mon Sep 17 00:00:00 2001 From: Brice Videau Date: Fri, 22 Mar 2024 18:25:05 -0500 Subject: [PATCH] Refactoring evaluations. --- bindings/python/cconfigspace/__init__.py | 1 + bindings/python/cconfigspace/base.py | 1 + bindings/python/cconfigspace/evaluation.py | 73 +------ .../python/cconfigspace/evaluation_binding.py | 72 +++++++ .../cconfigspace/features_evaluation.py | 71 +------ .../python/cconfigspace/tree_evaluation.py | 67 +----- bindings/ruby/lib/cconfigspace.rb | 1 + bindings/ruby/lib/cconfigspace/base.rb | 2 + bindings/ruby/lib/cconfigspace/evaluation.rb | 57 +----- .../lib/cconfigspace/evaluation_binding.rb | 60 ++++++ .../lib/cconfigspace/features_evaluation.rb | 43 +--- .../ruby/lib/cconfigspace/tree_evaluation.rb | 43 +--- include/cconfigspace.h | 1 + include/cconfigspace/base.h | 4 + include/cconfigspace/evaluation.h | 163 +-------------- include/cconfigspace/evaluation_binding.h | 178 ++++++++++++++++ include/cconfigspace/features_evaluation.h | 142 +------------ include/cconfigspace/objective_space.h | 12 +- include/cconfigspace/tree_evaluation.h | 144 +------------ samples/test_python.c | 6 +- samples/test_ruby.c | 6 +- src/Makefile.am | 2 + src/cconfigspace_internal.h | 2 +- src/evaluation.c | 175 ++-------------- src/evaluation_binding.c | 122 +++++++++++ src/evaluation_binding_internal.h | 92 +++++++++ src/evaluation_internal.h | 5 + src/features_evaluation.c | 193 +++--------------- src/features_evaluation_internal.h | 5 + src/features_tuner_random.c | 11 +- src/objective_space.c | 16 +- src/tree_evaluation.c | 178 ++-------------- src/tree_evaluation_internal.h | 5 + src/tree_tuner_random.c | 11 +- src/tuner_random.c | 11 +- tests/test_random_features_tuner.c | 14 +- tests/test_random_tree_tuner.c | 7 +- tests/test_random_tuner.c | 6 +- 38 files changed, 685 insertions(+), 1317 deletions(-) create mode 100644 bindings/python/cconfigspace/evaluation_binding.py create mode 100644 bindings/ruby/lib/cconfigspace/evaluation_binding.rb create mode 100644 include/cconfigspace/evaluation_binding.h create mode 100644 src/evaluation_binding.c create mode 100644 src/evaluation_binding_internal.h diff --git a/bindings/python/cconfigspace/__init__.py b/bindings/python/cconfigspace/__init__.py index ca36a49c..446aa70a 100644 --- a/bindings/python/cconfigspace/__init__.py +++ b/bindings/python/cconfigspace/__init__.py @@ -26,6 +26,7 @@ from .features_space import * from .features import * from .objective_space import * +from .evaluation_binding import * from .evaluation import * from .features_evaluation import * from .tuner import * diff --git a/bindings/python/cconfigspace/base.py b/bindings/python/cconfigspace/base.py index 4369698d..6617ae3c 100644 --- a/bindings/python/cconfigspace/base.py +++ b/bindings/python/cconfigspace/base.py @@ -34,6 +34,7 @@ def __str__(self): ccs_features_space = ccs_object ccs_features = ccs_object ccs_objective_space = ccs_object +ccs_evaluation_binding = ccs_object ccs_evaluation = ccs_object ccs_features_evaluation = ccs_object ccs_tuner = ccs_object diff --git a/bindings/python/cconfigspace/evaluation.py b/bindings/python/cconfigspace/evaluation.py index 35e77ed5..0a79c038 100644 --- a/bindings/python/cconfigspace/evaluation.py +++ b/bindings/python/cconfigspace/evaluation.py @@ -1,26 +1,12 @@ import ctypes as ct -from .base import Object, Error, CEnumeration, Result, ccs_evaluation_result, _ccs_get_function, ccs_context, ccs_parameter, ccs_configuration, Datum, DatumFix, ccs_objective_space, ccs_evaluation, ccs_bool -from .binding import Binding +from .base import Error, Datum, Result, _ccs_get_function, ccs_configuration, ccs_evaluation, ccs_objective_space, ccs_evaluation_result +from .evaluation_binding import EvaluationBinding from .configuration import Configuration -from .objective_space import ObjectiveSpace - -class Comparison(CEnumeration): - _members_ = [ - ('BETTER', -1), - ('EQUIVALENT', 0), - ('WORSE', 1), - ('NOT_COMPARABLE', 2) ] ccs_create_evaluation = _ccs_get_function("ccs_create_evaluation", [ccs_objective_space, ccs_configuration, ccs_evaluation_result, ct.c_size_t, ct.POINTER(Datum), ct.POINTER(ccs_evaluation)]) -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_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)]) -ccs_evaluation_check = _ccs_get_function("ccs_evaluation_check", [ccs_evaluation, ct.POINTER(ccs_bool)]) -class Evaluation(Binding): +class Evaluation(EvaluationBinding): def __init__(self, handle = None, retain = False, auto_release = True, objective_space = None, configuration = None, result = Result.SUCCESS, values = None): if handle is None: @@ -44,16 +30,6 @@ def __init__(self, handle = None, retain = False, auto_release = True, def from_handle(cls, handle, retain = True, auto_release = True): return cls(handle = handle, retain = retain, auto_release = auto_release) - @property - def objective_space(self): - if hasattr(self, "_objective_space"): - return self._objective_space - v = ccs_objective_space() - res = ccs_evaluation_get_objective_space(self.handle, ct.byref(v)) - Error.check(res) - self._objective_space = ObjectiveSpace.from_handle(v) - return self._objective_space - @property def configuration(self): if hasattr(self, "_configuration"): @@ -63,46 +39,3 @@ def configuration(self): Error.check(res) self._configuration = Configuration.from_handle(v) return self._configuration - - @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) - self._result = v.value - return self._result - - @property - def num_objective_values(self): - if hasattr(self, "_num_objective_values"): - return self._num_objective_values - v = ct.c_size_t() - res = ccs_evaluation_get_objective_values(self.handle, 0, None, ct.byref(v)) - Error.check(res) - self._num_objective_values = v.value - return self._num_objective_values - - @property - def objective_values(self): - if hasattr(self, "_objective_values"): - return self._objective_values - sz = self.num_objective_values - v = (Datum * sz)() - res = ccs_evaluation_get_objective_values(self.handle, sz, v, None) - Error.check(res) - self._objective_values = tuple(x.value for x in v) - return self._objective_values - - def compare(self, other): - v = Comparison(0) - res = ccs_evaluation_compare(self.handle, other.handle, ct.byref(v)) - Error.check(res) - return v.value - - def check(self): - valid = ccs_bool() - res = ccs_evaluation_check(self.handle, ct.byref(valid)) - Error.check(res) - return False if valid.value == 0 else True diff --git a/bindings/python/cconfigspace/evaluation_binding.py b/bindings/python/cconfigspace/evaluation_binding.py new file mode 100644 index 00000000..0a635367 --- /dev/null +++ b/bindings/python/cconfigspace/evaluation_binding.py @@ -0,0 +1,72 @@ +import ctypes as ct +from .base import Error, CEnumeration, Result, ccs_evaluation_result, _ccs_get_function, Datum, DatumFix, ccs_evaluation_binding, ccs_objective_space, ccs_bool +from .binding import Binding +from .objective_space import ObjectiveSpace + +class Comparison(CEnumeration): + _members_ = [ + ('BETTER', -1), + ('EQUIVALENT', 0), + ('WORSE', 1), + ('NOT_COMPARABLE', 2) ] + +ccs_evaluation_binding_get_objective_space = _ccs_get_function("ccs_evaluation_binding_get_objective_space", [ccs_evaluation_binding, ct.POINTER(ccs_objective_space)]) +ccs_evaluation_binding_get_result = _ccs_get_function("ccs_evaluation_binding_get_result", [ccs_evaluation_binding, ct.POINTER(ccs_evaluation_result)]) +ccs_evaluation_binding_get_objective_values = _ccs_get_function("ccs_evaluation_binding_get_objective_values", [ccs_evaluation_binding, ct.c_size_t, ct.POINTER(Datum), ct.POINTER(ct.c_size_t)]) +ccs_evaluation_binding_compare = _ccs_get_function("ccs_evaluation_binding_compare", [ccs_evaluation_binding, ccs_evaluation_binding, ct.POINTER(Comparison)]) +ccs_evaluation_binding_check = _ccs_get_function("ccs_evaluation_binding_check", [ccs_evaluation_binding, ct.POINTER(ccs_bool)]) + +class EvaluationBinding(Binding): + + @property + def objective_space(self): + if hasattr(self, "_objective_space"): + return self._objective_space + v = ccs_objective_space() + res = ccs_evaluation_binding_get_objective_space(self.handle, ct.byref(v)) + Error.check(res) + self._objective_space = ObjectiveSpace.from_handle(v) + return self._objective_space + + @property + def result(self): + if hasattr(self, "_result"): + return self._result + v = ccs_evaluation_result() + res = ccs_evaluation_binding_get_result(self.handle, ct.byref(v)) + Error.check(res) + self._result = v.value + return self._result + + @property + def num_objective_values(self): + if hasattr(self, "_num_objective_values"): + return self._num_objective_values + v = ct.c_size_t() + res = ccs_evaluation_binding_get_objective_values(self.handle, 0, None, ct.byref(v)) + Error.check(res) + self._num_objective_values = v.value + return self._num_objective_values + + @property + def objective_values(self): + if hasattr(self, "_objective_values"): + return self._objective_values + sz = self.num_objective_values + v = (Datum * sz)() + res = ccs_evaluation_binding_get_objective_values(self.handle, sz, v, None) + Error.check(res) + self._objective_values = tuple(x.value for x in v) + return self._objective_values + + def compare(self, other): + v = Comparison(0) + res = ccs_evaluation_binding_compare(self.handle, other.handle, ct.byref(v)) + Error.check(res) + return v.value + + def check(self): + valid = ccs_bool() + res = ccs_evaluation_binding_check(self.handle, ct.byref(valid)) + Error.check(res) + return False if valid.value == 0 else True diff --git a/bindings/python/cconfigspace/features_evaluation.py b/bindings/python/cconfigspace/features_evaluation.py index 225ed664..f5c08439 100644 --- a/bindings/python/cconfigspace/features_evaluation.py +++ b/bindings/python/cconfigspace/features_evaluation.py @@ -1,26 +1,14 @@ import ctypes as ct -from .base import Object, Error, CEnumeration, Result, ccs_evaluation_result, _ccs_get_function, ccs_context, ccs_parameter, ccs_configuration_space, ccs_configuration, ccs_features_space, ccs_features, Datum, DatumFix, ccs_objective_space, ccs_features_evaluation, ccs_bool -from .context import Context -from .parameter import Parameter -from .configuration_space import ConfigurationSpace +from .base import Error, Datum, Result, _ccs_get_function, ccs_configuration, ccs_features, ccs_features_evaluation, ccs_objective_space, ccs_evaluation_result +from .evaluation_binding import EvaluationBinding from .configuration import Configuration -from .features_space import FeaturesSpace from .features import Features -from .objective_space import ObjectiveSpace -from .evaluation import Comparison -from .binding import Binding ccs_create_features_evaluation = _ccs_get_function("ccs_create_features_evaluation", [ccs_objective_space, ccs_configuration, ccs_features, ccs_evaluation_result, ct.c_size_t, ct.POINTER(Datum), ct.POINTER(ccs_features_evaluation)]) -ccs_features_evaluation_get_objective_space = _ccs_get_function("ccs_features_evaluation_get_objective_space", [ccs_features_evaluation, ct.POINTER(ccs_objective_space)]) 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_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)]) -ccs_features_evaluation_check = _ccs_get_function("ccs_features_evaluation_check", [ccs_features_evaluation, ct.POINTER(ccs_bool)]) -class FeaturesEvaluation(Binding): +class FeaturesEvaluation(EvaluationBinding): def __init__(self, handle = None, retain = False, auto_release = True, objective_space = None, configuration = None, features = None, result = Result.SUCCESS, values = None): if handle is None: @@ -44,16 +32,6 @@ def __init__(self, handle = None, retain = False, auto_release = True, def from_handle(cls, handle, retain = True, auto_release = True): return cls(handle = handle, retain = retain, auto_release = auto_release) - @property - def objective_space(self): - if hasattr(self, "_objective_space"): - return self._objective_space - v = ccs_objective_space() - res = ccs_features_evaluation_get_objective_space(self.handle, ct.byref(v)) - Error.check(res) - self._objective_space = ObjectiveSpace.from_handle(v) - return self._objective_space - @property def configuration(self): if hasattr(self, "_configuration"): @@ -73,46 +51,3 @@ def features(self): Error.check(res) self._features = Features.from_handle(v) return self._features - - @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) - self._result = v.value - return self._result - - @property - def num_objective_values(self): - if hasattr(self, "_num_objective_values"): - return self._num_objective_values - v = ct.c_size_t() - res = ccs_features_evaluation_get_objective_values(self.handle, 0, None, ct.byref(v)) - Error.check(res) - self._num_objective_values = v.value - return self._num_objective_values - - @property - def objective_values(self): - if hasattr(self, "_objective_values"): - return self._objective_values - sz = self.num_objective_values - v = (Datum * sz)() - res = ccs_features_evaluation_get_objective_values(self.handle, sz, v, None) - Error.check(res) - self._objective_values = tuple(x.value for x in v) - return self._objective_values - - def compare(self, other): - v = Comparison(0) - res = ccs_features_evaluation_compare(self.handle, other.handle, ct.byref(v)) - Error.check(res) - return v.value - - def check(self): - valid = ccs_bool() - res = res = ccs_features_evaluation(self.handle, ct.byref(valid)) - Error.check(res) - return False if valid.value == 0 else True diff --git a/bindings/python/cconfigspace/tree_evaluation.py b/bindings/python/cconfigspace/tree_evaluation.py index 8459e45d..6c6c8bf0 100644 --- a/bindings/python/cconfigspace/tree_evaluation.py +++ b/bindings/python/cconfigspace/tree_evaluation.py @@ -1,20 +1,12 @@ import ctypes as ct -from .base import Object, Error, CEnumeration, Result, ccs_evaluation_result, _ccs_get_function, ccs_context, ccs_parameter, ccs_tree_configuration, Datum, DatumFix, ccs_objective_space, ccs_tree_evaluation, ccs_bool -from .evaluation import Comparison -from .binding import Binding +from .base import Error, Datum, Result, _ccs_get_function, ccs_tree_configuration, ccs_tree_evaluation, ccs_objective_space, ccs_evaluation_result +from .evaluation_binding import EvaluationBinding from .tree_configuration import TreeConfiguration -from .objective_space import ObjectiveSpace ccs_create_tree_evaluation = _ccs_get_function("ccs_create_tree_evaluation", [ccs_objective_space, ccs_tree_configuration, ccs_evaluation_result, ct.c_size_t, ct.POINTER(Datum), ct.POINTER(ccs_tree_evaluation)]) -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_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)]) -ccs_tree_evaluation_check = _ccs_get_function("ccs_tree_evaluation_check", [ccs_tree_evaluation, ct.POINTER(ccs_bool)]) -class TreeEvaluation(Binding): +class TreeEvaluation(EvaluationBinding): def __init__(self, handle = None, retain = False, auto_release = True, objective_space = None, configuration = None, result = Result.SUCCESS, values = None): if handle is None: @@ -38,16 +30,6 @@ def __init__(self, handle = None, retain = False, auto_release = True, def from_handle(cls, handle, retain = True, auto_release = True): return cls(handle = handle, retain = retain, auto_release = auto_release) - @property - def objective_space(self): - if hasattr(self, "_objective_space"): - return self._objective_space - v = ccs_objective_space() - res = ccs_tree_evaluation_get_objective_space(self.handle, ct.byref(v)) - Error.check(res) - self._objective_space = ObjectiveSpace.from_handle(v) - return self._objective_space - @property def configuration(self): if hasattr(self, "_configuration"): @@ -57,46 +39,3 @@ def configuration(self): Error.check(res) self._configuration = TreeConfiguration.from_handle(v) return self._configuration - - @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) - self._result = v.value - return self._result - - @property - def num_objective_values(self): - if hasattr(self, "_num_objective_values"): - return self._num_objective_values - v = ct.c_size_t() - res = ccs_tree_evaluation_get_objective_values(self.handle, 0, None, ct.byref(v)) - Error.check(res) - self._num_objective_values = v.value - return self._num_objective_values - - @property - def objective_values(self): - if hasattr(self, "_objective_values"): - return self._objective_values - sz = self.num_objective_values - v = (Datum * sz)() - res = ccs_tree_evaluation_get_objective_values(self.handle, sz, v, None) - Error.check(res) - self._objective_values = tuple(x.value for x in v) - return self._objective_values - - def compare(self, other): - v = Comparison(0) - res = ccs_tree_evaluation_compare(self.handle, other.handle, ct.byref(v)) - Error.check(res) - return v.value - - def check(self): - valid = ccs_bool() - res = ccs_tree_evaluation_check(self.handle, ct.byref(valid)) - Error.check(res) - return False if valid.value == 0 else True diff --git a/bindings/ruby/lib/cconfigspace.rb b/bindings/ruby/lib/cconfigspace.rb index 77d3f0e4..93b1610f 100644 --- a/bindings/ruby/lib/cconfigspace.rb +++ b/bindings/ruby/lib/cconfigspace.rb @@ -18,6 +18,7 @@ require_relative 'cconfigspace/features_space' require_relative 'cconfigspace/features' require_relative 'cconfigspace/objective_space' +require_relative 'cconfigspace/evaluation_binding' require_relative 'cconfigspace/evaluation' require_relative 'cconfigspace/features_evaluation' require_relative 'cconfigspace/tuner' diff --git a/bindings/ruby/lib/cconfigspace/base.rb b/bindings/ruby/lib/cconfigspace/base.rb index f4e0c0eb..3ccb32b0 100644 --- a/bindings/ruby/lib/cconfigspace/base.rb +++ b/bindings/ruby/lib/cconfigspace/base.rb @@ -103,6 +103,7 @@ class Version < FFI::Struct typedef :ccs_object_t, :ccs_features_space_t typedef :ccs_object_t, :ccs_features_t typedef :ccs_object_t, :ccs_objective_space_t + typedef :ccs_object_t, :ccs_evaluation_binding_t typedef :ccs_object_t, :ccs_evaluation_t typedef :ccs_object_t, :ccs_features_evaluation_t typedef :ccs_object_t, :ccs_tuner_t @@ -128,6 +129,7 @@ class MemoryPointer alias read_ccs_features_space_t read_ccs_object_t alias read_ccs_features_t read_ccs_object_t alias read_ccs_objective_space_t read_ccs_object_t + alias read_ccs_evaluation_binding_t read_ccs_object_t alias read_ccs_evaluation_t read_ccs_object_t alias read_ccs_features_evaluation_t read_ccs_object_t alias read_ccs_tuner_t read_ccs_object_t diff --git a/bindings/ruby/lib/cconfigspace/evaluation.rb b/bindings/ruby/lib/cconfigspace/evaluation.rb index 9ef351c6..87db9c42 100644 --- a/bindings/ruby/lib/cconfigspace/evaluation.rb +++ b/bindings/ruby/lib/cconfigspace/evaluation.rb @@ -1,27 +1,8 @@ module CCS - Comparison = enum FFI::Type::INT32, :ccs_comparison_t, [ - :CCS_COMPARISON_BETTER, -1, - :CCS_COMPARISON_EQUIVALENT, 0, - :CCS_COMPARISON_WORSE, 1, - :CCS_COMPARISON_NOT_COMPARABLE, 2 - ] - class MemoryPointer - def read_ccs_comparison_t - Comparison.from_native(read_int32, nil) - end - end - 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_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 + class Evaluation < EvaluationBinding 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: true def initialize(handle = nil, retain: false, auto_release: true, objective_space: nil, configuration: nil, result: :CCS_RESULT_SUCCESS, values: nil) @@ -50,41 +31,5 @@ def self.from_handle(handle, retain: true, auto_release: true) self::new(handle, retain: retain, auto_release: auto_release) end - def num_objective_values - @num_objective_values ||= begin - ptr = MemoryPointer::new(:size_t) - CCS.error_check CCS.ccs_evaluation_get_objective_values(@handle, 0, nil, ptr) - ptr.read_size_t - end - end - - def objective_values - @objective_values ||= begin - count = num_objective_values - 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 - ptr = MemoryPointer::new(:ccs_bool_t) - CCS.error_check CCS.ccs_evaluation_check(@handle, ptr) - return ptr.read_ccs_bool_t == CCS::FALSE ? false : true - end - - def compare(other) - ptr = MemoryPointer::new(:ccs_comparison_t) - CCS.error_check CCS.ccs_evaluation_compare(@handle, other, ptr) - ptr.read_ccs_comparison_t - end - - def <=>(other) - ptr = MemoryPointer::new(:ccs_comparison_t) - CCS.error_check CCS.ccs_evaluation_compare(@handle, other, ptr) - r = ptr.read_int32 - r == 2 ? nil : r - end - end end diff --git a/bindings/ruby/lib/cconfigspace/evaluation_binding.rb b/bindings/ruby/lib/cconfigspace/evaluation_binding.rb new file mode 100644 index 00000000..b0b16fa0 --- /dev/null +++ b/bindings/ruby/lib/cconfigspace/evaluation_binding.rb @@ -0,0 +1,60 @@ +module CCS + Comparison = enum FFI::Type::INT32, :ccs_comparison_t, [ + :CCS_COMPARISON_BETTER, -1, + :CCS_COMPARISON_EQUIVALENT, 0, + :CCS_COMPARISON_WORSE, 1, + :CCS_COMPARISON_NOT_COMPARABLE, 2 + ] + class MemoryPointer + def read_ccs_comparison_t + Comparison.from_native(read_int32, nil) + end + end + + attach_function :ccs_evaluation_binding_get_result, [:ccs_evaluation_binding_t, :pointer], :ccs_result_t + attach_function :ccs_evaluation_binding_get_objective_values, [:ccs_evaluation_binding_t, :size_t, :pointer, :pointer], :ccs_result_t + attach_function :ccs_evaluation_binding_compare, [:ccs_evaluation_binding_t, :ccs_evaluation_binding_t, :pointer], :ccs_result_t + attach_function :ccs_evaluation_binding_check, [:ccs_evaluation_binding_t, :pointer], :ccs_result_t + + class EvaluationBinding < Binding + alias objective_space context + add_property :result, :ccs_evaluation_binding_result_t, :ccs_evaluation_binding_get_result, memoize: true + + def num_objective_values + @num_objective_values ||= begin + ptr = MemoryPointer::new(:size_t) + CCS.error_check CCS.ccs_evaluation_binding_get_objective_values(@handle, 0, nil, ptr) + ptr.read_size_t + end + end + + def objective_values + @objective_values ||= begin + count = num_objective_values + values = MemoryPointer::new(:ccs_datum_t, count) + CCS.error_check CCS.ccs_evaluation_binding_get_objective_values(@handle, count, values, nil) + count.times.collect { |i| Datum::new(values[i]).value }.freeze + end + end + + def check + ptr = MemoryPointer::new(:ccs_bool_t) + CCS.error_check CCS.ccs_evaluation_binding_check(@handle, ptr) + return ptr.read_ccs_bool_t == CCS::FALSE ? false : true + end + + def compare(other) + ptr = MemoryPointer::new(:ccs_comparison_t) + CCS.error_check CCS.ccs_evaluation_binding_compare(@handle, other, ptr) + ptr.read_ccs_comparison_t + end + + def <=>(other) + ptr = MemoryPointer::new(:ccs_comparison_t) + CCS.error_check CCS.ccs_evaluation_binding_compare(@handle, other, ptr) + r = ptr.read_int32 + r == 2 ? nil : r + end + + end +end diff --git a/bindings/ruby/lib/cconfigspace/features_evaluation.rb b/bindings/ruby/lib/cconfigspace/features_evaluation.rb index 1133b21e..0e351cd5 100644 --- a/bindings/ruby/lib/cconfigspace/features_evaluation.rb +++ b/bindings/ruby/lib/cconfigspace/features_evaluation.rb @@ -2,16 +2,10 @@ module CCS attach_function :ccs_create_features_evaluation, [:ccs_objective_space_t, :ccs_configuration_t, :ccs_features_t, :ccs_evaluation_result_t, :size_t, :pointer, :pointer], :ccs_result_t attach_function :ccs_features_evaluation_get_configuration, [:ccs_features_evaluation_t, :pointer], :ccs_result_t attach_function :ccs_features_evaluation_get_features, [:ccs_features_evaluation_t, :pointer], :ccs_result_t - attach_function :ccs_features_evaluation_get_result, [:ccs_features_evaluation_t, :pointer], :ccs_result_t - attach_function :ccs_features_evaluation_get_objective_value, [:ccs_features_evaluation_t, :size_t, :pointer], :ccs_result_t - attach_function :ccs_features_evaluation_get_objective_values, [:ccs_features_evaluation_t, :size_t, :pointer, :pointer], :ccs_result_t - attach_function :ccs_features_evaluation_compare, [:ccs_features_evaluation_t, :ccs_features_evaluation_t, :pointer], :ccs_result_t - attach_function :ccs_features_evaluation_check, [:ccs_features_evaluation_t, :pointer], :ccs_result_t - class FeaturesEvaluation < Binding + class FeaturesEvaluation < EvaluationBinding alias objective_space context add_handle_property :configuration, :ccs_configuration_t, :ccs_features_evaluation_get_configuration, memoize: true add_handle_property :features, :ccs_features_t, :ccs_features_evaluation_get_features, memoize: true - add_property :result, :ccs_evaluation_result_t, :ccs_features_evaluation_get_result, memoize: true def initialize(handle = nil, retain: false, auto_release: true, objective_space: nil, configuration: nil, features: nil, result: :CCS_RESULT_SUCCESS, values: nil) @@ -41,40 +35,5 @@ def self.from_handle(handle, retain: true, auto_release: true) self::new(handle, retain: retain, auto_release: auto_release) end - def num_objective_values - @num_objective_values ||= begin - ptr = MemoryPointer::new(:size_t) - CCS.error_check CCS.ccs_features_evaluation_get_objective_values(@handle, 0, nil, ptr) - ptr.read_size_t - end - end - - def objective_values - @objective_values ||= begin - count = num_objective_values - values = MemoryPointer::new(:ccs_datum_t, count) - CCS.error_check CCS.ccs_features_evaluation_get_objective_values(@handle, count, values, nil) - count.times.collect { |i| Datum::new(values[i]).value }.freeze - end - end - - def check - ptr = MemoryPointer::new(:ccs_bool_t) - CCS.error_check CCS.ccs_features_evaluation_check(@handle, ptr) - return ptr.read_ccs_bool_t == CCS::FALSE ? false : true - end - - def compare(other) - ptr = MemoryPointer::new(:ccs_comparison_t) - CCS.error_check CCS.ccs_features_evaluation_compare(@handle, other, ptr) - ptr.read_ccs_comparison_t - end - - def <=>(other) - ptr = MemoryPointer::new(:ccs_comparison_t) - CCS.error_check CCS.ccs_features_evaluation_compare(@handle, other, ptr) - r = ptr.read_int32 - r == 2 ? nil : r - end end end diff --git a/bindings/ruby/lib/cconfigspace/tree_evaluation.rb b/bindings/ruby/lib/cconfigspace/tree_evaluation.rb index 9517ba8a..00951398 100644 --- a/bindings/ruby/lib/cconfigspace/tree_evaluation.rb +++ b/bindings/ruby/lib/cconfigspace/tree_evaluation.rb @@ -2,15 +2,10 @@ module CCS attach_function :ccs_create_tree_evaluation, [:ccs_objective_space_t, :ccs_tree_configuration_t, :ccs_evaluation_result_t, :size_t, :pointer, :pointer], :ccs_result_t attach_function :ccs_tree_evaluation_get_configuration, [:ccs_tree_evaluation_t, :pointer], :ccs_result_t - attach_function :ccs_tree_evaluation_get_result, [:ccs_tree_evaluation_t, :pointer], :ccs_result_t - attach_function :ccs_tree_evaluation_get_objective_values, [:ccs_tree_evaluation_t, :size_t, :pointer, :pointer], :ccs_result_t - attach_function :ccs_tree_evaluation_compare, [:ccs_tree_evaluation_t, :ccs_tree_evaluation_t, :pointer], :ccs_result_t - attach_function :ccs_tree_evaluation_check, [:ccs_tree_evaluation_t, :pointer], :ccs_result_t - class TreeEvaluation < Binding + class TreeEvaluation < EvaluationBinding alias objective_space context add_handle_property :configuration, :ccs_tree_configuration_t, :ccs_tree_evaluation_get_configuration, memoize: true - add_property :result, :ccs_evaluation_result_t, :ccs_tree_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) @@ -39,42 +34,6 @@ def self.from_handle(handle, retain: true, auto_release: true) self::new(handle, retain: retain, auto_release: auto_release) end - def num_objective_values - @num_objective_values ||= begin - ptr = MemoryPointer::new(:size_t) - CCS.error_check CCS.ccs_tree_evaluation_get_objective_values(@handle, 0, nil, ptr) - ptr.read_size_t - end - end - - def objective_values - @objective_values ||= begin - count = num_objective_values - values = MemoryPointer::new(:ccs_datum_t, count) - CCS.error_check CCS.ccs_tree_evaluation_get_objective_values(@handle, count, values, nil) - count.times.collect { |i| Datum::new(values[i]).value }.freeze - end - end - - def check - ptr = MemoryPointer::new(:ccs_bool_t) - CCS.error_check CCS.ccs_tree_evaluation_check(@handle, ptr) - return ptr.read_ccs_bool_t == CCS::FALSE ? false : true - end - - def compare(other) - ptr = MemoryPointer::new(:ccs_comparison_t) - CCS.error_check CCS.ccs_tree_evaluation_compare(@handle, other, ptr) - ptr.read_ccs_comparison_t - end - - def <=>(other) - ptr = MemoryPointer::new(:ccs_comparison_t) - CCS.error_check CCS.ccs_tree_evaluation_compare(@handle, other, ptr) - r = ptr.read_int32 - r == 2 ? nil : r - end - end end diff --git a/include/cconfigspace.h b/include/cconfigspace.h index 3c6be6ef..e08a50ed 100644 --- a/include/cconfigspace.h +++ b/include/cconfigspace.h @@ -20,6 +20,7 @@ #include "cconfigspace/features.h" #include "cconfigspace/objective_space.h" #include "cconfigspace/evaluation.h" +#include "cconfigspace/evaluation_binding.h" #include "cconfigspace/features_evaluation.h" #include "cconfigspace/tuner.h" #include "cconfigspace/features_tuner.h" diff --git a/include/cconfigspace/base.h b/include/cconfigspace/base.h index 8e336e2d..f3e05606 100644 --- a/include/cconfigspace/base.h +++ b/include/cconfigspace/base.h @@ -129,6 +129,10 @@ typedef struct _ccs_features_s *ccs_features_t; * An opaque type defining a CCS objective space. */ typedef struct _ccs_objective_space_s *ccs_objective_space_t; +/** + * An opaque type defining a CCS evaluation binding. + */ +typedef struct _ccs_evaluation_binding_s *ccs_evaluation_binding_t; /** * An opaque type defining a CCS evaluation. */ diff --git a/include/cconfigspace/evaluation.h b/include/cconfigspace/evaluation.h index 1380168a..b6f7712d 100644 --- a/include/cconfigspace/evaluation.h +++ b/include/cconfigspace/evaluation.h @@ -6,36 +6,11 @@ extern "C" { #endif /** - * @file evaluation.h An evaluation is a binding (see binding.h) over an - * objective space (see objective_space.h) given a specific configuration (see - * configuration.h). Successful evaluations over the same objective space are - * weakly ordered by their objective values. Evaluation that have failed must - * report a result code different than CCS_RESULT_SUCCESS. + * @file evaluation.h An evaluation is an evaluation binding + * (see evaluation_binding.h) given a specific configuration + * (see configuration.h). */ -/** - * The different possible return codes when comparing two evaluations. - */ -enum ccs_comparison_e { - /** The first configuration is better then the second */ - CCS_COMPARISON_BETTER = -1, - /** The two configurations are equivalent */ - CCS_COMPARISON_EQUIVALENT = 0, - /** The first configuration is worse than the second */ - CCS_COMPARISON_WORSE = 1, - /** The two configurations cannot be compared */ - CCS_COMPARISON_NOT_COMPARABLE = 2, - /** Guard */ - CCS_COMPARISON_MAX, - /** Try forcing 32 bits value for bindings */ - CCS_COMPARISON_FORCE_32BIT = INT32_MAX -}; - -/** - * A commodity type to represent CCS the result of comparing evaluations. - */ -typedef enum ccs_comparison_e ccs_comparison_t; - /** * Create a new instance of an evaluation on a given objective_space for a given * configuration. @@ -69,23 +44,6 @@ ccs_create_evaluation( ccs_datum_t *values, ccs_evaluation_t *evaluation_ret); -/** - * Get the objective space associated with an evaluation. - * @param[in] evaluation - * @param[out] objective_space_ret a pointer to the variable that will - * contain the objective space - * @return #CCS_RESULT_SUCCESS on success - * @return #CCS_RESULT_ERROR_INVALID_OBJECT if \p evaluation is not a valid CCS - * evaluation - * @return #CCS_RESULT_ERROR_INVALID_VALUE if \p objective_space_ret is NULL - * @remarks - * This function is thread-safe - */ -extern ccs_result_t -ccs_evaluation_get_objective_space( - ccs_evaluation_t evaluation, - ccs_objective_space_t *objective_space_ret); - /** * Get the configuration associated with an evaluation. * @param[in] evaluation @@ -103,121 +61,6 @@ ccs_evaluation_get_configuration( ccs_evaluation_t evaluation, ccs_configuration_t *configuration_ret); -/** - * Get the result code associated with an evaluation. - * @param[in] evaluation - * @param[out] result_ret a pointer to the variable that will contain the - * returned result code - * @return #CCS_RESULT_SUCCESS on success - * @return #CCS_RESULT_ERROR_INVALID_OBJECT if \p evaluation is not a valid CCS - * evaluation - * @return #CCS_RESULT_ERROR_INVALID_VALUE if \p result_ret is NULL - * @remarks - * This function is thread-safe - */ -extern ccs_result_t -ccs_evaluation_get_result( - ccs_evaluation_t evaluation, - ccs_evaluation_result_t *result_ret); - -/** - * Check that an evaluation values are valid in the objective space. - * @param[in] evaluation - * @param[out] is_valid_ret a pointer to a variable that will hold the result - * of the check. Result will be #CCS_TRUE if the - * evaluation is valid. Result will be #CCS_FALSE if - * an parameter value is not a valid value - * for this parameter - * @return #CCS_RESULT_SUCCESS on success - * @return #CCS_RESULT_ERROR_INVALID_OBJECT if \p evaluation is not a valid CCS - * evaluation - * @return #CCS_RESULT_ERROR_INVALID_EVALUATION if \p evaluation was found to be - * invalid in the context of the objective space - * @remarks - * This function is thread-safe - */ -extern ccs_result_t -ccs_evaluation_check(ccs_evaluation_t evaluation, ccs_bool_t *is_valid_ret); - -/** - * Get the value of an objective for a valid evaluation in the context of its - * objective space. - * @param[in] evaluation - * @param[in] index the index of the objective in the objective space - * @param[out] value_ret a pointer to the variable that will contain the value - * of the objective - * @return #CCS_RESULT_SUCCESS on success - * @return #CCS_RESULT_ERROR_INVALID_OBJECT if \p evaluation is not a valid CCS - * evaluation - * @return #CCS_RESULT_ERROR_INVALID_VALUE if \p value_ret is NULL; or if there - * was an issue evaluating the objective - * @return #CCS_RESULT_ERROR_OUT_OF_BOUNDS if \p index is greater than the - * number of objective in the objective space - * @remarks - * This function is thread-safe - */ -extern ccs_result_t -ccs_evaluation_get_objective_value( - ccs_evaluation_t evaluation, - size_t index, - ccs_datum_t *value_ret); - -/** - * Get the values of the objectives for a valid evaluation in the context of its - * objective space. - * @param[in] evaluation - * @param[in] num_values the number of values that \p values can contain - * @param[out] values an optional array of values that will contain the returned - * objective values. If values is bigger than the number of - * objectives, extra values will be set to - * #CCS_DATA_TYPE_NONE - * @param[out] num_values_ret an optional pointer to a variable that will - * contain the number of values that are or would be - * returned. Can be NULL - * @return #CCS_RESULT_SUCCESS on success - * @return #CCS_RESULT_ERROR_INVALID_OBJECT if \p evaluation is not a valid CCS - * evaluation - * @return #CCS_RESULT_ERROR_INVALID_VALUE if \p values is NULL and \p - * num_values is greater than 0; or if values is NULL and num_values_ret is - * NULL; or if there was an issue evaluating any of the objectives - * @remarks - * This function is thread-safe - */ -extern ccs_result_t -ccs_evaluation_get_objective_values( - ccs_evaluation_t evaluation, - size_t num_values, - ccs_datum_t *values, - size_t *num_values_ret); - -/** - * Compare two successful evaluations objectives. - * @param[in] evaluation the first evaluation - * @param[in] other_evaluation the second evaluation - * @param[out] result_ret a pointer to the variable that will contain the result - * of the comparison. Will contain - * #CCS_COMPARISON_BETTER, #CCS_COMPARISON_EQUIVALENT, - * #CCS_COMPARISON_WORSE, or - * #CCS_COMPARISON_NOT_COMPARABLE if the first - * evaluation is found to be respectively better, - * equivalent, worse, or not comparable with the second - * evaluation. - * @return #CCS_RESULT_SUCCESS on success - * @return #CCS_RESULT_ERROR_INVALID_OBJECT if \p evaluation or \p - * other_evaluation are not valid CCS evaluations; or if \p evaluation and \p - * other_evaluation do not share the same objective space; or if any of the - * configuration is associated a result code different than CCS_SUCESS - * @return #CCS_RESULT_ERROR_INVALID_VALUE if \p result_ret is NULL; or if there - * was an issue evaluating any of the objectives - * @remarks - * This function is thread-safe - */ -extern ccs_result_t -ccs_evaluation_compare( - ccs_evaluation_t evaluation, - ccs_evaluation_t other_evaluation, - ccs_comparison_t *result_ret); - #ifdef __cplusplus } #endif diff --git a/include/cconfigspace/evaluation_binding.h b/include/cconfigspace/evaluation_binding.h new file mode 100644 index 00000000..a2fe8e4a --- /dev/null +++ b/include/cconfigspace/evaluation_binding.h @@ -0,0 +1,178 @@ +#ifndef _CCS_EVALUATION_BINDING_H +#define _CCS_EVALUATION_BINDING_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @file evaluation_binding.h An evaluation binding is a binding (see + * binding.h) over an objective space (see objective_space.h). Successful + * evaluations over the same objective space are weakly ordered by their + * objective values. Evaluation that have failed must report a result code + * different than CCS_RESULT_SUCCESS. + */ + +/** + * The different possible return codes when comparing two evaluations. + */ +enum ccs_comparison_e { + /** The first configuration is better then the second */ + CCS_COMPARISON_BETTER = -1, + /** The two configurations are equivalent */ + CCS_COMPARISON_EQUIVALENT = 0, + /** The first configuration is worse than the second */ + CCS_COMPARISON_WORSE = 1, + /** The two configurations cannot be compared */ + CCS_COMPARISON_NOT_COMPARABLE = 2, + /** Guard */ + CCS_COMPARISON_MAX, + /** Try forcing 32 bits value for bindings */ + CCS_COMPARISON_FORCE_32BIT = INT32_MAX +}; + +/** + * A commodity type to represent CCS the result of comparing evaluations. + */ +typedef enum ccs_comparison_e ccs_comparison_t; + +/** + * Get the objective space associated with an evaluation binding. + * @param[in] evaluation_binding + * @param[out] objective_space_ret a pointer to the variable that will + * contain the objective space + * @return #CCS_RESULT_SUCCESS on success + * @return #CCS_RESULT_ERROR_INVALID_OBJECT if \p evaluation_binding is not a + * valid CCS evaluation binding + * @return #CCS_RESULT_ERROR_INVALID_VALUE if \p objective_space_ret is NULL + * @remarks + * This function is thread-safe + */ +extern ccs_result_t +ccs_evaluation_binding_get_objective_space( + ccs_evaluation_binding_t evaluation, + ccs_objective_space_t *objective_space_ret); + +/** + * Get the result code associated with an evaluation. + * @param[in] evaluation + * @param[out] result_ret a pointer to the variable that will contain the + * returned result code + * @return #CCS_RESULT_SUCCESS on success + * @return #CCS_RESULT_ERROR_INVALID_OBJECT if \p evaluation is not a valid CCS + * evaluation + * @return #CCS_RESULT_ERROR_INVALID_VALUE if \p result_ret is NULL + * @remarks + * This function is thread-safe + */ +extern ccs_result_t +ccs_evaluation_binding_get_result( + ccs_evaluation_binding_t evaluation, + ccs_evaluation_result_t *result_ret); + +/** + * Get the value of an objective for a valid evaluation in the context of its + * objective space. + * @param[in] evaluation + * @param[in] index the index of the objective in the objective space + * @param[out] value_ret a pointer to the variable that will contain the value + * of the objective + * @return #CCS_RESULT_SUCCESS on success + * @return #CCS_RESULT_ERROR_INVALID_OBJECT if \p evaluation is not a valid CCS + * evaluation + * @return #CCS_RESULT_ERROR_INVALID_VALUE if \p value_ret is NULL; or if there + * was an issue evaluating the objective + * @return #CCS_RESULT_ERROR_OUT_OF_BOUNDS if \p index is greater than the + * number of objective in the objective space + * @remarks + * This function is thread-safe + */ +extern ccs_result_t +ccs_evaluation_binding_get_objective_value( + ccs_evaluation_binding_t evaluation, + size_t index, + ccs_datum_t *value_ret); + +/** + * Get the values of the objectives for a valid evaluation in the context of its + * objective space. + * @param[in] evaluation + * @param[in] num_values the number of values that \p values can contain + * @param[out] values an optional array of values that will contain the returned + * objective values. If values is bigger than the number of + * objectives, extra values will be set to + * #CCS_DATA_TYPE_NONE + * @param[out] num_values_ret an optional pointer to a variable that will + * contain the number of values that are or would be + * returned. Can be NULL + * @return #CCS_RESULT_SUCCESS on success + * @return #CCS_RESULT_ERROR_INVALID_OBJECT if \p evaluation is not a valid CCS + * evaluation binding + * @return #CCS_RESULT_ERROR_INVALID_VALUE if \p values is NULL and \p + * num_values is greater than 0; or if values is NULL and num_values_ret is + * NULL; or if there was an issue evaluating any of the objectives + * @remarks + * This function is thread-safe + */ +extern ccs_result_t +ccs_evaluation_binding_get_objective_values( + ccs_evaluation_binding_t evaluation, + size_t num_values, + ccs_datum_t *values, + size_t *num_values_ret); + +/** + * Check that an evaluation values are valid in the objective space. + * @param[in] evaluation + * @param[out] is_valid_ret a pointer to a variable that will hold the result + * of the check. Result will be #CCS_TRUE if the + * evaluation is valid. Result will be #CCS_FALSE if + * an parameter value is not a valid value + * for this parameter + * @return #CCS_RESULT_SUCCESS on success + * @return #CCS_RESULT_ERROR_INVALID_OBJECT if \p evaluation is not a valid CCS + * evaluation + * @return #CCS_RESULT_ERROR_INVALID_EVALUATION if \p evaluation was found to be + * invalid in the context of the objective space + * @remarks + * This function is thread-safe + */ +extern ccs_result_t +ccs_evaluation_binding_check( + ccs_evaluation_binding_t evaluation, + ccs_bool_t *is_valid_ret); + +/** + * Compare two successful evaluations objectives. + * @param[in] evaluation the first evaluation + * @param[in] other_evaluation the second evaluation + * @param[out] result_ret a pointer to the variable that will contain the result + * of the comparison. Will contain + * #CCS_COMPARISON_BETTER, #CCS_COMPARISON_EQUIVALENT, + * #CCS_COMPARISON_WORSE, or + * #CCS_COMPARISON_NOT_COMPARABLE if the first + * evaluation is found to be respectively better, + * equivalent, worse, or not comparable with the second + * evaluation. + * @return #CCS_RESULT_SUCCESS on success + * @return #CCS_RESULT_ERROR_INVALID_OBJECT if \p evaluation or \p + * other_evaluation are not valid CCS evaluations; or if \p evaluation and \p + * other_evaluation do not share the same objective space; or if any of the + * the evaluation is associated a result code different than #CCS_RESULT_SUCESS; + * or if both evaluations are not ot the same type + * @return #CCS_RESULT_ERROR_INVALID_VALUE if \p result_ret is NULL; or if there + * was an issue evaluating any of the objectives + * @remarks + * This function is thread-safe + */ +extern ccs_result_t +ccs_evaluation_binding_compare( + ccs_evaluation_binding_t evaluation, + ccs_evaluation_binding_t other_evaluation, + ccs_comparison_t *result_ret); + +#ifdef __cplusplus +} +#endif + +#endif //_CCS_EVALUATION_BINDING_H diff --git a/include/cconfigspace/features_evaluation.h b/include/cconfigspace/features_evaluation.h index 5f4805ca..07b96810 100644 --- a/include/cconfigspace/features_evaluation.h +++ b/include/cconfigspace/features_evaluation.h @@ -7,11 +7,8 @@ extern "C" { /** * @file features_evaluation.h - * A features evaluation is a binding (see binding.h) over an objective space - * given a specific configuration (see configuration.h) and features (see - * features.h). Successful evaluations over the same objective space are weakly - * ordered by their objective values. Evaluation that have failed must report a - * result code different than CCS_RESULT_SUCCESS. + * A features evaluation is an evaluation binding (see evaluation_binding.h) + * configuration (see configuration.h) and features (see features.h). */ /** @@ -50,23 +47,6 @@ ccs_create_features_evaluation( ccs_datum_t *values, ccs_features_evaluation_t *features_evaluation_ret); -/** - * Get the objective space associated with a features evaluation. - * @param[in] features_evaluation - * @param[out] objective_space_ret a pointer to the variable that will - * contain the objective space - * @return #CCS_RESULT_SUCCESS on success - * @return #CCS_RESULT_ERROR_INVALID_OBJECT if \p features_evaluation is not a - * valid CCS features_evaluation - * @return #CCS_RESULT_ERROR_INVALID_VALUE if \p objective_space_ret is NULL - * @remarks - * This function is thread-safe - */ -extern ccs_result_t -ccs_features_evaluation_get_objective_space( - ccs_features_evaluation_t features_evaluation, - ccs_objective_space_t *objective_space_ret); - /** * Get the configuration associated with a features evaluation. * @param[in] features_evaluation @@ -101,124 +81,6 @@ ccs_features_evaluation_get_features( ccs_features_evaluation_t features_evaluation, ccs_features_t *features_ret); -/** - * Get the result code associated with a features evaluation. - * @param[in] features_evaluation - * @param[out] result_ret a pointer to the variable that will contain the - * returned result code - * @return #CCS_RESULT_SUCCESS on success - * @return #CCS_RESULT_ERROR_INVALID_OBJECT if \p features_evaluation is not a - * valid CCS features evaluation - * @return #CCS_RESULT_ERROR_INVALID_VALUE if \p result_ret is NULL - * @remarks - * This function is thread-safe - */ -extern ccs_result_t -ccs_features_evaluation_get_result( - ccs_features_evaluation_t features_evaluation, - ccs_evaluation_result_t *result_ret); - -/** - * Get the value of an objective for a valid features evaluation in the context - * of its objective space. - * @param[in] features_evaluation - * @param[in] index the index of the objective in the objective space - * @param[out] value_ret a pointer to the variable that will contain the value - * of the objective - * @return #CCS_RESULT_SUCCESS on success - * @return #CCS_RESULT_ERROR_INVALID_OBJECT if \p features_evaluation is not a - * valid CCS features evaluation - * @return #CCS_RESULT_ERROR_INVALID_VALUE if \p value_ret is NULL; or if there - * was an issue evaluating the objective - * @return #CCS_RESULT_ERROR_OUT_OF_BOUNDS if \p index is greater than the - * number of objective in the objective space - * @remarks - * This function is thread-safe - */ -extern ccs_result_t -ccs_features_evaluation_get_objective_value( - ccs_features_evaluation_t features_evaluation, - size_t index, - ccs_datum_t *value_ret); - -/** - * Get the values of the objectives for a valid features evaluation in the - * context of its objective space. - * @param[in] features_evaluation - * @param[in] num_values the number of values that \p values can contain - * @param[out] values an optional array of values that will contain the returned - * objective values. If values is bigger than the number of - * objectives, extra values will be set to - * #CCS_DATA_TYPE_NONE - * @param[out] num_values_ret an optional pointer to a variable that will - * contain the number of values that are or would be - * returned. Can be NULL - * @return #CCS_RESULT_SUCCESS on success - * @return #CCS_RESULT_ERROR_INVALID_OBJECT if \p features_evaluation is not a - * valid CCS features evaluation - * @return #CCS_RESULT_ERROR_INVALID_VALUE if \p values is NULL and \p - * num_values is greater than 0; or if values is NULL and num_values_ret is - * NULL; or if there was an issue evaluating any of the objectives - * @remarks - * This function is thread-safe - */ -extern ccs_result_t -ccs_features_evaluation_get_objective_values( - ccs_features_evaluation_t features_evaluation, - size_t num_values, - ccs_datum_t *values, - size_t *num_values_ret); - -/** - * Compare two successful features evaluations objectives. - * @param[in] features_evaluation the first features evaluation - * @param[in] other_features_evaluation the second features evaluation - * @param[out] result_ret a pointer to the variable that will contain the result - * of the comparison. Will contain - * #CCS_COMPARISON_BETTER, #CCS_COMPARISON_EQUIVALENT, - * #CCS_COMPARISON_WORSE, or - * #CCS_COMPARISON_NOT_COMPARABLE if the first features - * evaluation is found to be respectively better, - * equivalent, worse, or not comparable with the second - * features evaluation. - * @return #CCS_RESULT_SUCCESS on success - * @return #CCS_RESULT_ERROR_INVALID_OBJECT if \p features_evaluation or \p - * other_features_evaluation are not valid CCS features evaluations; or if \p - * features_evaluation and \p other_features_evaluation do not share the same - * objective space; or if any of the configuration is associated a result code - * different than CCS_SUCESS - * @return #CCS_RESULT_ERROR_INVALID_VALUE if \p result_ret is NULL; or if there - * was an issue evaluating any of the objectives - * @remarks - * This function is thread-safe - */ -extern ccs_result_t -ccs_features_evaluation_compare( - ccs_features_evaluation_t features_evaluation, - ccs_features_evaluation_t other_features_evaluation, - ccs_comparison_t *result_ret); - -/** - * Check that a features evaluation values are valid in the objective space. - * @param[in] features_evaluation - * @param[out] is_valid_ret a pointer to a variable that will hold the result - * of the check. Result will be #CCS_TRUE if the - * features_evaluation is valid. Result will be - * #CCS_FALSE if an parameter value is not a valid - * value for this parameter - * @return #CCS_RESULT_SUCCESS on success - * @return #CCS_RESULT_ERROR_INVALID_OBJECT if \p features_evaluation is not a - * valid CCS features evaluation - * @return #CCS_RESULT_ERROR_INVALID_EVALUATION if \p features_evaluation was - * found to be invalid in the context of the objective space - * @remarks - * This function is thread-safe - */ -extern ccs_result_t -ccs_features_evaluation_check( - ccs_features_evaluation_t features_evaluation, - ccs_bool_t *is_valid_ret); - #ifdef __cplusplus } #endif diff --git a/include/cconfigspace/objective_space.h b/include/cconfigspace/objective_space.h index 1c12ffe4..78067d89 100644 --- a/include/cconfigspace/objective_space.h +++ b/include/cconfigspace/objective_space.h @@ -83,18 +83,18 @@ ccs_create_objective_space( * @return #CCS_RESULT_SUCCESS on success * @return #CCS_RESULT_ERROR_INVALID_OBJECT if \p objective_space is not a * valid CCS objective space; or if \p evaluation is not a valid CCS - * evaluation + * evaluation binding * @return #CCS_RESULT_ERROR_INVALID_VALUE if \p is_valid_ret is NULL - * @return #CCS_RESULT_ERROR_INVALID_EVALUATION if \p evaluation is not - * associated to the objective space + * @return #CCS_RESULT_ERROR_INVALID_EVALUATION_BINDING if \p evaluation + * is not associated to the objective space * @remarks * This function is thread-safe */ extern ccs_result_t ccs_objective_space_check_evaluation( - ccs_objective_space_t objective_space, - ccs_evaluation_t evaluation, - ccs_bool_t *is_valid_ret); + ccs_objective_space_t objective_space, + ccs_evaluation_binding_t evaluation, + ccs_bool_t *is_valid_ret); /** * Get the objective of rank index in a objective space. diff --git a/include/cconfigspace/tree_evaluation.h b/include/cconfigspace/tree_evaluation.h index 4f8df716..cc865005 100644 --- a/include/cconfigspace/tree_evaluation.h +++ b/include/cconfigspace/tree_evaluation.h @@ -5,12 +5,10 @@ extern "C" { #endif -/** @file tree_evaluation.h A tree evaluation is a binding (see binding.h) over - * an objective space (see objective_space.h) given a specific tree - * configuration (see tree_configuration.h). Successful evaluations over the - * same objective space are weakly ordered by their objective values. - * Evaluation that have failed must report a result code different than - * CCS_RESULT_SUCCESS. +/** + * @file tree_evaluation.h A tree evaluation is an evaluation binding + * (see evaluation_binding.h) given a specific tree configuration + * (see tree_configuration.h). */ /** @@ -47,23 +45,6 @@ ccs_create_tree_evaluation( ccs_datum_t *values, ccs_tree_evaluation_t *evaluation_ret); -/** - * Get the objective space associated with a tree evaluation. - * @param[in] evaluation - * @param[out] objective_space_ret a pointer to the variable that will - * contain the objective space - * @return #CCS_RESULT_SUCCESS on success - * @return #CCS_RESULT_ERROR_INVALID_OBJECT if \p evaluation is not a valid CCS - * tree evaluation - * @return #CCS_RESULT_ERROR_INVALID_VALUE if \p objective_space_ret is NULL - * @remarks - * This function is thread-safe - */ -extern ccs_result_t -ccs_tree_evaluation_get_objective_space( - ccs_tree_evaluation_t evaluation, - ccs_objective_space_t *objective_space_ret); - /** * Get the configuration associated with a tree evaluation. * @param[in] evaluation @@ -81,123 +62,6 @@ ccs_tree_evaluation_get_configuration( ccs_tree_evaluation_t evaluation, ccs_tree_configuration_t *configuration_ret); -/** - * Get the result code associated with a tree evaluation. - * @param[in] evaluation - * @param[out] result_ret a pointer to the variable that will contain the - * returned error code - * @return #CCS_RESULT_SUCCESS on success - * @return #CCS_RESULT_ERROR_INVALID_OBJECT if \p evaluation is not a valid CCS - * tree evaluation - * @return #CCS_RESULT_ERROR_INVALID_VALUE if \p result_ret is NULL - * @remarks - * This function is thread-safe - */ -extern ccs_result_t -ccs_tree_evaluation_get_result( - ccs_tree_evaluation_t evaluation, - ccs_evaluation_result_t *result_ret); - -/** - * Check that an evaluation values are valid in the objective space. - * @param[in] evaluation - * @param[out] is_valid_ret a pointer to a variable that will hold the result - * of the check. Result will be #CCS_TRUE if the - * evaluation is valid. Result will be #CCS_FALSE if - * an parameter value is not a valid value - * for this parameter - * @return #CCS_RESULT_SUCCESS on success - * @return #CCS_RESULT_ERROR_INVALID_OBJECT if \p evaluation is not a valid CCS - * tree evaluation - * @return #CCS_RESULT_ERROR_INVALID_EVALUATION if \p evaluation was found to be - * invalid in the context of the objective space - * @remarks - * This function is thread-safe - */ -extern ccs_result_t -ccs_tree_evaluation_check( - ccs_tree_evaluation_t evaluation, - ccs_bool_t *is_valid_ret); - -/** - * Get the value of an objective for a valid tree evaluation in the context of - * its objective space. - * @param[in] evaluation - * @param[in] index the index of the objective in the objective space - * @param[out] value_ret a pointer to the variable that will contain the value - * of the objective - * @return #CCS_RESULT_SUCCESS on success - * @return #CCS_RESULT_ERROR_INVALID_OBJECT if \p evaluation is not a valid CCS - * tree evaluation - * @return #CCS_RESULT_ERROR_INVALID_VALUE if \p value_ret is NULL; or if there - * was an issue evaluating the objective - * @return #CCS_RESULT_ERROR_OUT_OF_BOUNDS if \p index is greater than the - * number of objective in the objective space - * @remarks - * This function is thread-safe - */ -extern ccs_result_t -ccs_tree_evaluation_get_objective_value( - ccs_tree_evaluation_t evaluation, - size_t index, - ccs_datum_t *value_ret); - -/** - * Get the values of the objectives for a valid tree evaluation in the context - * of its objective space. - * @param[in] evaluation - * @param[in] num_values the number of values that \p values can contain - * @param[out] values an optional array of values that will contain the returned - * objective values. If values is bigger than the number of - * objectives, extra values will be set to - * #CCS_DATA_TYPE_NONE - * @param[out] num_values_ret an optional pointer to a variable that will - * contain the number of values that are or would be - * returned. Can be NULL - * @return #CCS_RESULT_SUCCESS on success - * @return #CCS_RESULT_ERROR_INVALID_OBJECT if \p evaluation is not a valid CCS - * tree evaluation - * @return #CCS_RESULT_ERROR_INVALID_VALUE if \p values is NULL and \p - * num_values is greater than 0; or if values is NULL and num_values_ret is - * NULL; or if there was an issue evaluating any of the objectives - * @remarks - * This function is thread-safe - */ -extern ccs_result_t -ccs_tree_evaluation_get_objective_values( - ccs_tree_evaluation_t evaluation, - size_t num_values, - ccs_datum_t *values, - size_t *num_values_ret); - -/** - * Compare two successful tree evaluations objectives. - * @param[in] evaluation the first evaluation - * @param[in] other_evaluation the second evaluation - * @param[out] result_ret a pointer to the variable that will contain the result - * of the comparison. Will contain - * #CCS_COMPARISON_BETTER, #CCS_COMPARISON_EQUIVALENT, - * #CCS_COMPARISON_WORSE, or - * #CCS_COMPARISON_NOT_COMPARABLE if the first - * evaluation is found to be respectively better, - * equivalent, worse, or not comparable with the second - * evaluation. - * @return #CCS_RESULT_SUCCESS on success - * @return #CCS_RESULT_ERROR_INVALID_OBJECT if \p evaluation or \p - * other_evaluation are not valid CCS tree evaluations; or if \p evaluation and - * \p other_evaluation do not share the same objective space; or if any of the - * configuration is associated a result code different than CCS_SUCESS - * @return #CCS_RESULT_ERROR_INVALID_VALUE if \p result_ret is NULL; or if there - * was an issue evaluating any of the objectives - * @remarks - * This function is thread-safe - */ -extern ccs_result_t -ccs_tree_evaluation_compare( - ccs_tree_evaluation_t evaluation, - ccs_tree_evaluation_t other_evaluation, - ccs_comparison_t *result_ret); - #ifdef __cplusplus } #endif diff --git a/samples/test_python.c b/samples/test_python.c index a82cdfcf..e31baf68 100644 --- a/samples/test_python.c +++ b/samples/test_python.c @@ -94,7 +94,8 @@ test_tuner(ccs_tuner_t tuner, ccs_objective_space_t ospace) for (size_t i = 0; i < 100; i++) { ccs_datum_t res; - err = ccs_evaluation_get_objective_value(history[i], 0, &res); + err = ccs_evaluation_binding_get_objective_value( + (ccs_evaluation_binding_t)history[i], 0, &res); assert(err == CCS_RESULT_SUCCESS); if (res.value.f < min.value.f) min.value.f = res.value.f; @@ -104,7 +105,8 @@ test_tuner(ccs_tuner_t tuner, ccs_objective_space_t ospace) ccs_datum_t res; err = ccs_tuner_get_optima(tuner, 1, &evaluation, NULL); assert(err == CCS_RESULT_SUCCESS); - err = ccs_evaluation_get_objective_value(evaluation, 0, &res); + err = ccs_evaluation_binding_get_objective_value( + (ccs_evaluation_binding_t)evaluation, 0, &res); assert(res.value.f == min.value.f); } diff --git a/samples/test_ruby.c b/samples/test_ruby.c index dbb03ce1..bbaa4f80 100644 --- a/samples/test_ruby.c +++ b/samples/test_ruby.c @@ -103,7 +103,8 @@ test_tuner(ccs_tuner_t tuner, ccs_objective_space_t ospace) for (size_t i = 0; i < 100; i++) { ccs_datum_t res; - err = ccs_evaluation_get_objective_value(history[i], 0, &res); + err = ccs_evaluation_binding_get_objective_value( + (ccs_evaluation_binding_t)history[i], 0, &res); assert(err == CCS_RESULT_SUCCESS); if (res.value.f < min.value.f) min.value.f = res.value.f; @@ -113,7 +114,8 @@ test_tuner(ccs_tuner_t tuner, ccs_objective_space_t ospace) ccs_datum_t res; err = ccs_tuner_get_optima(tuner, 1, &evaluation, NULL); assert(err == CCS_RESULT_SUCCESS); - err = ccs_evaluation_get_objective_value(evaluation, 0, &res); + err = ccs_evaluation_binding_get_objective_value( + (ccs_evaluation_binding_t)evaluation, 0, &res); assert(res.value.f == min.value.f); } diff --git a/src/Makefile.am b/src/Makefile.am index 000f5e3b..9cd2b778 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -76,6 +76,8 @@ libcconfigspace_la_SOURCES = \ objective_space.c \ objective_space_internal.h \ objective_space_deserialize.h \ + evaluation_binding.c \ + evaluation_binding_internal.h \ evaluation.c \ evaluation_internal.h \ evaluation_deserialize.h \ diff --git a/src/cconfigspace_internal.h b/src/cconfigspace_internal.h index ebeac147..ace49e0d 100644 --- a/src/cconfigspace_internal.h +++ b/src/cconfigspace_internal.h @@ -247,7 +247,7 @@ _ccs_do_nothing(void) CCS_RESULT_ERROR_INVALID_OBJECT, \ "Invalid CCS context '%s' == %p supplied", #c, c) -#define CCS_CHECK_EVALUATION(e) \ +#define CCS_CHECK_EVALUATION_BINDING(e) \ CCS_REFUTE_MSG( \ !(e) || !((_ccs_object_template_t *)(e))->data || \ (((_ccs_object_template_t *)(e))->obj.type != \ diff --git a/src/evaluation.c b/src/evaluation.c index 6258c3d5..4eb36552 100644 --- a/src/evaluation.c +++ b/src/evaluation.c @@ -1,4 +1,5 @@ #include "cconfigspace_internal.h" +#include "evaluation_binding_internal.h" #include "evaluation_internal.h" #include "configuration_internal.h" #include "objective_space_internal.h" @@ -155,11 +156,24 @@ _ccs_evaluation_cmp( return CCS_RESULT_SUCCESS; } +static ccs_result_t +_ccs_evaluation_compare( + ccs_evaluation_t evaluation, + ccs_evaluation_t other, + ccs_comparison_t *result_ret) +{ + CCS_VALIDATE(_ccs_evaluation_binding_compare( + (ccs_evaluation_binding_t)evaluation, + (ccs_evaluation_binding_t)other, result_ret)); + return CCS_RESULT_SUCCESS; +} + static _ccs_evaluation_ops_t _evaluation_ops = { {&_ccs_evaluation_del, &_ccs_evaluation_serialize_size, &_ccs_evaluation_serialize}, &_ccs_evaluation_hash, - &_ccs_evaluation_cmp}; + &_ccs_evaluation_cmp, + &_ccs_evaluation_compare}; ccs_result_t ccs_create_evaluation( @@ -225,18 +239,6 @@ ccs_create_evaluation( return err; } -ccs_result_t -ccs_evaluation_get_objective_space( - ccs_evaluation_t evaluation, - ccs_objective_space_t *objective_space_ret) -{ - CCS_CHECK_OBJ(evaluation, CCS_OBJECT_TYPE_EVALUATION); - CCS_VALIDATE(_ccs_binding_get_context( - (ccs_binding_t)evaluation, - (ccs_context_t *)objective_space_ret)); - return CCS_RESULT_SUCCESS; -} - ccs_result_t ccs_evaluation_get_configuration( ccs_evaluation_t evaluation, @@ -247,150 +249,3 @@ ccs_evaluation_get_configuration( *configuration_ret = evaluation->data->configuration; return CCS_RESULT_SUCCESS; } - -ccs_result_t -ccs_evaluation_get_result( - ccs_evaluation_t evaluation, - ccs_evaluation_result_t *result_ret) -{ - CCS_CHECK_OBJ(evaluation, CCS_OBJECT_TYPE_EVALUATION); - CCS_CHECK_PTR(result_ret); - *result_ret = evaluation->data->result; - return CCS_RESULT_SUCCESS; -} - -ccs_result_t -ccs_evaluation_check(ccs_evaluation_t evaluation, ccs_bool_t *is_valid_ret) -{ - CCS_CHECK_OBJ(evaluation, CCS_OBJECT_TYPE_EVALUATION); - CCS_VALIDATE(ccs_objective_space_check_evaluation( - evaluation->data->objective_space, evaluation, is_valid_ret)); - return CCS_RESULT_SUCCESS; -} - -ccs_result_t -ccs_evaluation_get_objective_value( - ccs_evaluation_t evaluation, - size_t index, - ccs_datum_t *value_ret) -{ - CCS_CHECK_OBJ(evaluation, CCS_OBJECT_TYPE_EVALUATION); - CCS_CHECK_PTR(value_ret); - ccs_expression_t expression; - ccs_objective_type_t type; - CCS_VALIDATE(ccs_objective_space_get_objective( - evaluation->data->objective_space, index, &expression, &type)); - CCS_VALIDATE(ccs_expression_eval( - expression, 1, (ccs_binding_t *)&evaluation, value_ret)); - return CCS_RESULT_SUCCESS; -} - -ccs_result_t -ccs_evaluation_get_objective_values( - ccs_evaluation_t evaluation, - size_t num_values, - ccs_datum_t *values, - size_t *num_values_ret) -{ - CCS_CHECK_OBJ(evaluation, CCS_OBJECT_TYPE_EVALUATION); - CCS_CHECK_ARY(num_values, values); - CCS_REFUTE(!values && !num_values_ret, CCS_RESULT_ERROR_INVALID_VALUE); - size_t count; - CCS_VALIDATE(ccs_objective_space_get_objectives( - evaluation->data->objective_space, 0, NULL, NULL, &count)); - if (values) { - CCS_REFUTE(count < num_values, CCS_RESULT_ERROR_INVALID_VALUE); - for (size_t i = 0; i < count; i++) { - ccs_expression_t expression; - ccs_objective_type_t type; - - CCS_VALIDATE(ccs_objective_space_get_objective( - evaluation->data->objective_space, i, - &expression, &type)); - CCS_VALIDATE(ccs_expression_eval( - expression, 1, (ccs_binding_t *)&evaluation, - values + i)); - } - for (size_t i = count; i < num_values; i++) - values[i] = ccs_none; - } - if (num_values_ret) - *num_values_ret = count; - return CCS_RESULT_SUCCESS; -} - -static inline int -_numeric_compare(const ccs_datum_t *a, const ccs_datum_t *b) -{ - if (a->type == CCS_DATA_TYPE_FLOAT) { - return a->value.f < b->value.f ? -1 : - a->value.f > b->value.f ? 1 : - 0; - } else { - return a->value.i < b->value.i ? -1 : - a->value.i > b->value.i ? 1 : - 0; - } -} - -// Could be using memoization here. -ccs_result_t -ccs_evaluation_compare( - ccs_evaluation_t evaluation, - ccs_evaluation_t other_evaluation, - ccs_comparison_t *result_ret) -{ - CCS_CHECK_OBJ(evaluation, CCS_OBJECT_TYPE_EVALUATION); - CCS_CHECK_OBJ(other_evaluation, CCS_OBJECT_TYPE_EVALUATION); - CCS_CHECK_PTR(result_ret); - if (evaluation == other_evaluation) { - *result_ret = CCS_COMPARISON_EQUIVALENT; - return CCS_RESULT_SUCCESS; - } - CCS_REFUTE( - evaluation->data->result || other_evaluation->data->result, - CCS_RESULT_ERROR_INVALID_OBJECT); - CCS_REFUTE( - evaluation->data->objective_space != - other_evaluation->data->objective_space, - CCS_RESULT_ERROR_INVALID_OBJECT); - size_t count; - CCS_VALIDATE(ccs_objective_space_get_objectives( - evaluation->data->objective_space, 0, NULL, NULL, &count)); - *result_ret = CCS_COMPARISON_EQUIVALENT; - for (size_t i = 0; i < count; i++) { - ccs_expression_t expression; - ccs_objective_type_t type; - ccs_datum_t values[2]; - int cmp; - - CCS_VALIDATE(ccs_objective_space_get_objective( - evaluation->data->objective_space, i, &expression, - &type)); - CCS_VALIDATE(ccs_expression_eval( - expression, 1, (ccs_binding_t *)&evaluation, values)); - CCS_VALIDATE(ccs_expression_eval( - expression, 1, (ccs_binding_t *)&other_evaluation, - values + 1)); - // Maybe relax to allow comparing Numerical values of different - // types. - if ((values[0].type != CCS_DATA_TYPE_INT && - values[0].type != CCS_DATA_TYPE_FLOAT) || - values[0].type != values[1].type) { - *result_ret = CCS_COMPARISON_NOT_COMPARABLE; - return CCS_RESULT_SUCCESS; - } - cmp = _numeric_compare(values, values + 1); - if (cmp) { - if (type == CCS_OBJECTIVE_TYPE_MAXIMIZE) - cmp = -cmp; - if (*result_ret == CCS_COMPARISON_EQUIVALENT) - *result_ret = (ccs_comparison_t)cmp; - else if (*result_ret != cmp) { - *result_ret = CCS_COMPARISON_NOT_COMPARABLE; - return CCS_RESULT_SUCCESS; - } - } - } - return CCS_RESULT_SUCCESS; -} diff --git a/src/evaluation_binding.c b/src/evaluation_binding.c new file mode 100644 index 00000000..61663a73 --- /dev/null +++ b/src/evaluation_binding.c @@ -0,0 +1,122 @@ +#include "cconfigspace_internal.h" +#include "evaluation_binding_internal.h" + +static inline _ccs_evaluation_binding_ops_t * +ccs_evaluation_binding_get_ops(ccs_evaluation_binding_t binding) +{ + return (_ccs_evaluation_binding_ops_t *)binding->obj.ops; +} + +ccs_result_t +ccs_evaluation_binding_get_objective_space( + ccs_evaluation_binding_t evaluation, + ccs_objective_space_t *objective_space_ret) +{ + CCS_CHECK_EVALUATION_BINDING(evaluation); + CCS_CHECK_PTR(objective_space_ret); + *objective_space_ret = evaluation->data->objective_space; + return CCS_RESULT_SUCCESS; +} + +ccs_result_t +ccs_evaluation_binding_get_result( + ccs_evaluation_binding_t evaluation, + ccs_evaluation_result_t *result_ret) +{ + CCS_CHECK_EVALUATION_BINDING(evaluation); + CCS_CHECK_PTR(result_ret); + *result_ret = evaluation->data->result; + return CCS_RESULT_SUCCESS; +} + +ccs_result_t +ccs_evaluation_binding_check( + ccs_evaluation_binding_t evaluation, + ccs_bool_t *is_valid_ret) +{ + CCS_CHECK_EVALUATION_BINDING(evaluation); + CCS_VALIDATE(ccs_objective_space_check_evaluation( + evaluation->data->objective_space, evaluation, is_valid_ret)); + return CCS_RESULT_SUCCESS; +} + +ccs_result_t +ccs_evaluation_binding_get_objective_value( + ccs_evaluation_binding_t evaluation, + size_t index, + ccs_datum_t *value_ret) +{ + CCS_CHECK_EVALUATION_BINDING(evaluation); + CCS_CHECK_PTR(value_ret); + ccs_expression_t expression; + ccs_objective_type_t type; + CCS_VALIDATE(ccs_objective_space_get_objective( + evaluation->data->objective_space, index, &expression, &type)); + CCS_VALIDATE(ccs_expression_eval( + expression, 1, (ccs_binding_t *)&evaluation, value_ret)); + return CCS_RESULT_SUCCESS; +} + +ccs_result_t +ccs_evaluation_binding_get_objective_values( + ccs_evaluation_binding_t evaluation, + size_t num_values, + ccs_datum_t *values, + size_t *num_values_ret) +{ + CCS_CHECK_EVALUATION_BINDING(evaluation); + CCS_CHECK_ARY(num_values, values); + CCS_REFUTE(!values && !num_values_ret, CCS_RESULT_ERROR_INVALID_VALUE); + size_t count; + CCS_VALIDATE(ccs_objective_space_get_objectives( + evaluation->data->objective_space, 0, NULL, NULL, &count)); + if (values) { + CCS_REFUTE(count < num_values, CCS_RESULT_ERROR_INVALID_VALUE); + for (size_t i = 0; i < count; i++) { + ccs_expression_t expression; + ccs_objective_type_t type; + + CCS_VALIDATE(ccs_objective_space_get_objective( + evaluation->data->objective_space, i, + &expression, &type)); + CCS_VALIDATE(ccs_expression_eval( + expression, 1, (ccs_binding_t *)&evaluation, + values + i)); + } + for (size_t i = count; i < num_values; i++) + values[i] = ccs_none; + } + if (num_values_ret) + *num_values_ret = count; + return CCS_RESULT_SUCCESS; +} + +ccs_result_t +ccs_evaluation_binding_compare( + ccs_evaluation_binding_t evaluation, + ccs_evaluation_binding_t other_evaluation, + ccs_comparison_t *result_ret) +{ + CCS_CHECK_EVALUATION_BINDING(evaluation); + CCS_CHECK_EVALUATION_BINDING(other_evaluation); + CCS_REFUTE( + evaluation->obj.type != other_evaluation->obj.type, + CCS_RESULT_ERROR_INVALID_OBJECT); + CCS_CHECK_PTR(result_ret); + if (evaluation == other_evaluation) { + *result_ret = CCS_COMPARISON_EQUIVALENT; + return CCS_RESULT_SUCCESS; + } + CCS_REFUTE( + evaluation->data->result || other_evaluation->data->result, + CCS_RESULT_ERROR_INVALID_OBJECT); + CCS_REFUTE( + evaluation->data->objective_space != + other_evaluation->data->objective_space, + CCS_RESULT_ERROR_INVALID_OBJECT); + + _ccs_evaluation_binding_ops_t *ops = + ccs_evaluation_binding_get_ops(evaluation); + CCS_VALIDATE(ops->compare(evaluation, other_evaluation, result_ret)); + return CCS_RESULT_SUCCESS; +} diff --git a/src/evaluation_binding_internal.h b/src/evaluation_binding_internal.h new file mode 100644 index 00000000..e30919f5 --- /dev/null +++ b/src/evaluation_binding_internal.h @@ -0,0 +1,92 @@ +#ifndef _EVALUATION_BINDING_INTERNAL_H +#define _EVALUATION_BINDING_INTERNAL_H + +typedef struct _ccs_evaluation_binding_data_s _ccs_evaluation_binding_data_t; + +struct _ccs_evaluation_binding_ops_s { + _ccs_object_ops_t obj_ops; + + ccs_result_t (*hash)(ccs_binding_t binding, ccs_hash_t *hash_ret); + + ccs_result_t ( + *cmp)(ccs_binding_t binding, ccs_binding_t other, int *cmp_ret); + + ccs_result_t (*compare)( + ccs_evaluation_binding_t evaluation, + ccs_evaluation_binding_t other_evaluation, + ccs_comparison_t *result_ret); +}; +typedef struct _ccs_evaluation_binding_ops_s _ccs_evaluation_binding_ops_t; + +struct _ccs_evaluation_binding_data_s { + ccs_objective_space_t objective_space; + size_t num_values; + ccs_datum_t *values; + ccs_evaluation_result_t result; +}; + +struct _ccs_evaluation_binding_s { + _ccs_object_internal_t obj; + _ccs_evaluation_binding_data_t *data; +}; + +static inline int +_numeric_compare(const ccs_datum_t *a, const ccs_datum_t *b) +{ + if (a->type == CCS_DATA_TYPE_FLOAT) { + return a->value.f < b->value.f ? -1 : + a->value.f > b->value.f ? 1 : + 0; + } else { + return a->value.i < b->value.i ? -1 : + a->value.i > b->value.i ? 1 : + 0; + } +} + +static inline ccs_result_t +_ccs_evaluation_binding_compare( + ccs_evaluation_binding_t evaluation, + ccs_evaluation_binding_t other_evaluation, + ccs_comparison_t *result_ret) +{ + size_t count; + CCS_VALIDATE(ccs_objective_space_get_objectives( + evaluation->data->objective_space, 0, NULL, NULL, &count)); + *result_ret = CCS_COMPARISON_EQUIVALENT; + for (size_t i = 0; i < count; i++) { + ccs_expression_t expression; + ccs_objective_type_t type; + ccs_datum_t values[2]; + int cmp; + + CCS_VALIDATE(ccs_objective_space_get_objective( + evaluation->data->objective_space, i, &expression, + &type)); + CCS_VALIDATE(ccs_expression_eval( + expression, 1, (ccs_binding_t *)&evaluation, values)); + CCS_VALIDATE(ccs_expression_eval( + expression, 1, (ccs_binding_t *)&other_evaluation, + values + 1)); + if ((values[0].type != CCS_DATA_TYPE_INT && + values[0].type != CCS_DATA_TYPE_FLOAT) || + values[0].type != values[1].type) { + *result_ret = CCS_COMPARISON_NOT_COMPARABLE; + return CCS_RESULT_SUCCESS; + } + cmp = _numeric_compare(values, values + 1); + if (cmp) { + if (type == CCS_OBJECTIVE_TYPE_MAXIMIZE) + cmp = -cmp; + if (*result_ret == CCS_COMPARISON_EQUIVALENT) + *result_ret = (ccs_comparison_t)cmp; + else if (*result_ret != cmp) { + *result_ret = CCS_COMPARISON_NOT_COMPARABLE; + return CCS_RESULT_SUCCESS; + } + } + } + return CCS_RESULT_SUCCESS; +} + +#endif // _EVALUATION_BINDING_INTERNAL_H diff --git a/src/evaluation_internal.h b/src/evaluation_internal.h index 8072a204..2e4d83f5 100644 --- a/src/evaluation_internal.h +++ b/src/evaluation_internal.h @@ -14,6 +14,11 @@ struct _ccs_evaluation_ops_s { ccs_evaluation_t evaluation, ccs_evaluation_t other, int *cmp_ret); + + ccs_result_t (*compare)( + ccs_evaluation_t evaluation, + ccs_evaluation_t other_evaluation, + ccs_comparison_t *result_ret); }; typedef struct _ccs_evaluation_ops_s _ccs_evaluation_ops_t; diff --git a/src/features_evaluation.c b/src/features_evaluation.c index 6a8cb9c0..12ae7871 100644 --- a/src/features_evaluation.c +++ b/src/features_evaluation.c @@ -1,4 +1,5 @@ #include "cconfigspace_internal.h" +#include "evaluation_binding_internal.h" #include "features_evaluation_internal.h" #include "configuration_internal.h" #include "features_internal.h" @@ -175,12 +176,33 @@ _ccs_features_evaluation_cmp( return CCS_RESULT_SUCCESS; } +static ccs_result_t +_ccs_features_evaluation_compare( + ccs_features_evaluation_t evaluation, + ccs_features_evaluation_t other_evaluation, + ccs_comparison_t *result_ret) +{ + int eql; + CCS_VALIDATE(ccs_binding_cmp( + (ccs_binding_t)evaluation->data->features, + (ccs_binding_t)other_evaluation->data->features, &eql)); + if (0 != eql) { + *result_ret = CCS_COMPARISON_NOT_COMPARABLE; + return CCS_RESULT_SUCCESS; + } + CCS_VALIDATE(_ccs_evaluation_binding_compare( + (ccs_evaluation_binding_t)evaluation, + (ccs_evaluation_binding_t)other_evaluation, result_ret)); + return CCS_RESULT_SUCCESS; +} + static _ccs_features_evaluation_ops_t _features_evaluation_ops = { {&_ccs_features_evaluation_del, &_ccs_features_evaluation_serialize_size, &_ccs_features_evaluation_serialize}, &_ccs_features_evaluation_hash, - &_ccs_features_evaluation_cmp}; + &_ccs_features_evaluation_cmp, + &_ccs_features_evaluation_compare}; ccs_result_t ccs_create_features_evaluation( @@ -257,18 +279,6 @@ ccs_create_features_evaluation( return err; } -ccs_result_t -ccs_features_evaluation_get_objective_space( - ccs_features_evaluation_t evaluation, - ccs_objective_space_t *objective_space_ret) -{ - CCS_CHECK_OBJ(evaluation, CCS_OBJECT_TYPE_FEATURES_EVALUATION); - CCS_VALIDATE(_ccs_binding_get_context( - (ccs_binding_t)evaluation, - (ccs_context_t *)objective_space_ret)); - return CCS_RESULT_SUCCESS; -} - ccs_result_t ccs_features_evaluation_get_configuration( ccs_features_evaluation_t evaluation, @@ -290,160 +300,3 @@ ccs_features_evaluation_get_features( *features_ret = evaluation->data->features; return CCS_RESULT_SUCCESS; } - -ccs_result_t -ccs_features_evaluation_get_result( - ccs_features_evaluation_t evaluation, - ccs_evaluation_result_t *result_ret) -{ - CCS_CHECK_OBJ(evaluation, CCS_OBJECT_TYPE_FEATURES_EVALUATION); - CCS_CHECK_PTR(result_ret); - *result_ret = evaluation->data->result; - return CCS_RESULT_SUCCESS; -} - -ccs_result_t -ccs_features_evaluation_check( - ccs_features_evaluation_t evaluation, - ccs_bool_t *is_valid_ret) -{ - CCS_CHECK_OBJ(evaluation, CCS_OBJECT_TYPE_FEATURES_EVALUATION); - CCS_VALIDATE(ccs_objective_space_check_evaluation( - evaluation->data->objective_space, (ccs_evaluation_t)evaluation, - is_valid_ret)); - return CCS_RESULT_SUCCESS; -} - -ccs_result_t -ccs_features_evaluation_get_objective_value( - ccs_features_evaluation_t evaluation, - size_t index, - ccs_datum_t *value_ret) -{ - CCS_CHECK_OBJ(evaluation, CCS_OBJECT_TYPE_FEATURES_EVALUATION); - CCS_CHECK_PTR(value_ret); - ccs_expression_t expression; - ccs_objective_type_t type; - CCS_VALIDATE(ccs_objective_space_get_objective( - evaluation->data->objective_space, index, &expression, &type)); - CCS_VALIDATE(ccs_expression_eval( - expression, 1, (ccs_binding_t *)&evaluation, value_ret)); - return CCS_RESULT_SUCCESS; -} - -ccs_result_t -ccs_features_evaluation_get_objective_values( - ccs_features_evaluation_t evaluation, - size_t num_values, - ccs_datum_t *values, - size_t *num_values_ret) -{ - CCS_CHECK_OBJ(evaluation, CCS_OBJECT_TYPE_FEATURES_EVALUATION); - CCS_CHECK_ARY(num_values, values); - CCS_REFUTE(!values && !num_values_ret, CCS_RESULT_ERROR_INVALID_VALUE); - size_t count; - CCS_VALIDATE(ccs_objective_space_get_objectives( - evaluation->data->objective_space, 0, NULL, NULL, &count)); - if (values) { - CCS_REFUTE(count < num_values, CCS_RESULT_ERROR_INVALID_VALUE); - for (size_t i = 0; i < count; i++) { - ccs_expression_t expression; - ccs_objective_type_t type; - - CCS_VALIDATE(ccs_objective_space_get_objective( - evaluation->data->objective_space, i, - &expression, &type)); - CCS_VALIDATE(ccs_expression_eval( - expression, 1, (ccs_binding_t *)&evaluation, - values + i)); - } - for (size_t i = count; i < num_values; i++) - values[i] = ccs_none; - } - if (num_values_ret) - *num_values_ret = count; - return CCS_RESULT_SUCCESS; -} - -static inline int -_numeric_compare(const ccs_datum_t *a, const ccs_datum_t *b) -{ - if (a->type == CCS_DATA_TYPE_FLOAT) { - return a->value.f < b->value.f ? -1 : - a->value.f > b->value.f ? 1 : - 0; - } else { - return a->value.i < b->value.i ? -1 : - a->value.i > b->value.i ? 1 : - 0; - } -} - -// Could be using memoization here. -ccs_result_t -ccs_features_evaluation_compare( - ccs_features_evaluation_t evaluation, - ccs_features_evaluation_t other_evaluation, - ccs_comparison_t *result_ret) -{ - CCS_CHECK_OBJ(evaluation, CCS_OBJECT_TYPE_FEATURES_EVALUATION); - CCS_CHECK_OBJ(other_evaluation, CCS_OBJECT_TYPE_FEATURES_EVALUATION); - CCS_CHECK_PTR(result_ret); - if (evaluation == other_evaluation) { - *result_ret = CCS_COMPARISON_EQUIVALENT; - return CCS_RESULT_SUCCESS; - } - CCS_REFUTE( - evaluation->data->result || other_evaluation->data->result, - CCS_RESULT_ERROR_INVALID_OBJECT); - CCS_REFUTE( - evaluation->data->objective_space != - other_evaluation->data->objective_space, - CCS_RESULT_ERROR_INVALID_OBJECT); - size_t count; - int eql; - CCS_VALIDATE(ccs_objective_space_get_objectives( - evaluation->data->objective_space, 0, NULL, NULL, &count)); - CCS_VALIDATE(ccs_binding_cmp( - (ccs_binding_t)evaluation->data->features, - (ccs_binding_t)other_evaluation->data->features, &eql)); - if (0 != eql) { - *result_ret = CCS_COMPARISON_NOT_COMPARABLE; - return CCS_RESULT_SUCCESS; - } - - *result_ret = CCS_COMPARISON_EQUIVALENT; - for (size_t i = 0; i < count; i++) { - ccs_expression_t expression; - ccs_objective_type_t type; - ccs_datum_t values[2]; - int cmp; - - CCS_VALIDATE(ccs_objective_space_get_objective( - evaluation->data->objective_space, i, &expression, - &type)); - CCS_VALIDATE(ccs_expression_eval( - expression, 1, (ccs_binding_t *)&evaluation, values)); - CCS_VALIDATE(ccs_expression_eval( - expression, 1, (ccs_binding_t *)&other_evaluation, - values + 1)); - if ((values[0].type != CCS_DATA_TYPE_INT && - values[0].type != CCS_DATA_TYPE_FLOAT) || - values[0].type != values[1].type) { - *result_ret = CCS_COMPARISON_NOT_COMPARABLE; - return CCS_RESULT_SUCCESS; - } - cmp = _numeric_compare(values, values + 1); - if (cmp) { - if (type == CCS_OBJECTIVE_TYPE_MAXIMIZE) - cmp = -cmp; - if (*result_ret == CCS_COMPARISON_EQUIVALENT) - *result_ret = (ccs_comparison_t)cmp; - else if (*result_ret != cmp) { - *result_ret = CCS_COMPARISON_NOT_COMPARABLE; - return CCS_RESULT_SUCCESS; - } - } - } - return CCS_RESULT_SUCCESS; -} diff --git a/src/features_evaluation_internal.h b/src/features_evaluation_internal.h index 4a9106c1..cc1fd683 100644 --- a/src/features_evaluation_internal.h +++ b/src/features_evaluation_internal.h @@ -16,6 +16,11 @@ struct _ccs_features_evaluation_ops_s { ccs_features_evaluation_t features_evaluation, ccs_features_evaluation_t other, int *cmp_ret); + + ccs_result_t (*compare)( + ccs_features_evaluation_t evaluation, + ccs_features_evaluation_t other_evaluation, + ccs_comparison_t *result_ret); }; typedef struct _ccs_features_evaluation_ops_s _ccs_features_evaluation_ops_t; diff --git a/src/features_tuner_random.c b/src/features_tuner_random.c index 544dc862..faa7dff7 100644 --- a/src/features_tuner_random.c +++ b/src/features_tuner_random.c @@ -196,8 +196,8 @@ _ccs_features_tuner_random_tell( ccs_result_t err; for (size_t i = 0; i < num_evaluations; i++) { ccs_evaluation_result_t result; - CCS_VALIDATE(ccs_features_evaluation_get_result( - evaluations[i], &result)); + CCS_VALIDATE(ccs_evaluation_binding_get_result( + (ccs_evaluation_binding_t)evaluations[i], &result)); if (result == CCS_RESULT_SUCCESS) { int discard = 0; UT_array *tmp; @@ -220,8 +220,11 @@ _ccs_features_tuner_random_tell( utarray_next(d->old_optima, eval))) { if (!discard) { ccs_comparison_t cmp; - err = ccs_features_evaluation_compare( - evaluations[i], *eval, &cmp); + err = ccs_evaluation_binding_compare( + (ccs_evaluation_binding_t) + evaluations[i], + (ccs_evaluation_binding_t)*eval, + &cmp); if (err) discard = 1; else diff --git a/src/objective_space.c b/src/objective_space.c index 1ce0be72..de24297b 100644 --- a/src/objective_space.c +++ b/src/objective_space.c @@ -1,6 +1,6 @@ #include "cconfigspace_internal.h" #include "objective_space_internal.h" -#include "evaluation_internal.h" +#include "evaluation_binding_internal.h" #include "expression_internal.h" static ccs_result_t @@ -272,9 +272,9 @@ ccs_create_objective_space( static inline ccs_result_t _check_evaluation( - ccs_objective_space_t objective_space, - ccs_evaluation_t evaluation, - ccs_bool_t *is_valid_ret) + ccs_objective_space_t objective_space, + ccs_evaluation_binding_t evaluation, + ccs_bool_t *is_valid_ret) { ccs_parameter_t *parameters = objective_space->data->parameters; size_t num_parameters = objective_space->data->num_parameters; @@ -292,12 +292,12 @@ _check_evaluation( ccs_result_t ccs_objective_space_check_evaluation( - ccs_objective_space_t objective_space, - ccs_evaluation_t evaluation, - ccs_bool_t *is_valid_ret) + ccs_objective_space_t objective_space, + ccs_evaluation_binding_t evaluation, + ccs_bool_t *is_valid_ret) { CCS_CHECK_OBJ(objective_space, CCS_OBJECT_TYPE_OBJECTIVE_SPACE); - CCS_CHECK_EVALUATION(evaluation); + CCS_CHECK_EVALUATION_BINDING(evaluation); CCS_REFUTE( evaluation->data->objective_space != objective_space, CCS_RESULT_ERROR_INVALID_EVALUATION); diff --git a/src/tree_evaluation.c b/src/tree_evaluation.c index b9a392ed..ef629a0c 100644 --- a/src/tree_evaluation.c +++ b/src/tree_evaluation.c @@ -1,4 +1,5 @@ #include "cconfigspace_internal.h" +#include "evaluation_binding_internal.h" #include "tree_evaluation_internal.h" #include "tree_configuration_internal.h" #include "objective_space_internal.h" @@ -157,11 +158,24 @@ _ccs_tree_evaluation_cmp( return CCS_RESULT_SUCCESS; } +static ccs_result_t +_ccs_tree_evaluation_compare( + ccs_tree_evaluation_t evaluation, + ccs_tree_evaluation_t other, + ccs_comparison_t *result_ret) +{ + CCS_VALIDATE(_ccs_evaluation_binding_compare( + (ccs_evaluation_binding_t)evaluation, + (ccs_evaluation_binding_t)other, result_ret)); + return CCS_RESULT_SUCCESS; +} + static _ccs_tree_evaluation_ops_t _evaluation_ops = { {&_ccs_tree_evaluation_del, &_ccs_tree_evaluation_serialize_size, &_ccs_tree_evaluation_serialize}, &_ccs_tree_evaluation_hash, - &_ccs_tree_evaluation_cmp}; + &_ccs_tree_evaluation_cmp, + &_ccs_tree_evaluation_compare}; ccs_result_t ccs_create_tree_evaluation( @@ -227,18 +241,6 @@ ccs_create_tree_evaluation( return err; } -ccs_result_t -ccs_tree_evaluation_get_objective_space( - ccs_tree_evaluation_t evaluation, - ccs_objective_space_t *objective_space_ret) -{ - CCS_CHECK_OBJ(evaluation, CCS_OBJECT_TYPE_TREE_EVALUATION); - CCS_VALIDATE(_ccs_binding_get_context( - (ccs_binding_t)evaluation, - (ccs_context_t *)objective_space_ret)); - return CCS_RESULT_SUCCESS; -} - ccs_result_t ccs_tree_evaluation_get_configuration( ccs_tree_evaluation_t evaluation, @@ -249,153 +251,3 @@ ccs_tree_evaluation_get_configuration( *configuration_ret = evaluation->data->configuration; return CCS_RESULT_SUCCESS; } - -ccs_result_t -ccs_tree_evaluation_get_result( - ccs_tree_evaluation_t evaluation, - ccs_evaluation_result_t *result_ret) -{ - CCS_CHECK_OBJ(evaluation, CCS_OBJECT_TYPE_TREE_EVALUATION); - CCS_CHECK_PTR(result_ret); - *result_ret = evaluation->data->result; - return CCS_RESULT_SUCCESS; -} - -ccs_result_t -ccs_tree_evaluation_check( - ccs_tree_evaluation_t evaluation, - ccs_bool_t *is_valid_ret) -{ - CCS_CHECK_OBJ(evaluation, CCS_OBJECT_TYPE_TREE_EVALUATION); - CCS_VALIDATE(ccs_objective_space_check_evaluation( - evaluation->data->objective_space, (ccs_evaluation_t)evaluation, - is_valid_ret)); - return CCS_RESULT_SUCCESS; -} - -ccs_result_t -ccs_tree_evaluation_get_objective_value( - ccs_tree_evaluation_t evaluation, - size_t index, - ccs_datum_t *value_ret) -{ - CCS_CHECK_OBJ(evaluation, CCS_OBJECT_TYPE_TREE_EVALUATION); - CCS_CHECK_PTR(value_ret); - ccs_expression_t expression; - ccs_objective_type_t type; - CCS_VALIDATE(ccs_objective_space_get_objective( - evaluation->data->objective_space, index, &expression, &type)); - CCS_VALIDATE(ccs_expression_eval( - expression, 1, (ccs_binding_t *)&evaluation, value_ret)); - return CCS_RESULT_SUCCESS; -} - -ccs_result_t -ccs_tree_evaluation_get_objective_values( - ccs_tree_evaluation_t evaluation, - size_t num_values, - ccs_datum_t *values, - size_t *num_values_ret) -{ - CCS_CHECK_OBJ(evaluation, CCS_OBJECT_TYPE_TREE_EVALUATION); - CCS_CHECK_ARY(num_values, values); - CCS_REFUTE(!values && !num_values_ret, CCS_RESULT_ERROR_INVALID_VALUE); - size_t count; - CCS_VALIDATE(ccs_objective_space_get_objectives( - evaluation->data->objective_space, 0, NULL, NULL, &count)); - if (values) { - CCS_REFUTE(count < num_values, CCS_RESULT_ERROR_INVALID_VALUE); - for (size_t i = 0; i < count; i++) { - ccs_expression_t expression; - ccs_objective_type_t type; - - CCS_VALIDATE(ccs_objective_space_get_objective( - evaluation->data->objective_space, i, - &expression, &type)); - CCS_VALIDATE(ccs_expression_eval( - expression, 1, (ccs_binding_t *)&evaluation, - values + i)); - } - for (size_t i = count; i < num_values; i++) - values[i] = ccs_none; - } - if (num_values_ret) - *num_values_ret = count; - return CCS_RESULT_SUCCESS; -} - -static inline int -_numeric_compare(const ccs_datum_t *a, const ccs_datum_t *b) -{ - if (a->type == CCS_DATA_TYPE_FLOAT) { - return a->value.f < b->value.f ? -1 : - a->value.f > b->value.f ? 1 : - 0; - } else { - return a->value.i < b->value.i ? -1 : - a->value.i > b->value.i ? 1 : - 0; - } -} - -// Could be using memoization here. -ccs_result_t -ccs_tree_evaluation_compare( - ccs_tree_evaluation_t evaluation, - ccs_tree_evaluation_t other_evaluation, - ccs_comparison_t *result_ret) -{ - CCS_CHECK_OBJ(evaluation, CCS_OBJECT_TYPE_TREE_EVALUATION); - CCS_CHECK_OBJ(other_evaluation, CCS_OBJECT_TYPE_TREE_EVALUATION); - CCS_CHECK_PTR(result_ret); - if (evaluation == other_evaluation) { - *result_ret = CCS_COMPARISON_EQUIVALENT; - return CCS_RESULT_SUCCESS; - } - CCS_REFUTE( - evaluation->data->result || other_evaluation->data->result, - CCS_RESULT_ERROR_INVALID_OBJECT); - CCS_REFUTE( - evaluation->data->objective_space != - other_evaluation->data->objective_space, - CCS_RESULT_ERROR_INVALID_OBJECT); - size_t count; - CCS_VALIDATE(ccs_objective_space_get_objectives( - evaluation->data->objective_space, 0, NULL, NULL, &count)); - *result_ret = CCS_COMPARISON_EQUIVALENT; - for (size_t i = 0; i < count; i++) { - ccs_expression_t expression; - ccs_objective_type_t type; - ccs_datum_t values[2]; - int cmp; - - CCS_VALIDATE(ccs_objective_space_get_objective( - evaluation->data->objective_space, i, &expression, - &type)); - CCS_VALIDATE(ccs_expression_eval( - expression, 1, (ccs_binding_t *)&evaluation, values)); - CCS_VALIDATE(ccs_expression_eval( - expression, 1, (ccs_binding_t *)&other_evaluation, - values + 1)); - // Maybe relax to allow comparing Numerical values of different - // types. - if ((values[0].type != CCS_DATA_TYPE_INT && - values[0].type != CCS_DATA_TYPE_FLOAT) || - values[0].type != values[1].type) { - *result_ret = CCS_COMPARISON_NOT_COMPARABLE; - return CCS_RESULT_SUCCESS; - } - cmp = _numeric_compare(values, values + 1); - if (cmp) { - if (type == CCS_OBJECTIVE_TYPE_MAXIMIZE) - cmp = -cmp; - if (*result_ret == CCS_COMPARISON_EQUIVALENT) - *result_ret = (ccs_comparison_t)cmp; - else if (*result_ret != cmp) { - *result_ret = CCS_COMPARISON_NOT_COMPARABLE; - return CCS_RESULT_SUCCESS; - } - } - } - return CCS_RESULT_SUCCESS; -} diff --git a/src/tree_evaluation_internal.h b/src/tree_evaluation_internal.h index 9c6cf8ab..ec5f5847 100644 --- a/src/tree_evaluation_internal.h +++ b/src/tree_evaluation_internal.h @@ -16,6 +16,11 @@ struct _ccs_tree_evaluation_ops_s { ccs_tree_evaluation_t tree_evaluation, ccs_tree_evaluation_t other, int *cmp_ret); + + ccs_result_t (*compare)( + ccs_tree_evaluation_t evaluation, + ccs_tree_evaluation_t other_evaluation, + ccs_comparison_t *result_ret); }; typedef struct _ccs_tree_evaluation_ops_s _ccs_tree_evaluation_ops_t; diff --git a/src/tree_tuner_random.c b/src/tree_tuner_random.c index 92265ae5..4286ba69 100644 --- a/src/tree_tuner_random.c +++ b/src/tree_tuner_random.c @@ -188,8 +188,8 @@ _ccs_tree_tuner_random_tell( ccs_result_t err; for (size_t i = 0; i < num_evaluations; i++) { ccs_evaluation_result_t result; - CCS_VALIDATE(ccs_tree_evaluation_get_result( - evaluations[i], &result)); + CCS_VALIDATE(ccs_evaluation_binding_get_result( + (ccs_evaluation_binding_t)evaluations[i], &result)); if (!result) { int discard = 0; UT_array *tmp; @@ -212,8 +212,11 @@ _ccs_tree_tuner_random_tell( d->old_optima, eval))) { if (!discard) { ccs_comparison_t cmp; - err = ccs_tree_evaluation_compare( - evaluations[i], *eval, &cmp); + err = ccs_evaluation_binding_compare( + (ccs_evaluation_binding_t) + evaluations[i], + (ccs_evaluation_binding_t)*eval, + &cmp); if (err) discard = 1; else diff --git a/src/tuner_random.c b/src/tuner_random.c index dd8208ab..2dbd0067 100644 --- a/src/tuner_random.c +++ b/src/tuner_random.c @@ -187,8 +187,8 @@ _ccs_tuner_random_tell( ccs_result_t err; for (size_t i = 0; i < num_evaluations; i++) { ccs_evaluation_result_t result; - CCS_VALIDATE( - ccs_evaluation_get_result(evaluations[i], &result)); + CCS_VALIDATE(ccs_evaluation_binding_get_result( + (ccs_evaluation_binding_t)evaluations[i], &result)); if (!result) { int discard = 0; UT_array *tmp; @@ -211,8 +211,11 @@ _ccs_tuner_random_tell( d->old_optima, eval))) { if (!discard) { ccs_comparison_t cmp; - err = ccs_evaluation_compare( - evaluations[i], *eval, &cmp); + err = ccs_evaluation_binding_compare( + (ccs_evaluation_binding_t) + evaluations[i], + (ccs_evaluation_binding_t)*eval, + &cmp); if (err) discard = 1; else diff --git a/tests/test_random_features_tuner.c b/tests/test_random_features_tuner.c index b61954c2..8c0758de 100644 --- a/tests/test_random_features_tuner.c +++ b/tests/test_random_features_tuner.c @@ -137,8 +137,8 @@ test(void) for (size_t i = 0; i < 50; i++) { ccs_datum_t res; - err = ccs_features_evaluation_get_objective_value( - history[i], 0, &res); + err = ccs_evaluation_binding_get_objective_value( + (ccs_evaluation_binding_t)history[i], 0, &res); assert(err == CCS_RESULT_SUCCESS); if (res.value.f < min_on.value.f) min_on.value.f = res.value.f; @@ -151,8 +151,8 @@ test(void) for (size_t i = 0; i < 50; i++) { ccs_datum_t res; - err = ccs_features_evaluation_get_objective_value( - history[i], 0, &res); + err = ccs_evaluation_binding_get_objective_value( + (ccs_evaluation_binding_t)history[i], 0, &res); assert(err == CCS_RESULT_SUCCESS); if (res.value.f < min_off.value.f) min_off.value.f = res.value.f; @@ -162,13 +162,15 @@ test(void) err = ccs_features_tuner_get_optima( tuner, features_on, 1, &evaluation, NULL); assert(err == CCS_RESULT_SUCCESS); - err = ccs_features_evaluation_get_objective_value(evaluation, 0, &res); + err = ccs_evaluation_binding_get_objective_value( + (ccs_evaluation_binding_t)evaluation, 0, &res); assert(res.value.f == min_on.value.f); err = ccs_features_tuner_get_optima( tuner, features_off, 1, &evaluation, NULL); assert(err == CCS_RESULT_SUCCESS); - err = ccs_features_evaluation_get_objective_value(evaluation, 0, &res); + err = ccs_evaluation_binding_get_objective_value( + (ccs_evaluation_binding_t)evaluation, 0, &res); assert(res.value.f == min_off.value.f); /* Test (de)serialization */ diff --git a/tests/test_random_tree_tuner.c b/tests/test_random_tree_tuner.c index 3eb799be..914a9eb2 100644 --- a/tests/test_random_tree_tuner.c +++ b/tests/test_random_tree_tuner.c @@ -121,8 +121,8 @@ test(void) for (size_t i = 0; i < 100; i++) { ccs_datum_t res; - err = ccs_tree_evaluation_get_objective_value( - history[i], 0, &res); + err = ccs_evaluation_binding_get_objective_value( + (ccs_evaluation_binding_t)history[i], 0, &res); assert(err == CCS_RESULT_SUCCESS); if (res.value.f > max.value.f) max.value.f = res.value.f; @@ -132,7 +132,8 @@ test(void) ccs_datum_t res; err = ccs_tree_tuner_get_optima(tuner, 1, &evaluation, NULL); assert(err == CCS_RESULT_SUCCESS); - err = ccs_tree_evaluation_get_objective_value(evaluation, 0, &res); + err = ccs_evaluation_binding_get_objective_value( + (ccs_evaluation_binding_t)evaluation, 0, &res); assert(res.value.f == max.value.f); /* Test (de)serialization */ diff --git a/tests/test_random_tuner.c b/tests/test_random_tuner.c index 0657d53e..63168fa7 100644 --- a/tests/test_random_tuner.c +++ b/tests/test_random_tuner.c @@ -84,7 +84,8 @@ test(void) for (size_t i = 0; i < 100; i++) { ccs_datum_t res; - err = ccs_evaluation_get_objective_value(history[i], 0, &res); + err = ccs_evaluation_binding_get_objective_value( + (ccs_evaluation_binding_t)history[i], 0, &res); assert(err == CCS_RESULT_SUCCESS); if (res.value.f < min.value.f) min.value.f = res.value.f; @@ -94,7 +95,8 @@ test(void) ccs_datum_t res; err = ccs_tuner_get_optima(tuner, 1, &evaluation, NULL); assert(err == CCS_RESULT_SUCCESS); - err = ccs_evaluation_get_objective_value(evaluation, 0, &res); + err = ccs_evaluation_binding_get_objective_value( + (ccs_evaluation_binding_t)evaluation, 0, &res); assert(res.value.f == min.value.f); /* Test (de)serialization */