From f87778b3871157d6c1921757e385a99002312de6 Mon Sep 17 00:00:00 2001 From: Brice Videau Date: Tue, 27 Oct 2020 14:53:47 -0500 Subject: [PATCH] Better user-defined tuner implementation. --- bindings/python/cconfigspace/tuner.py | 52 ++++++++++----------- bindings/python/test/test_tuner.py | 12 ++--- bindings/ruby/lib/cconfigspace/tuner.rb | 52 +++++++-------------- bindings/ruby/test/test_tuner.rb | 12 ++--- include/cconfigspace/tuner.h | 55 ++++++++-------------- samples/test_python.py | 12 ++--- samples/test_python_from_ruby.rb | 2 +- samples/test_ruby.rb | 12 ++--- src/tuner.c | 10 ++-- src/tuner_internal.h | 9 ++++ src/tuner_random.c | 8 ++-- src/tuner_user_defined.c | 60 ++++++++++++++++-------- tests/test_user_defined_tuner.c | 62 ++++++++++++++++--------- 13 files changed, 185 insertions(+), 173 deletions(-) diff --git a/bindings/python/cconfigspace/tuner.py b/bindings/python/cconfigspace/tuner.py index f04f8bf..ccc04bc 100644 --- a/bindings/python/cconfigspace/tuner.py +++ b/bindings/python/cconfigspace/tuner.py @@ -152,11 +152,11 @@ class ccs_tuner_common_data(ct.Structure): ('configuration_space', ccs_configuration_space), ('objective_space', ccs_objective_space) ] -ccs_user_defined_tuner_del_type = ct.CFUNCTYPE(ccs_result, ct.c_void_p) -ccs_user_defined_tuner_ask_type = ct.CFUNCTYPE(ccs_result, ct.c_void_p, ct.c_size_t, ct.POINTER(ccs_configuration), ct.POINTER(ct.c_size_t)) -ccs_user_defined_tuner_tell_type = ct.CFUNCTYPE(ccs_result, ct.c_void_p, ct.c_size_t, ct.POINTER(ccs_evaluation)) -ccs_user_defined_tuner_get_optimums_type = ct.CFUNCTYPE(ccs_result, ct.c_void_p, ct.c_size_t, ct.POINTER(ccs_evaluation), ct.POINTER(ct.c_size_t)) -ccs_user_defined_tuner_get_history_type = ct.CFUNCTYPE(ccs_result, ct.c_void_p, ct.c_size_t, ct.POINTER(ccs_evaluation), ct.POINTER(ct.c_size_t)) +ccs_user_defined_tuner_del_type = ct.CFUNCTYPE(ccs_result, ccs_tuner) +ccs_user_defined_tuner_ask_type = ct.CFUNCTYPE(ccs_result, ccs_tuner, ct.c_size_t, ct.POINTER(ccs_configuration), ct.POINTER(ct.c_size_t)) +ccs_user_defined_tuner_tell_type = ct.CFUNCTYPE(ccs_result, ccs_tuner, ct.c_size_t, ct.POINTER(ccs_evaluation)) +ccs_user_defined_tuner_get_optimums_type = ct.CFUNCTYPE(ccs_result, ccs_tuner, ct.c_size_t, ct.POINTER(ccs_evaluation), ct.POINTER(ct.c_size_t)) +ccs_user_defined_tuner_get_history_type = ct.CFUNCTYPE(ccs_result, ccs_tuner, ct.c_size_t, ct.POINTER(ccs_evaluation), ct.POINTER(ct.c_size_t)) class ccs_user_defined_tuner_vector(ct.Structure): _fields_ = [ @@ -166,31 +166,24 @@ class ccs_user_defined_tuner_vector(ct.Structure): ('get_optimums', ccs_user_defined_tuner_get_optimums_type), ('get_history', ccs_user_defined_tuner_get_history_type) ] -class ccs_user_defined_tuner_data(ct.Structure): - _fields_ = [ - ('common_data', ccs_tuner_common_data), - ('vector', ccs_user_defined_tuner_vector), - ('tuner_data', ct.c_void_p) ] - ccs_create_user_defined_tuner = _ccs_get_function("ccs_create_user_defined_tuner", [ct.c_char_p, ccs_configuration_space, ccs_objective_space, ct.c_void_p, ct.POINTER(ccs_user_defined_tuner_vector), ct.c_void_p, ct.POINTER(ccs_tuner)]) +ccs_user_defined_tuner_get_tuner_data = _ccs_get_function("ccs_user_defined_tuner_get_tuner_data", [ccs_tuner, ct.POINTER(ct.c_void_p)]) def _wrap_user_defined_callbacks(delete, ask, tell, get_optimums, get_history): ptr = ct.c_int(33) - def delete_wrapper(data): + def delete_wrapper(tun): try: - data = ct.cast(data, ct.POINTER(ccs_user_defined_tuner_data)) - delete(data.contents) + delete(Object.from_handle(tun)) del _callbacks[ct.addressof(ptr)] return ccs_error.SUCCESS except Error as e: return -e.message.value - def ask_wrapper(data, count, p_configurations, p_count): + def ask_wrapper(tun, count, p_configurations, p_count): try: - data = ct.cast(data, ct.POINTER(ccs_user_defined_tuner_data)) p_confs = ct.cast(p_configurations, ct.c_void_p) p_c = ct.cast(p_count, ct.c_void_p) - (configurations, count_ret) = ask(data.contents, count if p_confs.value else None) + (configurations, count_ret) = ask(Tuner.from_handle(tun), count if p_confs.value else None) if p_confs.value is not None and count < count_ret: raise Error(ccs_error(ccs_error.INVALID_VALUE)) if p_confs.value is not None: @@ -206,26 +199,24 @@ def _wrap_user_defined_callbacks(delete, ask, tell, get_optimums, get_history): except Error as e: return -e.message.value - def tell_wrapper(data, count, p_evaluations): + def tell_wrapper(tun, count, p_evaluations): try: if count == 0: return ccs_error.SUCCESS - data = ct.cast(data, ct.POINTER(ccs_user_defined_tuner_data)) p_evals = ct.cast(p_evaluations, ct.c_void_p) if p_evals.value is None: raise Error(ccs_error(ccs_error.INVALID_VALUE)) evals = [Evaluation.from_handle(ccs_evaluation(p_evaluations[i])) for i in range(count)] - tell(data.contents, evals) + tell(Tuner.from_handle(tun), evals) return ccs_error.SUCCESS except Error as e: return -e.message.value - def get_optimums_wrapper(data, count, p_evaluations, p_count): + def get_optimums_wrapper(tun, count, p_evaluations, p_count): try: - data = ct.cast(data, ct.POINTER(ccs_user_defined_tuner_data)) p_evals = ct.cast(p_evaluations, ct.c_void_p) p_c = ct.cast(p_count, ct.c_void_p) - optimums = get_optimums(data.contents) + optimums = get_optimums(Tuner.from_handle(tun)) count_ret = len(optimums) if p_evals.value is not None and count < count_ret: raise Error(ccs_error(ccs_error.INVALID_VALUE)) @@ -240,12 +231,11 @@ def _wrap_user_defined_callbacks(delete, ask, tell, get_optimums, get_history): except Error as e: return -e.message.value - def get_history_wrapper(data, count, p_evaluations, p_count): + def get_history_wrapper(tun, count, p_evaluations, p_count): try: - data = ct.cast(data, ct.POINTER(ccs_user_defined_tuner_data)) p_evals = ct.cast(p_evaluations, ct.c_void_p) p_c = ct.cast(p_count, ct.c_void_p) - history = get_history(data.contents) + history = get_history(Tuner.from_handle(tun)) count_ret = len(history) if p_evals.value is not None and count < count_ret: raise Error(ccs_error(ccs_error.INVALID_VALUE)) @@ -305,4 +295,14 @@ class UserDefinedTuner(Tuner): else: super().__init__(handle = handle, retain = retain, auto_release = auto_release) + @property + def tuner_data(self): + if hasattr(self, "_tuner_data"): + return self._tuner_data + v = ct.c_void_p() + res = ccs_user_defined_tuner_get_tuner_data(self.handle, ct.byref(v)) + Error.check(res) + self._tuner_data = v + return v + diff --git a/bindings/python/test/test_tuner.py b/bindings/python/test/test_tuner.py index 99be3e8..5336f31 100644 --- a/bindings/python/test/test_tuner.py +++ b/bindings/python/test/test_tuner.py @@ -46,17 +46,17 @@ class TestTuner(unittest.TestCase): history = [] optimums = [] - def delete(data): + def delete(tuner): return None - def ask(data, count): + def ask(tuner, count): if count is None: return (None, 1) else: - cs = ccs.ConfigurationSpace.from_handle(ccs.ccs_configuration_space(data.common_data.configuration_space)) + cs = tuner.configuration_space return (cs.samples(count), count) - def tell(data, evaluations): + def tell(tuner, evaluations): nonlocal history nonlocal optimums history += evaluations @@ -78,10 +78,10 @@ class TestTuner(unittest.TestCase): optimums = new_optimums return None - def get_history(data): + def get_history(tuner): return history - def get_optimums(data): + def get_optimums(tuner): return optimums (cs, os) = self.create_tuning_problem() diff --git a/bindings/ruby/lib/cconfigspace/tuner.rb b/bindings/ruby/lib/cconfigspace/tuner.rb index 02d91e2..912a075 100644 --- a/bindings/ruby/lib/cconfigspace/tuner.rb +++ b/bindings/ruby/lib/cconfigspace/tuner.rb @@ -113,23 +113,11 @@ module CCS end end - class TunerCommonData < FFI::Struct - layout :type, :ccs_tuner_type_t, - :name, :string, - :user_data, :pointer, - :configuration_space, :ccs_configuration_space_t, - :objective_space, :ccs_objective_space_t - end - typedef TunerCommonData.by_value, :ccs_tuner_common_data_t - - class UserDefinedTunerData < FFI::Struct - end - - callback :ccs_user_defined_tuner_del, [UserDefinedTunerData.by_ref], :ccs_result_t - callback :ccs_user_defined_tuner_ask, [UserDefinedTunerData.by_ref, :size_t, :pointer, :pointer], :ccs_result_t - callback :ccs_user_defined_tuner_tell, [UserDefinedTunerData.by_ref, :size_t, :pointer], :ccs_result_t - callback :ccs_user_defined_tuner_get_optimums, [UserDefinedTunerData.by_ref, :size_t, :pointer, :pointer], :ccs_result_t - callback :ccs_user_defined_tuner_get_history, [UserDefinedTunerData.by_ref, :size_t, :pointer, :pointer], :ccs_result_t + callback :ccs_user_defined_tuner_del, [:ccs_tuner_t], :ccs_result_t + callback :ccs_user_defined_tuner_ask, [:ccs_tuner_t, :size_t, :pointer, :pointer], :ccs_result_t + callback :ccs_user_defined_tuner_tell, [:ccs_tuner_t, :size_t, :pointer], :ccs_result_t + callback :ccs_user_defined_tuner_get_optimums, [:ccs_tuner_t, :size_t, :pointer, :pointer], :ccs_result_t + callback :ccs_user_defined_tuner_get_history, [:ccs_tuner_t, :size_t, :pointer, :pointer], :ccs_result_t class UserDefinedTunerVector < FFI::Struct layout :del, :ccs_user_defined_tuner_del, :ask, :ccs_user_defined_tuner_ask, @@ -139,27 +127,19 @@ module CCS end typedef UserDefinedTunerVector.by_value, :ccs_user_defined_tuner_vector_t - class UserDefinedTunerData - layout :common_data, :ccs_tuner_common_data_t, - :vector, :ccs_user_defined_tuner_vector_t, - :tuner_data, :pointer - - end - typedef UserDefinedTunerData.by_value, :ccs_user_defined_tuner_data_t - def self.wrap_user_defined_callbacks(del, ask, tell, get_optimums, get_history) - delwrapper = lambda { |data| + delwrapper = lambda { |tun| begin - del.call(data) + del.call(CCS::Object.from_handle(tun)) @@callbacks.delete(delwrapper) CCSError.to_native(:CCS_SUCCESS) rescue CCSError => e e.to_native end } - askwrapper = lambda { |data, count, p_configurations, p_count| + askwrapper = lambda { |tun, count, p_configurations, p_count| begin - configurations, count_ret = ask.call(data, p_configurations.null? ? nil : count) + configurations, count_ret = ask.call(Tuner.from_handle(tun), p_configurations.null? ? nil : count) raise CCSError, :CCS_INVALID_VALUE if !p_configurations.null? && count < count_ret if !p_configurations.null? configurations.each_with_index { |c, i| @@ -175,20 +155,20 @@ module CCS e.to_native end } - tellwrapper = lambda { |data, count, p_evaluations| + tellwrapper = lambda { |tun, count, p_evaluations| begin if count > 0 evals = count.times.collect { |i| Evaluation::from_handle(p_evaluations.get_pointer(i*8)) } - tell.call(data, evals) + tell.call(Tuner.from_handle(tun), evals) end CCSError.to_native(:CCS_SUCCESS) rescue CCSError => e e.to_native end } - get_optimumswrapper = lambda { |data, count, p_evaluations, p_count| + get_optimumswrapper = lambda { |tun, count, p_evaluations, p_count| begin - optimums = get_optimums.call(data) + optimums = get_optimums.call(Tuner.from_handle(tun)) raise CCSError, :CCS_INVALID_VALUE if !p_evaluations.null? && count < optimums.size unless p_evaluations.null? optimums.each_with_index { |o, i| @@ -202,9 +182,9 @@ module CCS e.to_native end } - get_historywrapper = lambda { |data, count, p_evaluations, p_count| + get_historywrapper = lambda { |tun, count, p_evaluations, p_count| begin - history = get_history.call(data) + history = get_history.call(Tuner.from_handle(tun)) raise CCSError, :CCS_INVALID_VALUE if !p_evaluations.null? && count < history.size unless p_evaluations.null? history.each_with_index { |e, i| @@ -222,7 +202,9 @@ module CCS end attach_function :ccs_create_user_defined_tuner, [:string, :ccs_configuration_space_t, :ccs_objective_space_t, :pointer, UserDefinedTunerVector.by_ref, :pointer, :pointer], :ccs_result_t + attach_function :ccs_user_defined_tuner_get_tuner_data, [:ccs_tuner_t, :pointer], :ccs_result_t class UserDefinedTuner < Tuner + add_property :tuner_data, :pointer, :ccs_user_defined_tuner_get_tuner_data, memoize: true class << self attr_reader :callbacks end diff --git a/bindings/ruby/test/test_tuner.rb b/bindings/ruby/test/test_tuner.rb index b01bfb3..5057d44 100644 --- a/bindings/ruby/test/test_tuner.rb +++ b/bindings/ruby/test/test_tuner.rb @@ -51,16 +51,16 @@ class CConfigSpaceTestTuner < Minitest::Test def test_user_defined history = [] optimums = [] - del = lambda { |data| nil } - ask = lambda { |data, count| + del = lambda { |tuner| nil } + ask = lambda { |tuner, count| if count - cs = CCS::ConfigurationSpace::from_handle(data[:common_data][:configuration_space]) + cs = tuner.configuration_space [cs.samples(count), count] else [nil, 1] end } - tell = lambda { |data, evaluations| + tell = lambda { |tuner, evaluations| history += evaluations evaluations.each { |e| discard = false @@ -82,10 +82,10 @@ class CConfigSpaceTestTuner < Minitest::Test optimums.push(e) unless discard } } - get_history = lambda { |data| + get_history = lambda { |tuner| history } - get_optimums = lambda { |data| + get_optimums = lambda { |tuner| optimums } cs, os = create_tuning_problem diff --git a/include/cconfigspace/tuner.h b/include/cconfigspace/tuner.h index 943a9ef..3f598af 100644 --- a/include/cconfigspace/tuner.h +++ b/include/cconfigspace/tuner.h @@ -63,55 +63,35 @@ ccs_create_random_tuner(const char *name, void *user_data, ccs_tuner_t *tuner_ret); -struct ccs_tuner_common_data_s { - ccs_tuner_type_t type; - const char *name; - void *user_data; - ccs_configuration_space_t configuration_space; - ccs_objective_space_t objective_space; -}; -typedef struct ccs_tuner_common_data_s ccs_tuner_common_data_t; - - - -struct ccs_user_defined_tuner_data_s; -typedef struct ccs_user_defined_tuner_data_s ccs_user_defined_tuner_data_t; - struct ccs_user_defined_tuner_vector_s { ccs_result_t (*del)( - ccs_user_defined_tuner_data_t *data); + ccs_tuner_t tuner); ccs_result_t (*ask)( - ccs_user_defined_tuner_data_t *data, - size_t num_configurations, - ccs_configuration_t *configurations, - size_t *num_configurations_ret); + ccs_tuner_t tuner, + size_t num_configurations, + ccs_configuration_t *configurations, + size_t *num_configurations_ret); ccs_result_t (*tell)( - ccs_user_defined_tuner_data_t *data, - size_t num_evaluations, - ccs_evaluation_t *evaluations); + ccs_tuner_t tuner, + size_t num_evaluations, + ccs_evaluation_t *evaluations); ccs_result_t (*get_optimums)( - ccs_user_defined_tuner_data_t *data, - size_t num_evaluations, - ccs_evaluation_t *evaluations, - size_t *num_evaluations_ret); + ccs_tuner_t tuner, + size_t num_evaluations, + ccs_evaluation_t *evaluations, + size_t *num_evaluations_ret); ccs_result_t (*get_history)( - ccs_user_defined_tuner_data_t *data, - size_t num_evaluations, - ccs_evaluation_t *evaluations, - size_t *num_evaluations_ret); + ccs_tuner_t tuner, + size_t num_evaluations, + ccs_evaluation_t *evaluations, + size_t *num_evaluations_ret); }; typedef struct ccs_user_defined_tuner_vector_s ccs_user_defined_tuner_vector_t; -struct ccs_user_defined_tuner_data_s { - ccs_tuner_common_data_t common_data; - ccs_user_defined_tuner_vector_t vector; - void *tuner_data; -}; - extern ccs_result_t ccs_create_user_defined_tuner(const char *name, ccs_configuration_space_t configuration_space, @@ -121,6 +101,9 @@ ccs_create_user_defined_tuner(const char *name, void *tuner_data, ccs_tuner_t *tuner_ret); +extern ccs_result_t +ccs_user_defined_tuner_get_tuner_data(ccs_tuner_t tuner, + void **tuner_data_ret); #ifdef __cplusplus } diff --git a/samples/test_python.py b/samples/test_python.py index 707f394..0c6f8d1 100644 --- a/samples/test_python.py +++ b/samples/test_python.py @@ -11,17 +11,17 @@ class TestTuner(ccs.UserDefinedTuner): self.__history = [] self.__optimums = [] - def delete(data): + def delete(tuner): return None - def ask(data, count): + def ask(tuner, count): if count is None: return (None, 1) else: - cs = ccs.ConfigurationSpace.from_handle(ccs.ccs_configuration_space(data.common_data.configuration_space)) + cs = tuner.configuration_space return (cs.samples(count), count) - def tell(data, evaluations): + def tell(tuner, evaluations): self.__history += evaluations for e in evaluations: discard = False @@ -41,10 +41,10 @@ class TestTuner(ccs.UserDefinedTuner): self.__optimums = new_optimums return None - def get_history(data): + def get_history(tuner): return self.__history - def get_optimums(data): + def get_optimums(tuner): return self.__optimums super().__init__(name = "tuner", configuration_space = cs, objective_space = os, delete = delete, ask = ask, tell = tell, get_optimums = get_optimums, get_history = get_history) diff --git a/samples/test_python_from_ruby.rb b/samples/test_python_from_ruby.rb index 30619ea..83a060e 100644 --- a/samples/test_python_from_ruby.rb +++ b/samples/test_python_from_ruby.rb @@ -1,4 +1,4 @@ -ENV["PYTHONPATH"] = "./:"+ ENV["PYTHONPATH"] +ENV["PYTHONPATH"] = "./" + (ENV["PYTHONPATH"] ? ":"+ ENV["PYTHONPATH"] : "") require 'rubygems' require_relative '../bindings/ruby/lib/cconfigspace' diff --git a/samples/test_ruby.rb b/samples/test_ruby.rb index e14b8fa..161cb5e 100644 --- a/samples/test_ruby.rb +++ b/samples/test_ruby.rb @@ -5,16 +5,16 @@ class TestTuner < CCS::UserDefinedTuner def initialize(cs, os) @history = [] @optimums = [] - del = lambda { |data| nil } - ask = lambda { |data, count| + del = lambda { |tuner| nil } + ask = lambda { |tuner, count| if count - cs = CCS::ConfigurationSpace::from_handle(data[:common_data][:configuration_space]) + cs = tuner.configuration_space [cs.samples(count), count] else [nil, 1] end } - tell = lambda { |data, evaluations| + tell = lambda { |tuner, evaluations| @history += evaluations evaluations.each { |e| discard = false @@ -36,10 +36,10 @@ class TestTuner < CCS::UserDefinedTuner @optimums.push(e) unless discard } } - get_history = lambda { |data| + get_history = lambda { |tuner| @history } - get_optimums = lambda { |data| + get_optimums = lambda { |tuner| @optimums } super(name: "tuner", configuration_space: cs, objective_space: os, del: del, ask: ask, tell: tell, get_optimums: get_optimums, get_history: get_history) diff --git a/src/tuner.c b/src/tuner.c index 286f9c1..638e55f 100644 --- a/src/tuner.c +++ b/src/tuner.c @@ -11,7 +11,7 @@ ccs_tuner_get_type(ccs_tuner_t tuner, ccs_tuner_type_t *type_ret) { CCS_CHECK_OBJ(tuner, CCS_TUNER); CCS_CHECK_PTR(type_ret); - ccs_tuner_common_data_t *d = (ccs_tuner_common_data_t *)tuner->data; + _ccs_tuner_common_data_t *d = (_ccs_tuner_common_data_t *)tuner->data; *type_ret = d->type; return CCS_SUCCESS; } @@ -21,7 +21,7 @@ ccs_tuner_get_name(ccs_tuner_t tuner, const char **name_ret) { CCS_CHECK_OBJ(tuner, CCS_TUNER); CCS_CHECK_PTR(name_ret); - ccs_tuner_common_data_t *d = (ccs_tuner_common_data_t *)tuner->data; + _ccs_tuner_common_data_t *d = (_ccs_tuner_common_data_t *)tuner->data; *name_ret = d->name; return CCS_SUCCESS; } @@ -31,7 +31,7 @@ ccs_tuner_get_user_data(ccs_tuner_t tuner, void **user_data_ret) { CCS_CHECK_OBJ(tuner, CCS_TUNER); CCS_CHECK_PTR(user_data_ret); - ccs_tuner_common_data_t *d = (ccs_tuner_common_data_t *)tuner->data; + _ccs_tuner_common_data_t *d = (_ccs_tuner_common_data_t *)tuner->data; *user_data_ret = d->user_data; return CCS_SUCCESS; } @@ -41,7 +41,7 @@ ccs_tuner_get_configuration_space(ccs_tuner_t tuner, ccs_configuration_space_t *configuration_space_ret) { CCS_CHECK_OBJ(tuner, CCS_TUNER); CCS_CHECK_PTR(configuration_space_ret); - ccs_tuner_common_data_t *d = (ccs_tuner_common_data_t *)tuner->data; + _ccs_tuner_common_data_t *d = (_ccs_tuner_common_data_t *)tuner->data; *configuration_space_ret = d->configuration_space; return CCS_SUCCESS; } @@ -51,7 +51,7 @@ ccs_tuner_get_objective_space(ccs_tuner_t tuner, ccs_objective_space_t *objective_space_ret) { CCS_CHECK_OBJ(tuner, CCS_TUNER); CCS_CHECK_PTR(objective_space_ret); - ccs_tuner_common_data_t *d = (ccs_tuner_common_data_t *)tuner->data; + _ccs_tuner_common_data_t *d = (_ccs_tuner_common_data_t *)tuner->data; *objective_space_ret = d->objective_space; return CCS_SUCCESS; } diff --git a/src/tuner_internal.h b/src/tuner_internal.h index 7e9c865..b31549b 100644 --- a/src/tuner_internal.h +++ b/src/tuner_internal.h @@ -37,4 +37,13 @@ struct _ccs_tuner_s { _ccs_tuner_data_t *data; }; +struct _ccs_tuner_common_data_s { + ccs_tuner_type_t type; + const char *name; + void *user_data; + ccs_configuration_space_t configuration_space; + ccs_objective_space_t objective_space; +}; +typedef struct _ccs_tuner_common_data_s _ccs_tuner_common_data_t; + #endif //_TUNER_INTERNAL_H diff --git a/src/tuner_random.c b/src/tuner_random.c index 3bb77bd..e056ec2 100644 --- a/src/tuner_random.c +++ b/src/tuner_random.c @@ -4,10 +4,10 @@ #include "utarray.h" struct _ccs_random_tuner_data_s { - ccs_tuner_common_data_t common_data; - UT_array *history; - UT_array *optimums; - UT_array *old_optimums; + _ccs_tuner_common_data_t common_data; + UT_array *history; + UT_array *optimums; + UT_array *old_optimums; }; typedef struct _ccs_random_tuner_data_s _ccs_random_tuner_data_t; diff --git a/src/tuner_user_defined.c b/src/tuner_user_defined.c index c076355..c42cfb5 100644 --- a/src/tuner_user_defined.c +++ b/src/tuner_user_defined.c @@ -2,12 +2,20 @@ #include "tuner_internal.h" #include "string.h" +struct _ccs_user_defined_tuner_data_s { + _ccs_tuner_common_data_t common_data; + ccs_tuner_t selfref; + ccs_user_defined_tuner_vector_t vector; + void *tuner_data; +}; +typedef struct _ccs_user_defined_tuner_data_s _ccs_user_defined_tuner_data_t; + static ccs_result_t _ccs_tuner_user_defined_del(ccs_object_t o) { - ccs_user_defined_tuner_data_t *d = - (ccs_user_defined_tuner_data_t *)((ccs_tuner_t)o)->data; + _ccs_user_defined_tuner_data_t *d = + (_ccs_user_defined_tuner_data_t *)((ccs_tuner_t)o)->data; ccs_result_t err; - err = d->vector.del(d); + err = d->vector.del(o); ccs_release_object(d->common_data.configuration_space); ccs_release_object(d->common_data.objective_space); return err; @@ -18,18 +26,18 @@ _ccs_tuner_user_defined_ask(_ccs_tuner_data_t *data, size_t num_configurations, ccs_configuration_t *configurations, size_t *num_configurations_ret) { - ccs_user_defined_tuner_data_t *d = - (ccs_user_defined_tuner_data_t *)data; - return d->vector.ask(d, num_configurations, configurations, num_configurations_ret); + _ccs_user_defined_tuner_data_t *d = + (_ccs_user_defined_tuner_data_t *)data; + return d->vector.ask(d->selfref, num_configurations, configurations, num_configurations_ret); } static ccs_result_t _ccs_tuner_user_defined_tell(_ccs_tuner_data_t *data, size_t num_evaluations, ccs_evaluation_t *evaluations) { - ccs_user_defined_tuner_data_t *d = - (ccs_user_defined_tuner_data_t *)data; - return d->vector.tell(d, num_evaluations, evaluations); + _ccs_user_defined_tuner_data_t *d = + (_ccs_user_defined_tuner_data_t *)data; + return d->vector.tell(d->selfref, num_evaluations, evaluations); } static ccs_result_t @@ -37,9 +45,9 @@ _ccs_tuner_user_defined_get_optimums(_ccs_tuner_data_t *data, size_t num_evaluations, ccs_evaluation_t *evaluations, size_t *num_evaluations_ret) { - ccs_user_defined_tuner_data_t *d = - (ccs_user_defined_tuner_data_t *)data; - return d->vector.get_optimums(d, num_evaluations, evaluations, num_evaluations_ret); + _ccs_user_defined_tuner_data_t *d = + (_ccs_user_defined_tuner_data_t *)data; + return d->vector.get_optimums(d->selfref, num_evaluations, evaluations, num_evaluations_ret); } static ccs_result_t @@ -47,9 +55,9 @@ _ccs_tuner_user_defined_get_history(_ccs_tuner_data_t *data, size_t num_evaluations, ccs_evaluation_t *evaluations, size_t *num_evaluations_ret) { - ccs_user_defined_tuner_data_t *d = - (ccs_user_defined_tuner_data_t *)data; - return d->vector.get_history(d, num_evaluations, evaluations, num_evaluations_ret); + _ccs_user_defined_tuner_data_t *d = + (_ccs_user_defined_tuner_data_t *)data; + return d->vector.get_history(d->selfref, num_evaluations, evaluations, num_evaluations_ret); } static _ccs_tuner_ops_t _ccs_tuner_user_defined_ops = { @@ -81,12 +89,12 @@ ccs_create_user_defined_tuner(const char *name, uintptr_t mem = (uintptr_t)calloc(1, sizeof(struct _ccs_tuner_s) + - sizeof(struct ccs_user_defined_tuner_data_s) + + sizeof(struct _ccs_user_defined_tuner_data_s) + strlen(name) + 1); if (!mem) return -CCS_OUT_OF_MEMORY; ccs_tuner_t tun; - ccs_user_defined_tuner_data_t * data; + _ccs_user_defined_tuner_data_t * data; ccs_result_t err; err = ccs_retain_object(configuration_space); if (err) @@ -98,14 +106,15 @@ ccs_create_user_defined_tuner(const char *name, tun = (ccs_tuner_t)mem; _ccs_object_init(&(tun->obj), CCS_TUNER, (_ccs_object_ops_t *)&_ccs_tuner_user_defined_ops); tun->data = (struct _ccs_tuner_data_s *)(mem + sizeof(struct _ccs_tuner_s)); - data = (ccs_user_defined_tuner_data_t *)tun->data; + data = (_ccs_user_defined_tuner_data_t *)tun->data; data->common_data.type = CCS_TUNER_USER_DEFINED; data->common_data.name = (const char *)(mem + sizeof(struct _ccs_tuner_s) + - sizeof(struct ccs_user_defined_tuner_data_s)); + sizeof(struct _ccs_user_defined_tuner_data_s)); data->common_data.user_data = user_data; data->common_data.configuration_space = configuration_space; data->common_data.objective_space = objective_space; + data->selfref = tun; data->vector = *vector; data->tuner_data = tuner_data; strcpy((char*)data->common_data.name, name); @@ -118,5 +127,16 @@ errmem: return err; } - +ccs_result_t +ccs_user_defined_tuner_get_tuner_data(ccs_tuner_t tuner, + void **tuner_data_ret) { + CCS_CHECK_OBJ(tuner, CCS_TUNER); + CCS_CHECK_PTR(tuner_data_ret); + _ccs_user_defined_tuner_data_t *d = + (_ccs_user_defined_tuner_data_t *)tuner->data; + if ( d->common_data.type != CCS_TUNER_USER_DEFINED) + return -CCS_INVALID_TUNER; + *tuner_data_ret = d->tuner_data; + return CCS_SUCCESS; +} diff --git a/tests/test_user_defined_tuner.c b/tests/test_user_defined_tuner.c index dc24d51..cf5bdda 100644 --- a/tests/test_user_defined_tuner.c +++ b/tests/test_user_defined_tuner.c @@ -20,26 +20,33 @@ struct tuner_last_s { typedef struct tuner_last_s tuner_last_t; ccs_result_t -tuner_last_del(ccs_user_defined_tuner_data_t *data) { +tuner_last_del(ccs_tuner_t tuner) { tuner_last_t *tuner_data; - tuner_data = (tuner_last_t *)(data->tuner_data); - if (tuner_data->last_eval) + ccs_result_t err; + err = ccs_user_defined_tuner_get_tuner_data(tuner, (void**)&tuner_data); + if (err) + return err; + if (tuner_data && tuner_data->last_eval) ccs_release_object(tuner_data->last_eval); free(tuner_data); return CCS_SUCCESS; } ccs_result_t -tuner_last_ask(ccs_user_defined_tuner_data_t *data, - size_t num_configurations, - ccs_configuration_t *configurations, - size_t *num_configurations_ret) { +tuner_last_ask(ccs_tuner_t tuner, + size_t num_configurations, + ccs_configuration_t *configurations, + size_t *num_configurations_ret) { if (!configurations) { *num_configurations_ret = 1; return CCS_SUCCESS; } ccs_result_t err; - err = ccs_configuration_space_samples(data->common_data.configuration_space, + ccs_configuration_space_t configuration_space; + err = ccs_tuner_get_configuration_space(tuner, &configuration_space); + if (err) + return err; + err = ccs_configuration_space_samples(configuration_space, num_configurations, configurations); if (err) return err; @@ -49,13 +56,16 @@ tuner_last_ask(ccs_user_defined_tuner_data_t *data, } ccs_result_t -tuner_last_tell(ccs_user_defined_tuner_data_t *data, - size_t num_evaluations, - ccs_evaluation_t *evaluations) { +tuner_last_tell(ccs_tuner_t tuner, + size_t num_evaluations, + ccs_evaluation_t *evaluations) { if (!num_evaluations) return CCS_SUCCESS; - tuner_last_t *tuner_data = (tuner_last_t *)(data->tuner_data); ccs_result_t err; + tuner_last_t *tuner_data; + err = ccs_user_defined_tuner_get_tuner_data(tuner, (void**)&tuner_data); + if (err) + return err; err = ccs_retain_object(evaluations[num_evaluations - 1]); if (err) return err; @@ -66,14 +76,18 @@ tuner_last_tell(ccs_user_defined_tuner_data_t *data, } ccs_result_t -tuner_last_get_optimums(ccs_user_defined_tuner_data_t *data, - size_t num_evaluations, - ccs_evaluation_t *evaluations, - size_t *num_evaluations_ret) { +tuner_last_get_optimums(ccs_tuner_t tuner, + size_t num_evaluations, + ccs_evaluation_t *evaluations, + size_t *num_evaluations_ret) { if (evaluations) { if (num_evaluations < 1) return -CCS_INVALID_VALUE; - tuner_last_t *tuner_data = (tuner_last_t *)(data->tuner_data); + ccs_result_t err; + tuner_last_t *tuner_data; + err = ccs_user_defined_tuner_get_tuner_data(tuner, (void**)&tuner_data); + if (err) + return err; evaluations[0] = tuner_data->last_eval; for(size_t i = 1; i < num_evaluations; i++) evaluations[i] = NULL; @@ -84,14 +98,18 @@ tuner_last_get_optimums(ccs_user_defined_tuner_data_t *data, } ccs_result_t -tuner_last_get_history(ccs_user_defined_tuner_data_t *data, - size_t num_evaluations, - ccs_evaluation_t *evaluations, - size_t *num_evaluations_ret) { +tuner_last_get_history(ccs_tuner_t tuner, + size_t num_evaluations, + ccs_evaluation_t *evaluations, + size_t *num_evaluations_ret) { if (evaluations) { if (num_evaluations < 1) return -CCS_INVALID_VALUE; - tuner_last_t *tuner_data = (tuner_last_t *)(data->tuner_data); + ccs_result_t err; + tuner_last_t *tuner_data; + err = ccs_user_defined_tuner_get_tuner_data(tuner, (void**)&tuner_data); + if (err) + return err; evaluations[0] = tuner_data->last_eval; for(size_t i = 1; i < num_evaluations; i++) evaluations[i] = NULL; -- 2.26.2