Commit 504dee7a authored by Brice Videau's avatar Brice Videau
Browse files

Added test for basic configuration space functionalities.

parent 3c735557
......@@ -36,8 +36,11 @@ enum ccs_error_e {
CCS_INVALID_VALUE,
CCS_INVALID_TYPE,
CCS_INVALID_SCALE,
CCS_INVALID_DISTRIBUTION,
CCS_INVALID_HYPERPARAMETER,
CCS_TYPE_NOT_COMPARABLE,
CCS_INVALID_BOUNDS,
CCS_OUT_OF_BOUNDS,
CCS_SAMPLING_UNSUCCESSFUL,
CCS_ENOMEM,
CCS_ERROR_MAX,
......
......@@ -51,6 +51,12 @@ ccs_configuration_space_get_hyperparameter(ccs_configuration_space_t configurat
size_t index,
ccs_hyperparameter_t *hyperparameter_ret);
extern ccs_error_t
ccs_configuration_space_get_hyperparameter_by_name(
ccs_configuration_space_t configuration_space,
const char * name,
ccs_hyperparameter_t *hyperparameter_ret);
extern ccs_error_t
ccs_configuration_space_get_hyperparameters(ccs_configuration_space_t configuration_space,
size_t num_hyperparameters,
......
......@@ -83,6 +83,10 @@ extern ccs_error_t
ccs_distribution_get_data_type(ccs_distribution_t distribution,
ccs_numeric_type_t *data_type_ret);
extern ccs_error_t
ccs_distribution_get_dimension(ccs_distribution_t distribution,
size_t *dimension);
extern ccs_error_t
ccs_distribution_get_scale_type(ccs_distribution_t distribution,
ccs_scale_type_t *scale_type_ret);
......
......@@ -13,10 +13,16 @@ _ccs_configuration_space_del(ccs_object_t object) {
_ccs_hyperparameter_wrapper_t *wrapper = NULL;
while ( (wrapper = (_ccs_hyperparameter_wrapper_t *)utarray_next(array, wrapper)) ) {
ccs_release_object(wrapper->hyperparameter);
ccs_release_object(wrapper->distribution);
}
HASH_CLEAR(hh_name, configuration_space->data->name_hash);
utarray_free(array);
_ccs_distribution_wrapper_t *dw;
_ccs_distribution_wrapper_t *tmp;
DL_FOREACH_SAFE(configuration_space->data->distribution_list, dw, tmp) {
DL_DELETE(configuration_space->data->distribution_list, dw);
ccs_release_object(dw->distribution);
free(dw);
}
ccs_release_object(configuration_space->data->rng);
return CCS_SUCCESS;
}
......@@ -61,6 +67,7 @@ ccs_create_configuration_space(const char *name,
config_space->data->rng = rng;
utarray_new(config_space->data->hyperparameters, &_hyperparameter_wrapper_icd);
config_space->data->name_hash = NULL;
config_space->data->distribution_list = NULL;
strcpy((char *)(config_space->data->name), name);
*configuration_space_ret = config_space;
return CCS_SUCCESS;
......@@ -116,7 +123,7 @@ ccs_configuration_space_get_rng(ccs_configuration_space_t configuration_space,
#undef utarray_oom
#define utarray_oom() { \
err = -CCS_ENOMEM; \
goto errordistrib; \
goto errordistrib_wrapper; \
}
#undef uthash_nonfatal_oom
#define uthash_nonfatal_oom(elt) { \
......@@ -130,37 +137,80 @@ ccs_configuration_space_add_hyperparameter(ccs_configuration_space_t configurati
if (!configuration_space || !configuration_space->data || !hyperparameter)
return -CCS_INVALID_OBJECT;
ccs_error_t err;
const char *name;
size_t sz_name;
_ccs_hyperparameter_wrapper_t *p_hyper_wrapper;
err = ccs_hyperparameter_get_name(hyperparameter, &name);
if (err)
goto error;
sz_name = strlen(name);
HASH_FIND(hh_name, configuration_space->data->name_hash,
name, sz_name, p_hyper_wrapper);
if (p_hyper_wrapper) {
err = -CCS_INVALID_HYPERPARAMETER;
goto error;
}
UT_array *hyperparameters;
unsigned int index;
size_t dimension;
_ccs_hyperparameter_wrapper_t hyper_wrapper;
_ccs_distribution_wrapper_t *distrib_wrapper;
uintptr_t pmem;
hyper_wrapper.hyperparameter = hyperparameter;
err = ccs_retain_object(hyperparameter);
if (err)
goto error;
if (distribution) {
ccs_retain_object(distribution);
hyper_wrapper.distribution = distribution;
err = ccs_distribution_get_dimension(distribution, &dimension);
if (err)
goto errorhyper;
if (dimension != 1) {
err = -CCS_INVALID_DISTRIBUTION;
goto errorhyper;
}
err = ccs_retain_object(distribution);
if (err)
goto errorhyper;
} else {
err = ccs_hyperparameter_get_default_distribution(hyperparameter, &hyper_wrapper.distribution);
err = ccs_hyperparameter_get_default_distribution(hyperparameter, &distribution);
if (err)
goto error;
goto errorhyper;
dimension = 1;
}
pmem = (uintptr_t)malloc(sizeof(_ccs_distribution_wrapper_t) + sizeof(size_t)*dimension);
if (!pmem) {
err = -CCS_ENOMEM;
goto errordistrib;
}
distrib_wrapper = (_ccs_distribution_wrapper_t *)pmem;
distrib_wrapper->distribution = distribution;
distrib_wrapper->dimension = dimension;
distrib_wrapper->hyperparameter_indexes = (size_t *)(pmem + sizeof(_ccs_distribution_wrapper_t));
distrib_wrapper->hyperparameter_indexes[0] = 0;
hyperparameters = configuration_space->data->hyperparameters;
index = utarray_len(hyperparameters);
hyper_wrapper.index = index;
err = ccs_hyperparameter_get_name(hyperparameter, &hyper_wrapper.name);
if (err)
goto errordistrib;
hyper_wrapper.distribution_index = 0;
hyper_wrapper.distribution = distrib_wrapper;
hyper_wrapper.name = name;
utarray_push_back(hyperparameters, &hyper_wrapper);
_ccs_hyperparameter_wrapper_t *p_hyper_wrapper =
p_hyper_wrapper =
(_ccs_hyperparameter_wrapper_t*)utarray_eltptr(hyperparameters, index);
HASH_ADD_KEYPTR( hh_name, configuration_space->data->name_hash,
p_hyper_wrapper->name, strlen(p_hyper_wrapper->name),
p_hyper_wrapper );
name, sz_name, p_hyper_wrapper );
DL_APPEND(configuration_space->data->distribution_list, distrib_wrapper);
return CCS_SUCCESS;
errorutarray:
utarray_pop_back(hyperparameters);
errordistrib_wrapper:
free(distrib_wrapper);
errordistrib:
ccs_release_object(hyper_wrapper.distribution);
ccs_release_object(distribution);
errorhyper:
ccs_release_object(hyperparameter);
error:
return err;
}
......@@ -211,9 +261,31 @@ ccs_configuration_space_get_hyperparameter(ccs_configuration_space_t configurat
return -CCS_INVALID_VALUE;
_ccs_hyperparameter_wrapper_t *wrapper = (_ccs_hyperparameter_wrapper_t*)
utarray_eltptr(configuration_space->data->hyperparameters, (unsigned int)index);
if (!wrapper)
if (wrapper)
*hyperparameter_ret = wrapper->hyperparameter;
else
*hyperparameter_ret = NULL;
return CCS_SUCCESS;
}
ccs_error_t
ccs_configuration_space_get_hyperparameter_by_name(
ccs_configuration_space_t configuration_space,
const char * name,
ccs_hyperparameter_t *hyperparameter_ret) {
if (!configuration_space || !configuration_space->data)
return -CCS_INVALID_OBJECT;
if (!hyperparameter_ret)
return -CCS_INVALID_VALUE;
*hyperparameter_ret = wrapper->hyperparameter;
_ccs_hyperparameter_wrapper_t *wrapper;
size_t sz_name;
sz_name = strlen(name);
HASH_FIND(hh_name, configuration_space->data->name_hash,
name, sz_name, wrapper);
if (wrapper)
*hyperparameter_ret = wrapper->hyperparameter;
else
*hyperparameter_ret = NULL;
return CCS_SUCCESS;
}
......@@ -237,7 +309,7 @@ ccs_configuration_space_get_hyperparameters(ccs_configuration_space_t configura
_ccs_hyperparameter_wrapper_t *wrapper = NULL;
size_t index = 0;
while ( (wrapper = (_ccs_hyperparameter_wrapper_t *)utarray_next(array, wrapper)) )
hyperparameters[index] = wrapper->hyperparameter;
hyperparameters[index++] = wrapper->hyperparameter;
for (size_t i = size; i < num_hyperparameters; i++)
hyperparameters[i] = NULL;
}
......
......@@ -3,16 +3,29 @@
#include "utarray.h"
#define HASH_NONFATAL_OOM 1
#include "uthash.h"
#include "utlist.h"
struct _ccs_distribution_wrapper_s;
typedef struct _ccs_distribution_wrapper_s _ccs_distribution_wrapper_t;
struct _ccs_hyperparameter_wrapper_s {
ccs_hyperparameter_t hyperparameter;
ccs_distribution_t distribution;
size_t index;
const char *name;
UT_hash_handle hh_name;
ccs_hyperparameter_t hyperparameter;
size_t index;
const char *name;
UT_hash_handle hh_name;
size_t distribution_index;
_ccs_distribution_wrapper_t *distribution;
};
typedef struct _ccs_hyperparameter_wrapper_s _ccs_hyperparameter_wrapper_t;
struct _ccs_distribution_wrapper_s {
ccs_distribution_t distribution;
size_t dimension;
size_t *hyperparameter_indexes;
_ccs_distribution_wrapper_t *prev;
_ccs_distribution_wrapper_t *next;
};
struct _ccs_configuration_space_data_s;
typedef struct _ccs_configuration_space_data_s _ccs_configuration_space_data_t;
......@@ -32,6 +45,7 @@ struct _ccs_configuration_space_data_s {
ccs_rng_t rng;
UT_array *hyperparameters;
_ccs_hyperparameter_wrapper_t *name_hash;
_ccs_distribution_wrapper_t *distribution_list;
};
#endif //_CONFIGURATION_SPACE_INTERNAL_H
......@@ -29,6 +29,18 @@ ccs_distribution_get_data_type(ccs_distribution_t distribution,
return CCS_SUCCESS;
}
ccs_error_t
ccs_distribution_get_dimension(ccs_distribution_t distribution,
size_t *dimension_ret) {
if (!distribution || !distribution->data)
return -CCS_INVALID_OBJECT;
if (!dimension_ret)
return -CCS_INVALID_VALUE;
*dimension_ret = 1;
return CCS_SUCCESS;
}
ccs_error_t
ccs_distribution_get_scale_type(ccs_distribution_t distribution,
ccs_scale_type_t *scale_type_ret) {
......
......@@ -11,7 +11,8 @@ RNG_TESTS = \
test_roulette_distribution \
test_numerical_hyperparameter \
test_categorical_hyperparameter \
test_ordinal_hyperparameter
test_ordinal_hyperparameter \
test_configuration_space
# unit tests
UNIT_TESTS = \
......
#include <stdlib.h>
#include <assert.h>
#include <cconfigspace.h>
#include <string.h>
ccs_hyperparameter_t create_dummy_hyperparameter(const char * name) {
ccs_hyperparameter_t hyperparameter;
ccs_error_t err;
err = ccs_create_numerical_hyperparameter(name, CCS_NUM_FLOAT,
CCSF(-5.0), CCSF(5.0),
CCSF(0.0), CCSF(1.0),
NULL, &hyperparameter);
assert( err == CCS_SUCCESS );
return hyperparameter;
}
void test_create() {
ccs_configuration_space_t configuration_space;
ccs_error_t err;
ccs_object_type_t type;
const char *name;
void * user_data;
size_t sz;
err = ccs_create_configuration_space("my_config_space", (void *)0xdeadbeef,
&configuration_space);
assert( err == CCS_SUCCESS );
err = ccs_object_get_type(configuration_space, &type);
assert( err == CCS_SUCCESS );
assert( type == CCS_CONFIGURATION_SPACE );
err = ccs_configuration_space_get_name(configuration_space, &name);
assert( err == CCS_SUCCESS );
assert( strcmp(name, "my_config_space") == 0 );
err = ccs_configuration_space_get_user_data(configuration_space, &user_data);
assert( err == CCS_SUCCESS );
assert( user_data == (void *)0xdeadbeef );
err = ccs_configuration_space_get_num_hyperparameters(configuration_space, &sz);
assert( err == CCS_SUCCESS );
assert( sz == 0 );
err = ccs_release_object(configuration_space);
assert( err == CCS_SUCCESS );
}
void check_configuration(ccs_configuration_space_t configuration_space,
size_t sz,
ccs_hyperparameter_t *hyperparameters) {
ccs_hyperparameter_t hyperparameter;
ccs_error_t err;
size_t sz_ret;
ccs_hyperparameter_t *hyperparameters_ret =
(ccs_hyperparameter_t *)malloc(sizeof(ccs_hyperparameter_t)*(sz+1));
const char *name;
err = ccs_configuration_space_get_num_hyperparameters(configuration_space,
&sz_ret);
assert( err == CCS_SUCCESS );
assert( sz_ret == sz );
for (size_t i = 0; i < sz; i++) {
err = ccs_configuration_space_get_hyperparameter(configuration_space, i,
&hyperparameter);
assert( err == CCS_SUCCESS );
assert( hyperparameter == hyperparameters[i] );
}
err = ccs_configuration_space_get_hyperparameters(configuration_space, sz + 1,
hyperparameters_ret, &sz_ret);
assert( err == CCS_SUCCESS );
assert( sz_ret == sz );
for (size_t i = 0; i < sz; i++)
assert( hyperparameters_ret[i] == hyperparameters[i] );
assert( hyperparameters_ret[sz] == NULL );
for (size_t i = 0; i < sz; i++) {
err = ccs_hyperparameter_get_name(hyperparameters[i], &name);
assert( err == CCS_SUCCESS );
err = ccs_configuration_space_get_hyperparameter_by_name(
configuration_space, name, &hyperparameter);
assert( err == CCS_SUCCESS );
assert( hyperparameter == hyperparameters[i] );
}
free(hyperparameters_ret);
}
void test_add() {
ccs_hyperparameter_t hyperparameters[3];
ccs_configuration_space_t configuration_space;
ccs_error_t err;
err = ccs_create_configuration_space("my_config_space", NULL,
&configuration_space);
assert( err == CCS_SUCCESS );
hyperparameters[0] = create_dummy_hyperparameter("param1");
hyperparameters[1] = create_dummy_hyperparameter("param2");
hyperparameters[2] = create_dummy_hyperparameter("param3");
err = ccs_configuration_space_add_hyperparameter(configuration_space,
hyperparameters[0], NULL);
assert( err == CCS_SUCCESS );
err = ccs_configuration_space_add_hyperparameter(configuration_space,
hyperparameters[0], NULL);
assert( err == -CCS_INVALID_HYPERPARAMETER );
err = ccs_configuration_space_add_hyperparameter(configuration_space,
hyperparameters[1], NULL);
assert( err == CCS_SUCCESS );
err = ccs_configuration_space_add_hyperparameter(configuration_space,
hyperparameters[2], NULL);
assert( err == CCS_SUCCESS );
check_configuration(configuration_space, 3, hyperparameters);
for (size_t i = 0; i < 3; i++) {
err = ccs_release_object(hyperparameters[i]);
assert( err == CCS_SUCCESS );
}
err = ccs_release_object(configuration_space);
assert( err == CCS_SUCCESS );
}
void test_add_list() {
ccs_hyperparameter_t hyperparameters[3];
ccs_configuration_space_t configuration_space;
ccs_error_t err;
err = ccs_create_configuration_space("my_config_space", NULL,
&configuration_space);
assert( err == CCS_SUCCESS );
hyperparameters[0] = create_dummy_hyperparameter("param1");
hyperparameters[1] = create_dummy_hyperparameter("param2");
hyperparameters[2] = create_dummy_hyperparameter("param3");
err = ccs_configuration_space_add_hyperparameters(configuration_space, 3,
hyperparameters, NULL);
assert( err == CCS_SUCCESS );
check_configuration(configuration_space, 3, hyperparameters);
for (size_t i = 0; i < 3; i++) {
err = ccs_release_object(hyperparameters[i]);
assert( err == CCS_SUCCESS );
}
err = ccs_release_object(configuration_space);
assert( err == CCS_SUCCESS );
}
int main(int argc, char *argv[]) {
ccs_init();
test_create();
test_add();
test_add_list();
return 0;
}
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