Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Brice Videau
CCS
Commits
80f82b8c
Commit
80f82b8c
authored
May 27, 2020
by
Brice Videau
Browse files
Added basic support for configurations.
parent
504dee7a
Changes
15
Hide whitespace changes
Inline
Side-by-side
include/ccs/base.h
View file @
80f82b8c
...
...
@@ -38,6 +38,7 @@ enum ccs_error_e {
CCS_INVALID_SCALE
,
CCS_INVALID_DISTRIBUTION
,
CCS_INVALID_HYPERPARAMETER
,
CCS_INVALID_NAME
,
CCS_TYPE_NOT_COMPARABLE
,
CCS_INVALID_BOUNDS
,
CCS_OUT_OF_BOUNDS
,
...
...
@@ -137,12 +138,12 @@ struct ccs_interval_s {
typedef
struct
ccs_interval_s
ccs_interval_t
;
struct
ccs_datum_
u
{
struct
ccs_datum_
s
{
ccs_value_t
value
;
ccs_data_type_t
type
;
};
typedef
struct
ccs_datum_
u
ccs_datum_t
;
typedef
struct
ccs_datum_
s
ccs_datum_t
;
extern
const
ccs_datum_t
ccs_none
;
...
...
include/ccs/configuration.h
View file @
80f82b8c
...
...
@@ -22,12 +22,17 @@ ccs_configuration_get_configuration_space(ccs_configuration_t configurati
extern
ccs_error_t
ccs_configuration_get_user_data
(
ccs_configuration_t
configuration
,
void
**
user_data
);
void
**
user_data
_ret
);
extern
ccs_error_t
ccs_configuration_get_value
(
ccs_configuration_t
configuration
,
size_t
index
,
ccs_datum_t
*
value
);
ccs_datum_t
*
value_ret
);
extern
ccs_error_t
ccs_configuration_set_value
(
ccs_configuration_t
configuration
,
size_t
index
,
ccs_datum_t
value
);
extern
ccs_error_t
ccs_configuration_get_values
(
ccs_configuration_t
configuration
,
...
...
@@ -35,6 +40,11 @@ ccs_configuration_get_values(ccs_configuration_t configuration,
ccs_datum_t
*
values
,
size_t
*
num_values_ret
);
extern
ccs_error_t
ccs_configuration_get_value_by_name
(
ccs_configuration_t
configuration
,
const
char
*
name
,
ccs_datum_t
*
value_ret
);
#ifdef __cplusplus
}
#endif
...
...
include/ccs/configuration_space.h
View file @
80f82b8c
...
...
@@ -57,6 +57,12 @@ ccs_configuration_space_get_hyperparameter_by_name(
const
char
*
name
,
ccs_hyperparameter_t
*
hyperparameter_ret
);
extern
ccs_error_t
ccs_configuration_space_get_hyperparameter_index_by_name
(
ccs_configuration_space_t
configuration_space
,
const
char
*
name
,
size_t
*
index_ret
);
extern
ccs_error_t
ccs_configuration_space_get_hyperparameters
(
ccs_configuration_space_t
configuration_space
,
size_t
num_hyperparameters
,
...
...
@@ -123,7 +129,7 @@ ccs_configuration_space_check_configuration_values(ccs_configuration_space_t co
extern
ccs_error_t
ccs_configuration_space_get_default_configuration
(
ccs_configuration_space_t
configuration_space
,
ccs_configuration_t
*
configuration
);
ccs_configuration_t
*
configuration
_ret
);
extern
ccs_error_t
ccs_configuration_space_sample_configuration
(
ccs_configuration_space_t
configuration_space
,
...
...
include/ccs/hyperparameter.h
View file @
80f82b8c
...
...
@@ -70,6 +70,17 @@ extern ccs_error_t
ccs_hyperparameter_get_default_distribution
(
ccs_hyperparameter_t
hyperparameter
,
ccs_distribution_t
*
distribution
);
extern
ccs_error_t
ccs_hyperparameter_check_value
(
ccs_hyperparameter_t
hyperparameter
,
ccs_datum_t
value
,
ccs_bool_t
*
result_ret
);
extern
ccs_error_t
ccs_hyperparameter_check_values
(
ccs_hyperparameter_t
hyperparameter
,
size_t
num_values
,
const
ccs_datum_t
*
values
,
ccs_bool_t
*
results
);
// Sampling Interface
extern
ccs_error_t
ccs_hyperparameter_sample
(
ccs_hyperparameter_t
hyperparameter
,
...
...
src/Makefile.am
View file @
80f82b8c
...
...
@@ -18,11 +18,14 @@ libcconfigspace_la_SOURCES = \
hyperparameter.c
\
hyperparameter_internal.h
\
hyperparameter_numerical.c
\
hyperparameter_categorical.c
\
uthash.h
\
datum_hash.h
\
hyperparameter_categorical.c
\
hyperparameter_ordinal.c
\
utarray.h
\
configuration_space.c
\
configuration_space_internal.h
configuration_space_internal.h
\
configuration.c
\
configuration_internal.h
@VALGRIND_CHECK_RULES@
src/configuration.c
0 → 100644
View file @
80f82b8c
#include "cconfigspace_internal.h"
#include "configuration_internal.h"
static
inline
_ccs_configuration_ops_t
*
ccs_configuration_get_ops
(
ccs_configuration_t
configuration
)
{
return
(
_ccs_configuration_ops_t
*
)
configuration
->
obj
.
ops
;
}
static
ccs_error_t
_ccs_configuration_del
(
ccs_object_t
object
)
{
ccs_configuration_t
configuration
=
(
ccs_configuration_t
)
object
;
ccs_release_object
(
configuration
->
data
->
configuration_space
);
return
CCS_SUCCESS
;
}
static
_ccs_configuration_ops_t
_configuration_ops
=
{
{
&
_ccs_configuration_del
}
};
ccs_error_t
ccs_create_configuration
(
ccs_configuration_space_t
configuration_space
,
size_t
num_values
,
ccs_datum_t
*
values
,
void
*
user_data
,
ccs_configuration_t
*
configuration_ret
)
{
if
(
!
configuration_ret
)
return
-
CCS_INVALID_VALUE
;
if
(
num_values
&&
!
values
)
return
-
CCS_INVALID_VALUE
;
if
(
!
num_values
&&
values
)
return
-
CCS_INVALID_VALUE
;
ccs_error_t
err
;
size_t
num
;
err
=
ccs_configuration_space_get_num_hyperparameters
(
configuration_space
,
&
num
);
if
(
err
)
return
err
;
if
(
values
&&
num
!=
num_values
)
return
-
CCS_INVALID_VALUE
;
uintptr_t
mem
=
(
uintptr_t
)
calloc
(
1
,
sizeof
(
struct
_ccs_configuration_s
)
+
sizeof
(
struct
_ccs_configuration_data_s
)
+
num
*
sizeof
(
ccs_datum_t
));
if
(
!
mem
)
return
CCS_ENOMEM
;
err
=
ccs_retain_object
(
configuration_space
);
if
(
err
)
{
free
((
void
*
)
mem
);
return
err
;
}
ccs_configuration_t
config
=
(
ccs_configuration_t
)
mem
;
_ccs_object_init
(
&
(
config
->
obj
),
CCS_CONFIGURATION
,
(
_ccs_object_ops_t
*
)
&
_configuration_ops
);
config
->
data
=
(
struct
_ccs_configuration_data_s
*
)(
mem
+
sizeof
(
struct
_ccs_configuration_s
));
config
->
data
->
user_data
=
user_data
;
config
->
data
->
num_values
=
num
;
config
->
data
->
configuration_space
=
configuration_space
;
config
->
data
->
values
=
(
ccs_datum_t
*
)(
mem
+
sizeof
(
struct
_ccs_configuration_s
)
+
sizeof
(
struct
_ccs_configuration_data_s
));
if
(
values
)
for
(
size_t
i
=
0
;
i
<
num
;
i
++
)
config
->
data
->
values
[
i
]
=
values
[
i
];
*
configuration_ret
=
config
;
return
CCS_SUCCESS
;
}
ccs_error_t
ccs_configuration_get_configuration_space
(
ccs_configuration_t
configuration
,
ccs_configuration_space_t
*
configuration_space_ret
)
{
if
(
!
configuration
||
!
configuration
->
data
)
return
-
CCS_INVALID_OBJECT
;
if
(
!
configuration_space_ret
)
return
-
CCS_INVALID_VALUE
;
*
configuration_space_ret
=
configuration
->
data
->
configuration_space
;
return
CCS_SUCCESS
;
}
ccs_error_t
ccs_configuration_get_user_data
(
ccs_configuration_t
configuration
,
void
**
user_data_ret
)
{
if
(
!
configuration
||
!
configuration
->
data
)
return
-
CCS_INVALID_OBJECT
;
if
(
!
user_data_ret
)
return
-
CCS_INVALID_VALUE
;
*
user_data_ret
=
configuration
->
data
->
user_data
;
return
CCS_SUCCESS
;
}
ccs_error_t
ccs_configuration_get_value
(
ccs_configuration_t
configuration
,
size_t
index
,
ccs_datum_t
*
value_ret
)
{
if
(
!
configuration
||
!
configuration
->
data
)
return
-
CCS_INVALID_OBJECT
;
if
(
!
value_ret
)
return
-
CCS_INVALID_VALUE
;
if
(
index
>=
configuration
->
data
->
num_values
)
return
-
CCS_OUT_OF_BOUNDS
;
*
value_ret
=
configuration
->
data
->
values
[
index
];
return
CCS_SUCCESS
;
}
ccs_error_t
ccs_configuration_set_value
(
ccs_configuration_t
configuration
,
size_t
index
,
ccs_datum_t
value
)
{
if
(
!
configuration
||
!
configuration
->
data
)
return
-
CCS_INVALID_OBJECT
;
if
(
index
>=
configuration
->
data
->
num_values
)
return
-
CCS_OUT_OF_BOUNDS
;
configuration
->
data
->
values
[
index
]
=
value
;
return
CCS_SUCCESS
;
}
ccs_error_t
ccs_configuration_get_values
(
ccs_configuration_t
configuration
,
size_t
num_values
,
ccs_datum_t
*
values
,
size_t
*
num_values_ret
)
{
if
(
!
configuration
||
!
configuration
->
data
)
return
-
CCS_INVALID_OBJECT
;
if
(
!
num_values_ret
&&
!
values
)
return
-
CCS_INVALID_VALUE
;
if
(
num_values
&&
!
values
)
return
-
CCS_INVALID_VALUE
;
if
(
!
num_values
&&
values
)
return
-
CCS_INVALID_VALUE
;
size_t
num
=
configuration
->
data
->
num_values
;
if
(
values
)
{
if
(
num_values
<
num
)
return
-
CCS_INVALID_VALUE
;
for
(
size_t
i
=
0
;
i
<
num
;
i
++
)
values
[
i
]
=
configuration
->
data
->
values
[
i
];
for
(
size_t
i
=
num
;
i
<
num_values
;
i
++
)
{
values
[
i
].
value
.
i
=
0
;
values
[
i
].
type
=
CCS_NONE
;
}
}
if
(
num_values_ret
)
*
num_values_ret
=
num
;
return
CCS_SUCCESS
;
}
ccs_error_t
ccs_configuration_get_value_by_name
(
ccs_configuration_t
configuration
,
const
char
*
name
,
ccs_datum_t
*
value_ret
)
{
if
(
!
configuration
||
!
configuration
->
data
)
return
-
CCS_INVALID_OBJECT
;
if
(
!
name
)
return
-
CCS_INVALID_VALUE
;
size_t
index
;
ccs_error_t
err
;
err
=
ccs_configuration_space_get_hyperparameter_index_by_name
(
configuration
->
data
->
configuration_space
,
name
,
&
index
);
if
(
err
)
return
err
;
*
value_ret
=
configuration
->
data
->
values
[
index
];
return
CCS_SUCCESS
;
}
src/configuration_internal.h
0 → 100644
View file @
80f82b8c
#ifndef _CONFIGURATION_INTERNAL_H
#define _CONFIGURATION_INTERNAL_H
struct
_ccs_configuration_ops_s
{
_ccs_object_ops_t
obj_ops
;
};
typedef
struct
_ccs_configuration_ops_s
_ccs_configuration_ops_t
;
struct
_ccs_configuration_data_s
;
typedef
struct
_ccs_configuration_data_s
_ccs_configuration_data_t
;
struct
_ccs_configuration_s
{
_ccs_object_internal_t
obj
;
_ccs_configuration_data_t
*
data
;
};
struct
_ccs_configuration_data_s
{
void
*
user_data
;
ccs_configuration_space_t
configuration_space
;
size_t
num_values
;
ccs_datum_t
*
values
;
};
#endif //_CONFIGURATION_INTERNAL_H
src/configuration_space.c
View file @
80f82b8c
...
...
@@ -261,10 +261,9 @@ 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
)
*
hyperparameter_ret
=
wrapper
->
hyperparameter
;
else
*
hyperparameter_ret
=
NULL
;
if
(
!
wrapper
)
return
-
CCS_OUT_OF_BOUNDS
;
*
hyperparameter_ret
=
wrapper
->
hyperparameter
;
return
CCS_SUCCESS
;
}
...
...
@@ -282,10 +281,29 @@ ccs_configuration_space_get_hyperparameter_by_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
;
if
(
!
wrapper
)
return
-
CCS_INVALID_NAME
;
*
hyperparameter_ret
=
wrapper
->
hyperparameter
;
return
CCS_SUCCESS
;
}
ccs_error_t
ccs_configuration_space_get_hyperparameter_index_by_name
(
ccs_configuration_space_t
configuration_space
,
const
char
*
name
,
size_t
*
index_ret
)
{
if
(
!
configuration_space
||
!
configuration_space
->
data
)
return
-
CCS_INVALID_OBJECT
;
if
(
!
index_ret
)
return
-
CCS_INVALID_VALUE
;
_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
)
return
-
CCS_INVALID_NAME
;
*
index_ret
=
wrapper
->
index
;
return
CCS_SUCCESS
;
}
...
...
@@ -306,6 +324,8 @@ ccs_configuration_space_get_hyperparameters(ccs_configuration_space_t configura
UT_array
*
array
=
configuration_space
->
data
->
hyperparameters
;
size_t
size
=
utarray_len
(
array
);
if
(
hyperparameters
)
{
if
(
num_hyperparameters
<
size
)
return
-
CCS_INVALID_VALUE
;
_ccs_hyperparameter_wrapper_t
*
wrapper
=
NULL
;
size_t
index
=
0
;
while
(
(
wrapper
=
(
_ccs_hyperparameter_wrapper_t
*
)
utarray_next
(
array
,
wrapper
))
)
...
...
@@ -318,3 +338,35 @@ ccs_configuration_space_get_hyperparameters(ccs_configuration_space_t configura
return
CCS_SUCCESS
;
}
ccs_error_t
ccs_configuration_space_get_default_configuration
(
ccs_configuration_space_t
configuration_space
,
ccs_configuration_t
*
configuration_ret
)
{
if
(
!
configuration_space
||
!
configuration_space
->
data
)
return
-
CCS_INVALID_OBJECT
;
if
(
!
configuration_ret
)
return
-
CCS_INVALID_VALUE
;
ccs_error_t
err
;
ccs_configuration_t
config
;
err
=
ccs_create_configuration
(
configuration_space
,
0
,
NULL
,
NULL
,
&
config
);
if
(
err
)
return
err
;
UT_array
*
array
=
configuration_space
->
data
->
hyperparameters
;
size_t
index
=
0
;
_ccs_hyperparameter_wrapper_t
*
wrapper
=
NULL
;
ccs_datum_t
d
;
while
(
(
wrapper
=
(
_ccs_hyperparameter_wrapper_t
*
)
utarray_next
(
array
,
wrapper
))
)
{
err
=
ccs_hyperparameter_get_default_value
(
wrapper
->
hyperparameter
,
&
d
);
if
(
unlikely
(
err
))
goto
error
;
err
=
ccs_configuration_set_value
(
config
,
index
++
,
d
);
if
(
unlikely
(
err
))
goto
error
;
}
*
configuration_ret
=
config
;
return
CCS_SUCCESS
;
error:
ccs_release_object
(
config
);
return
err
;
}
src/datum_hash.h
0 → 100644
View file @
80f82b8c
#ifndef _DATUMHASH_H
#define _DATUMHASH_H
#define HASH_NONFATAL_OOM 1
#define HASH_FUNCTION(s,len,hashv) (hashv) = _hash_datum((ccs_datum_t *)(s))
#define HASH_KEYCMP(a,b,len) (_datum_cmp((ccs_datum_t *)a, (ccs_datum_t *)b))
#include "uthash.h"
/* BEWARE: ccs_float_t are used as hash keys. In order to recall sucessfully,
* The *SAME* float must be used.
* Alternative is o(n) access for floating point values as they would all go
* in the same bucket. May be the wisest... Switch to find in the possiblie_values list?
* #define MAXULPDIFF 7 // To define
* // Could be doing type puning...
* static inline int _cmp_float(ccs_float_t a, ccs_float_t b) {
* int64_t t1, t2, cmp;
* memcpy(&t1, &a, sizeof(int64));
* memcpy(&t2, &b, sizeof(int64));
* if (a == b)
* return 0;
* if ((t1 < 0) != (t2 < 0)) {
* if (t1 < 0)
* return -1;
* if (t2 < 0)
* return 1;
* }
* cmp = labs(t1-t2);
* if (cmp <= MAXULPDIFF)
* return 0;
* else if (a < b)
* return -1;
* else
* return 1;
* }
*/
static
inline
int
_datum_cmp
(
ccs_datum_t
*
a
,
ccs_datum_t
*
b
)
{
if
(
a
->
type
<
b
->
type
)
{
return
-
1
;
}
else
if
(
a
->
type
>
b
->
type
)
{
return
1
;
}
else
{
switch
(
a
->
type
)
{
case
CCS_STRING
:
if
(
a
->
value
.
s
==
b
->
value
.
s
)
return
0
;
else
if
(
!
a
->
value
.
s
)
return
-
1
;
else
if
(
!
b
->
value
.
s
)
return
1
;
else
return
strcmp
(
a
->
value
.
s
,
b
->
value
.
s
);
case
CCS_NONE
:
return
0
;
break
;
default:
return
memcmp
(
&
(
a
->
value
),
&
(
b
->
value
),
sizeof
(
ccs_value_t
));
}
}
}
static
inline
unsigned
_hash_datum
(
ccs_datum_t
*
d
)
{
unsigned
h
;
switch
(
d
->
type
)
{
case
CCS_STRING
:
if
(
d
->
value
.
s
)
HASH_JEN
(
d
->
value
.
s
,
strlen
(
d
->
value
.
s
),
h
);
else
HASH_JEN
(
d
,
sizeof
(
ccs_datum_t
),
h
);
break
;
case
CCS_NONE
:
HASH_JEN
(
&
(
d
->
type
),
sizeof
(
d
->
type
),
h
);
break
;
default:
HASH_JEN
(
d
,
sizeof
(
ccs_datum_t
),
h
);
}
return
h
;
}
struct
_ccs_hash_datum_s
{
ccs_datum_t
d
;
UT_hash_handle
hh
;
};
typedef
struct
_ccs_hash_datum_s
_ccs_hash_datum_t
;
#endif //_DATUMHASH_H
src/hyperparameter.c
View file @
80f82b8c
...
...
@@ -62,6 +62,31 @@ ccs_hyperparameter_get_default_distribution(ccs_hyperparameter_t hyperparameter
return
ops
->
get_default_distribution
(
hyperparameter
->
data
,
distribution
);
}
ccs_error_t
ccs_hyperparameter_check_value
(
ccs_hyperparameter_t
hyperparameter
,
ccs_datum_t
value
,
ccs_bool_t
*
result_ret
)
{
if
(
!
hyperparameter
||
!
hyperparameter
->
data
)
return
-
CCS_INVALID_OBJECT
;
if
(
!
result_ret
)
return
-
CCS_INVALID_VALUE
;
_ccs_hyperparameter_ops_t
*
ops
=
ccs_hyperparameter_get_ops
(
hyperparameter
);
return
ops
->
check_values
(
hyperparameter
->
data
,
1
,
&
value
,
result_ret
);
}
ccs_error_t
ccs_hyperparameter_check_values
(
ccs_hyperparameter_t
hyperparameter
,
size_t
num_values
,
const
ccs_datum_t
*
values
,
ccs_bool_t
*
results
)
{
if
(
!
hyperparameter
||
!
hyperparameter
->
data
)
return
-
CCS_INVALID_OBJECT
;
if
(
num_values
&&
(
!
values
||
!
results
))
return
-
CCS_INVALID_VALUE
;
_ccs_hyperparameter_ops_t
*
ops
=
ccs_hyperparameter_get_ops
(
hyperparameter
);
return
ops
->
check_values
(
hyperparameter
->
data
,
num_values
,
values
,
results
);
}
ccs_error_t
ccs_hyperparameter_sample
(
ccs_hyperparameter_t
hyperparameter
,
ccs_distribution_t
distribution
,
...
...
src/hyperparameter_categorical.c
View file @
80f82b8c
#include "cconfigspace_internal.h"
#include "hyperparameter_internal.h"
#include "datum_hash.h"
#include <string.h>
struct
_ccs_hyperparameter_categorical_data_s
{
_ccs_hyperparameter_common_data_t
common_data
;
ccs_int_t
num_possible_values
;
ccs_datum_t
*
possible_values
;
_ccs_hash_datum_t
*
possible_values
;
_ccs_hash_datum_t
*
hash
;
};
typedef
struct
_ccs_hyperparameter_categorical_data_s
_ccs_hyperparameter_categorical_data_t
;
static
ccs_error_t
_ccs_hyperparameter_categorical_del
(
ccs_object_t
o
)
{
(
void
)
o
;
ccs_hyperparameter_t
d
=
(
ccs_hyperparameter_t
)
o
;
_ccs_hyperparameter_categorical_data_t
*
data
=
(
_ccs_hyperparameter_categorical_data_t
*
)(
d
->
data
);
HASH_CLEAR
(
hh
,
data
->
hash
);
return
CCS_SUCCESS
;
}
static
ccs_error_t
_ccs_hyperparameter_categorical_check_values
(
_ccs_hyperparameter_data_t
*
data
,
size_t
num_values
,
const
ccs_datum_t
*
values
,
ccs_bool_t
*
results
)
{
_ccs_hyperparameter_categorical_data_t
*
d
=
(
_ccs_hyperparameter_categorical_data_t
*
)
data
;
for
(
size_t
i
=
0
;
i
<
num_values
;
i
++
)
{
_ccs_hash_datum_t
*
p
;
HASH_FIND
(
hh
,
d
->
hash
,
values
+
i
,
sizeof
(
ccs_datum_t
),
p
);
results
[
i
]
=
p
?
CCS_TRUE
:
CCS_FALSE
;
}
return
CCS_SUCCESS
;
}
...
...
@@ -24,36 +43,37 @@ _ccs_hyperparameter_categorical_samples(_ccs_hyperparameter_data_t *data,
_ccs_hyperparameter_categorical_data_t
*
d
=
(
_ccs_hyperparameter_categorical_data_t
*
)
data
;
ccs_error_t
err
;
ccs_
numeric
_t
*
vs
=
(
ccs_
numeric
_t
*
)
values
+
num_values
;
ccs_
int
_t
*
vs
=
(
ccs_
int
_t
*
)
values
+
num_values
;
ccs_bool_t
oversampling
;
err
=
ccs_distribution_check_oversampling
(
distribution
,
&
(
d
->
common_data
.
interval
),
&
oversampling
);
if
(
err
)
return
err
;
err
=
ccs_distribution_samples
(
distribution
,
rng
,
num_values
,
vs
);
err
=
ccs_distribution_samples
(
distribution
,
rng
,
num_values
,
(
ccs_numeric_t
*
)
vs
);
if
(
err
)
return
err
;
if
(
!
oversampling
)
{
for
(
size_t
i
=
0
;
i
<
num_values
;
i
++
)
values
[
i
]
=
d
->
possible_values
[
vs
[
i
]
.
i
]
;
values
[
i
]
=
d
->
possible_values
[
vs
[
i
]
].
d
;
}
else
{
size_t
found
=
0
;
for
(
size_t
i
=
0
;
i
<
num_values
;
i
++
)
if
(
vs
[
i
]
.
i
>=
0
&&
vs
[
i
]
.
i
<
d
->
num_possible_values
)
values
[
found
++
]
=
d
->
possible_values
[
vs
[
i
]
.
i
]
;
if
(
vs
[
i
]
>=
0
&&
vs
[
i
]
<
d
->
num_possible_values
)
values
[
found
++
]
=
d
->
possible_values
[
vs
[
i
]
].
d
;
vs
=
NULL
;
size_t
coeff
=
2
;
while
(
found
<
num_values
)
{
size_t
buff_sz
=
(
num_values
-
found
)
*
coeff
;
vs
=
(
ccs_
numeric
_t
*
)
malloc
(
sizeof
(
ccs_
numeric
_t
)
*
buff_sz
);
vs
=
(
ccs_
int
_t
*
)
malloc
(
sizeof
(
ccs_
int
_t
)
*
buff_sz
);
if
(
!
vs
)
return
-
CCS_ENOMEM
;
err
=
ccs_distribution_samples
(
distribution
,
rng
,
buff_sz
,
vs
);
buff_sz
,
(
ccs_numeric_t
*
)
vs
);
for
(
size_t
i
=
0
;
i
<
buff_sz
&&
found
<
num_values
;
i
++
)
if
(
vs
[
i
]
.
i
>=
0
&&
vs
[
i
]
.
i
<
d
->
num_possible_values
)
values
[
found
++
]
=
d
->
possible_values
[
vs
[
i
]
.
i
]
;
if
(
vs
[
i
]
>=
0
&&
vs
[
i
]
<
d
->
num_possible_values
)
values
[
found
++
]
=
d
->
possible_values
[
vs
[
i
]
].
d
;
coeff
<<=
1
;
free
(
vs
);
if
(
coeff
>
32
)
...
...
@@ -77,10 +97,18 @@ _ccs_hyperparameter_categorical_get_default_distribution(
static
_ccs_hyperparameter_ops_t
_ccs_hyperparameter_categorical_ops
=
{
{
&
_ccs_hyperparameter_categorical_del
},
&
_ccs_hyperparameter_categorical_check_values
,
&
_ccs_hyperparameter_categorical_samples
,
&
_ccs_hyperparameter_categorical_get_default_distribution
};
#undef uthash_nonfatal_oom
#define uthash_nonfatal_oom(elt) { \
HASH_CLEAR(hh, hyperparam_data->hash); \
free((void*)mem); \
return -CCS_ENOMEM; \
}
ccs_error_t
ccs_create_categorical_hyperparameter
(
const
char
*
name
,
size_t
num_possible_values
,
...
...
@@ -96,11 +124,20 @@ ccs_create_categorical_hyperparameter(const char *name,
return
-
CCS_INVALID_VALUE
;
if
(
!
possible_values
)