Commit 0d900261 authored by Brice Videau's avatar Brice Videau

Example of python tuner used in c land.

parent cc98c2aa
......@@ -24,6 +24,7 @@ AC_HEADER_ASSERT
#
PKG_CHECK_MODULES([RUBY], [ruby >= 2.3])
PKG_CHECK_MODULES([PYTHON], [python3-embed >= 3.6])
#check for libraries
AC_CHECK_LIB([m],[cos])
......@@ -44,5 +45,6 @@ AC_CONFIG_FILES([Makefile
tests/Makefile
samples/Makefile
cconfigspace.pc])
AC_CONFIG_LINKS([samples/test_ruby.rb:samples/test_ruby.rb])
AC_CONFIG_LINKS([samples/test_ruby.rb:samples/test_ruby.rb
samples/test_python.py:samples/test_python.py])
AC_OUTPUT
AM_COLOR_TESTS = yes
AM_CFLAGS = -I$(top_srcdir)/include -Wall -Werror -Wpedantic $(RUBY_CFLAGS)
AM_LDFLAGS = ../src/libcconfigspace.la $(RUBY_LIBS)
test_ruby_CFLAGS = -I$(top_srcdir)/include -Wall -Werror -Wpedantic $(RUBY_CFLAGS)
test_ruby_LDFLAGS = ../src/libcconfigspace.la $(RUBY_LIBS)
test_python_CFLAGS = -I$(top_srcdir)/include -Wall -Werror -Wpedantic $(PYTHON_CFLAGS)
test_python_LDFLAGS = ../src/libcconfigspace.la $(PYTHON_LIBS)
CCONFIGSPACE_TESTS = \
test_ruby
test_ruby \
test_python
# unit tests
UNIT_TESTS = \
......
#include <stdlib.h>
#include <assert.h>
#include <cconfigspace.h>
#include <string.h>
#include <Python.h>
ccs_hyperparameter_t create_numerical(const char * name, double lower, double upper) {
ccs_hyperparameter_t hyperparameter;
ccs_result_t err;
err = ccs_create_numerical_hyperparameter(name, CCS_NUM_FLOAT,
CCSF(lower), CCSF(upper),
CCSF(0.0), CCSF(0),
NULL, &hyperparameter);
assert( err == CCS_SUCCESS );
return hyperparameter;
}
void create_problem(ccs_configuration_space_t *cs, ccs_objective_space_t *os) {
ccs_hyperparameter_t hyperparameter1, hyperparameter2;
ccs_hyperparameter_t hyperparameter3;
ccs_configuration_space_t cspace;
ccs_objective_space_t ospace;
ccs_expression_t expression;
ccs_result_t err;
hyperparameter1 = create_numerical("x", -5.0, 5.0);
hyperparameter2 = create_numerical("y", -5.0, 5.0);
err = ccs_create_configuration_space("2dplane", NULL, &cspace);
assert( err == CCS_SUCCESS );
err = ccs_configuration_space_add_hyperparameter(cspace, hyperparameter1, NULL);
assert( err == CCS_SUCCESS );
err = ccs_configuration_space_add_hyperparameter(cspace, hyperparameter2, NULL);
assert( err == CCS_SUCCESS );
hyperparameter3 = create_numerical("z", -CCS_INFINITY, CCS_INFINITY);
err = ccs_create_variable(hyperparameter3, &expression);
assert( err == CCS_SUCCESS );
err = ccs_create_objective_space("height", NULL, &ospace);
assert( err == CCS_SUCCESS );
err = ccs_objective_space_add_hyperparameter(ospace, hyperparameter3);
assert( err == CCS_SUCCESS );
err = ccs_objective_space_add_objective(ospace, expression, CCS_MINIMIZE);
assert( err == CCS_SUCCESS );
err = ccs_release_object(hyperparameter1);
assert( err == CCS_SUCCESS );
err = ccs_release_object(hyperparameter2);
assert( err == CCS_SUCCESS );
err = ccs_release_object(hyperparameter3);
assert( err == CCS_SUCCESS );
err = ccs_release_object(&expression);
assert( err == CCS_SUCCESS );
*cs = cspace;
*os = ospace;
}
void test_tuner(ccs_tuner_t tuner, ccs_objective_space_t ospace) {
ccs_result_t err;
for (size_t i = 0; i < 100; i++) {
ccs_datum_t values[2], res;
ccs_configuration_t configuration;
ccs_evaluation_t evaluation;
err = ccs_tuner_ask(tuner, 1, &configuration, NULL);
assert( err == CCS_SUCCESS );
err = ccs_configuration_get_values(configuration, 2, values, NULL);
assert( err == CCS_SUCCESS );
res = ccs_float((values[0].value.f - 1)*(values[0].value.f - 1) +
(values[1].value.f - 2)*(values[1].value.f - 2));
ccs_create_evaluation(ospace, configuration, CCS_SUCCESS, 1, &res, NULL, &evaluation);
err = ccs_tuner_tell(tuner, 1, &evaluation);
assert( err == CCS_SUCCESS );
err = ccs_release_object(configuration);
assert( err == CCS_SUCCESS );
err = ccs_release_object(evaluation);
assert( err == CCS_SUCCESS );
}
size_t count;
ccs_evaluation_t history[100];
ccs_datum_t min = ccs_float(INFINITY);
err = ccs_tuner_get_history(tuner, 100, history, &count);
assert( err == CCS_SUCCESS );
assert( count == 100 );
for (size_t i = 0; i < 100; i++) {
ccs_datum_t res;
err = ccs_evaluation_get_objective_value(history[i], 0, &res);
assert( err == CCS_SUCCESS );
if (res.value.f < min.value.f)
min.value.f = res.value.f;
}
ccs_evaluation_t evaluation;
ccs_datum_t res;
err = ccs_tuner_get_optimums(tuner, 1, &evaluation, NULL);
assert( err == CCS_SUCCESS );
err = ccs_evaluation_get_objective_value(evaluation, 0, &res);
assert( res.value.f == min.value.f );
}
void test() {
ccs_tuner_t t;
ccs_configuration_space_t cs;
ccs_objective_space_t os;
ccs_result_t err;
create_problem(&cs, &os);
PyObject *pName, *pModule, *pFunc;
PyObject *pArgs, *pValue, *pHandle, *pAddr;
Py_SetProgramName(L"test_python");
Py_Initialize();
PyRun_SimpleString("import sys\n"
"sys.path.insert(1, '.')\n"
"sys.path.insert(1, '..')\n");
pName = PyUnicode_DecodeFSDefault("test_python");
pModule = PyImport_Import(pName);
Py_DECREF(pName);
if (pModule != NULL) {
pFunc = PyObject_GetAttrString(pModule, "create_test_tuner");
pArgs = PyTuple_New(2);
pValue = PyLong_FromVoidPtr(cs);
PyTuple_SetItem(pArgs, 0, pValue);
pValue = PyLong_FromVoidPtr(os);
PyTuple_SetItem(pArgs, 1, pValue);
pValue = PyObject_CallObject(pFunc, pArgs);
Py_DECREF(pArgs);
Py_DECREF(pFunc);
pHandle = PyObject_GetAttrString(pValue, "handle");
pAddr = PyObject_GetAttrString(pHandle, "value");
t = PyLong_AsVoidPtr(pAddr);
err = ccs_retain_object(t);
Py_DECREF(pHandle);
Py_DECREF(pAddr);
Py_DECREF(pValue);
assert( err == CCS_SUCCESS );
test_tuner(t, os);
err = ccs_release_object(t);
assert( err == CCS_SUCCESS );
} else {
if (PyErr_Occurred())
PyErr_Print();
assert(0);
}
err = ccs_release_object(os);
assert( err == CCS_SUCCESS );
err = ccs_release_object(cs);
assert( err == CCS_SUCCESS );
Py_Finalize();
}
int main() {
ccs_init();
test();
return 0;
}
import unittest
import sys
sys.path.insert(1, '../bindings/python')
sys.path.insert(1, '../../bindings/python')
import cconfigspace as ccs
import ctypes as ct
from math import sin
class TestTuner(ccs.UserDefinedTuner):
def __init__(self, cs, os):
self.__history = []
self.__optimums = []
def delete(data):
return None
def ask(data, count):
if count is None:
return (None, 1)
else:
cs = ccs.ConfigurationSpace.from_handle(ccs.ccs_configuration_space(data.common_data.configuration_space))
return (cs.samples(count), count)
def tell(data, evaluations):
self.__history += evaluations
for e in evaluations:
discard = False
new_optimums = []
for o in self.__optimums:
if discard:
new_optimums.append(o)
else:
c = e.cmp(o).value
if c == ccs.EQUIVALENT or c == ccs.WORSE:
discard = True
new_optimums.append(o)
elif c == ccs.NOT_COMPARABLE:
new_optimums.append(o)
if not discard:
new_optimums.append(e)
self.__optimums = new_optimums
return None
def get_history(data):
return self.__history
def get_optimums(data):
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)
def create_test_tuner(cs_ptr, os_ptr):
cs_handle = ccs.ccs_configuration_space(cs_ptr)
os_handle = ccs.ccs_objective_space(os_ptr)
cs = ccs.ConfigurationSpace.from_handle(cs_handle)
os = ccs.ObjectiveSpace.from_handle(os_handle)
t = TestTuner(cs, os)
return t
def create_tuning_problem():
cs = ccs.ConfigurationSpace(name = "cspace")
h1 = ccs.NumericalHyperparameter(lower = -5.0, upper = 5.0)
h2 = ccs.NumericalHyperparameter(lower = -5.0, upper = 5.0)
h3 = ccs.NumericalHyperparameter(lower = -5.0, upper = 5.0)
cs.add_hyperparameters([h1, h2, h3])
os = ccs.ObjectiveSpace(name = "ospace")
v1 = ccs.NumericalHyperparameter(lower = float('-inf'), upper = float('inf'))
v2 = ccs.NumericalHyperparameter(lower = float('-inf'), upper = float('inf'))
os.add_hyperparameters([v1, v2])
e1 = ccs.Variable(hyperparameter = v1)
e2 = ccs.Variable(hyperparameter = v2)
os.add_objectives( [e1, e2] )
return (cs, os)
class Test(unittest.TestCase):
def test_user_defined(self):
(cs, os) = create_tuning_problem()
t = TestTuner(cs, os)
self.assertEqual("tuner", t.name)
self.assertEqual(ccs.TUNER_USER_DEFINED, t.type.value)
self.assertEqual(cs.handle.value, t.configuration_space.handle.value)
self.assertEqual(os.handle.value, t.objective_space.handle.value)
func = lambda x, y, z: [(x-2)*(x-2), sin(z+y)]
evals = [ccs.Evaluation(objective_space = os, configuration = c, values = func(*(c.values))) for c in t.ask(100)]
t.tell(evals)
hist = t.history
self.assertEqual(100, len(hist))
evals = [ccs.Evaluation(objective_space = os, configuration = c, values = func(*(c.values))) for c in t.ask(100)]
t.tell(evals)
hist = t.history
self.assertEqual(200, len(hist))
optims = t.optimums
objs = [x.objective_values for x in optims]
objs.sort(key = lambda x: x[0])
# assert pareto front
self.assertTrue(all(objs[i][1] >= objs[i+1][1] for i in range(len(objs)-1)))
if __name__ == '__main__':
unittest.main()
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment