Commit 5d5e097b authored by Brice Videau's avatar Brice Videau

More bindings.

parent bf594744
...@@ -6,3 +6,7 @@ require_relative 'cconfigspace/rng' ...@@ -6,3 +6,7 @@ require_relative 'cconfigspace/rng'
require_relative 'cconfigspace/distribution' require_relative 'cconfigspace/distribution'
require_relative 'cconfigspace/hyperparameter' require_relative 'cconfigspace/hyperparameter'
require_relative 'cconfigspace/expression' require_relative 'cconfigspace/expression'
require_relative 'cconfigspace/context'
require_relative 'cconfigspace/configuration_space'
require_relative 'cconfigspace/configuration'
require_relative 'cconfigspace/objective_space'
...@@ -192,6 +192,13 @@ module CCS ...@@ -192,6 +192,13 @@ module CCS
class InactiveClass class InactiveClass
include Singleton include Singleton
def to_s
"inactive"
end
def inspect
"inactive"
end
end end
Inactive = InactiveClass.instance Inactive = InactiveClass.instance
...@@ -221,7 +228,7 @@ module CCS ...@@ -221,7 +228,7 @@ module CCS
when :CCS_FLOAT when :CCS_FLOAT
self[:value][:f] self[:value][:f]
when :CCS_BOOLEAN when :CCS_BOOLEAN
self[:value][:i] == :CCS_FALSE ? false : true self[:value][:i] == CCS::FALSE ? false : true
when :CCS_STRING when :CCS_STRING
self[:value][:s].read_string self[:value][:s].read_string
when :CCS_INACTIVE when :CCS_INACTIVE
......
module CCS
attach_function :ccs_create_configuration, [:ccs_configuration_space_t, :size_t, :pointer, :pointer, :pointer], :ccs_result_t
attach_function :ccs_configuration_get_configuration_space, [:ccs_configuration_t, :pointer], :ccs_result_t
attach_function :ccs_configuration_get_user_data, [:ccs_configuration_t, :pointer], :ccs_result_t
attach_function :ccs_configuration_get_value, [:ccs_configuration_t, :size_t, :pointer], :ccs_result_t
attach_function :ccs_configuration_set_value, [:ccs_configuration_t, :size_t, :ccs_datum_t], :ccs_result_t
attach_function :ccs_configuration_get_values, [:ccs_configuration_t, :size_t, :pointer, :pointer], :ccs_result_t
attach_function :ccs_configuration_get_value_by_name, [:ccs_configuration_t, :string, :pointer], :ccs_result_t
attach_function :ccs_configuration_check, [:ccs_configuration_t], :ccs_result_t
attach_function :ccs_configuration_hash, [:ccs_configuration_t, :pointer], :ccs_result_t
attach_function :ccs_configuration_cmp, [:ccs_configuration_t, :ccs_configuration_t, :pointer], :ccs_result_t
class Configuration < Object
include Comparable
add_property :user_data, :pointer, :ccs_configuration_get_user_data, memoize: true
add_property :hash, :ccs_hash_t, :ccs_configuration_hash, memoize: false
def initialize(handle = nil, retain: false, configuration_space: nil, values: nil, user_data: nil)
if (handle)
super(handle, retain: retain)
else
if values
count = values.size
raise StandardError, :CCS_INVALID_VALUE if count == 0
p_values = MemoryPointer::new(:ccs_datum_t, count)
values.each_with_index { |v, i| Datum::new(p_values[i]).value = v }
values = p_values
end
ptr = MemoryPointer::new(:ccs_configuration_t)
res = CCS.ccs_create_configuration(configuration_space, count, values, user_data, ptr)
CCS.error_check(res)
super(ptr.read_ccs_configuration_t, retain: false)
end
end
def self.from_handle(handle)
self::new(handle, retain: true)
end
def configuration_space
@configuration_space ||= begin
ptr = MemoryPointer::new(:ccs_configuration_space_t)
res = CCS.ccs_configuration_get_configuration_space(@handle, ptr)
CCS.error_check(res)
ConfigurationSpace.from_handle(ptr.read_ccs_configuration_space_t)
end
end
def value(hyperparameter)
ptr = MemoryPointer::new(:ccs_datum_t)
case hyperparameter
when String
res = CCS.ccs_configuration_get_value_by_name(@handle, hyperparameter, ptr)
when Hyperparameter
res = CCS.ccs_configuration_get_value(@handle, configuration_space.hyperparameter_index(hyperparameter), ptr)
when Integer
res = CCS.ccs_configuration_get_value(@handle, hyperparameter, ptr)
else
raise StandardError, :CCS_INVALID_VALUE
end
CCS.error_check(res)
Datum::new(ptr).value
end
def num_values
@num_values ||= begin
ptr = MemoryPointer::new(:size_t)
res = CCS.ccs_configuration_get_values(@handle, 0, nil, ptr)
CCS.error_check(res)
ptr.read_size_t
end
end
def values
count = num_values
return [] if count == 0
values = MemoryPointer::new(:ccs_datum_t, count)
res = CCS.ccs_configuration_get_values(@handle, count, values, nil)
CCS.error_check(res)
count.times.collect { |i| Datum::new(values[i]).value }
end
def check
res = CCS.ccs_configuration_check(@handle)
CCS.error_check(res)
self
end
def <=>(other)
ptr = MemoryPointer::new(:int)
res = CCS.ccs_configuration_cmp(@handle, other, ptr)
CCS.error_check(res)
return ptr.read_int
end
def to_h
configuration_space.hyperparameters.collect(&:name).zip(values).to_h
end
end
end
This diff is collapsed.
module CCS
attach_function :ccs_context_get_hyperparameter_index, [:ccs_context_t, :ccs_hyperparameter_t, :pointer], :ccs_result_t
class Context < Object
def hyperparameter_index(hyperparameter)
ptr = MemoryPointer::new(:size_t)
res = CCS.ccs_context_get_hyperparameter_index(@handle, hyperparameter, ptr)
CCS.error_check(res)
ptr.read_size_t
end
end
end
...@@ -143,7 +143,7 @@ module CCS ...@@ -143,7 +143,7 @@ module CCS
def check_context(context) def check_context(context)
res = CCS.ccs_expression_check_context(@handle, context) res = CCS.ccs_expression_check_context(@handle, context)
CCS.error_check(res) CCS.error_check(res)
true self
end end
def to_s def to_s
...@@ -186,7 +186,12 @@ module CCS ...@@ -186,7 +186,12 @@ module CCS
end end
def to_s def to_s
value.to_s case value
when String
value.inspect
else
value.to_s
end
end end
end end
...@@ -223,7 +228,7 @@ module CCS ...@@ -223,7 +228,7 @@ module CCS
end end
end end
def eval(index, contex: nil, values: nil) def eval(index, context: nil, values: nil)
if values && context if values && context
count = context.num_hyperparameters count = context.num_hyperparameters
raise StandardError, :CCS_INVALID_VALUES if values.size != count raise StandardError, :CCS_INVALID_VALUES if values.size != count
......
...@@ -97,7 +97,7 @@ module CCS ...@@ -97,7 +97,7 @@ module CCS
count = vals.size count = vals.size
return [] if count == 0 return [] if count == 0
values = MemoryPointer::new(:ccs_datum_t, count) values = MemoryPointer::new(:ccs_datum_t, count)
vals.each_with_index{ |v, i| Datum::new(values[i]).value = v } vals.each_with_index { |v, i| Datum::new(values[i]).value = v }
ptr = MemoryPointer::new(:ccs_bool_t, count) ptr = MemoryPointer::new(:ccs_bool_t, count)
res = CCS.ccs_hyperparameter_check_values(@handle, count, values, ptr) res = CCS.ccs_hyperparameter_check_values(@handle, count, values, ptr)
CCS.error_check(res) CCS.error_check(res)
...@@ -118,6 +118,10 @@ module CCS ...@@ -118,6 +118,10 @@ module CCS
CCS.error_check(res) CCS.error_check(res)
count.times.collect { |i| Datum::new(values[i]).value } count.times.collect { |i| Datum::new(values[i]).value }
end end
def ==(other)
self.class == other.class && @handle == other.handle
end
end end
attach_function :ccs_create_numerical_hyperparameter, [:string, :ccs_numeric_type_t, :ccs_numeric_t, :ccs_numeric_t, :ccs_numeric_t, :ccs_numeric_t, :pointer, :pointer], :ccs_result_t attach_function :ccs_create_numerical_hyperparameter, [:string, :ccs_numeric_type_t, :ccs_numeric_t, :ccs_numeric_t, :ccs_numeric_t, :ccs_numeric_t, :pointer, :pointer], :ccs_result_t
......
module CCS
ObjectiveType = enum FFI::Type::INT32, :ccs_objective_type_t, [
:CCS_MINIMIZE,
:CCS_MAXIMIZE
]
class MemoryPointer
def read_ccs_objective_type_t
ObjectiveType.from_native(read_int32, nil)
end
def write_ccs_objective_type_t(v)
write_int32 ObjectiveType.to_native(v, nil)
end
def write_array_of_ccs_objective_type_t(ary)
write_array_of_int32( ary.collect { |v| ObjectiveType.to_native(v, nil) } )
end
def read_array_of_ccs_objective_type_t(count)
read_array_of_int32(count).collect { |v| ObjectiveType.from_native(v, nil) }
end
end
attach_function :ccs_create_objective_space, [:string, :pointer, :pointer], :ccs_result_t
attach_function :ccs_objective_space_get_name, [:ccs_objective_space_t, :pointer], :ccs_result_t
attach_function :ccs_objective_space_get_user_data, [:ccs_objective_space_t, :pointer], :ccs_result_t
attach_function :ccs_objective_space_add_hyperparameter, [:ccs_objective_space_t, :ccs_hyperparameter_t], :ccs_result_t
attach_function :ccs_objective_space_add_hyperparameters, [:ccs_objective_space_t, :size_t, :pointer], :ccs_result_t
attach_function :ccs_objective_space_get_num_hyperparameters, [:ccs_objective_space_t, :pointer], :ccs_result_t
attach_function :ccs_objective_space_get_hyperparameter, [:ccs_objective_space_t, :size_t, :pointer], :ccs_result_t
attach_function :ccs_objective_space_get_hyperparameter_by_name, [:ccs_objective_space_t, :string, :pointer], :ccs_result_t
attach_function :ccs_objective_space_get_hyperparameter_index_by_name, [:ccs_objective_space_t, :string, :pointer], :ccs_result_t
attach_function :ccs_objective_space_get_hyperparameter_index, [:ccs_objective_space_t, :ccs_hyperparameter_t, :pointer], :ccs_result_t
attach_function :ccs_objective_space_get_hyperparameters, [:ccs_objective_space_t, :size_t, :pointer, :pointer], :size_t
attach_function :ccs_objective_space_add_objective, [:ccs_objective_space_t, :ccs_expression_t, :ccs_objective_type_t], :ccs_result_t
attach_function :ccs_objective_space_add_objectives, [:ccs_objective_space_t, :size_t, :pointer, :pointer], :ccs_result_t
attach_function :ccs_objective_space_get_objective, [:ccs_objective_space_t, :size_t, :pointer, :pointer], :ccs_result_t
attach_function :ccs_objective_space_get_objectives, [:ccs_objective_space_t, :size_t, :pointer, :pointer, :pointer], :ccs_result_t
class ObjectiveSpace < Object
add_property :user_data, :pointer, :ccs_objective_space_get_user_data, memoize: true
add_property :num_hyperparameters, :size_t, :ccs_objective_space_get_num_hyperparameters, memoize: false
def initialize(handle = nil, retain: false, name: "", user_data: nil)
if handle
super(handle, retain: retain)
else
ptr = MemoryPointer::new(:ccs_objective_space_t)
res = CCS.ccs_create_objective_space(name, user_data, ptr)
CCS.error_check(res)
super(ptr.read_ccs_objective_space_t, retain: false)
end
end
def self.from_handle(handle)
self::new(handle, retain: true)
end
def name
@name ||= begin
ptr = MemoryPointer::new(:pointer)
res = CCS.ccs_objective_space_get_name(@handle, ptr)
CCS.error_check(res)
ptr.read_pointer.read_string
end
end
def add_hyperparameter(hyperparameter)
res = CCS.ccs_objective_space_add_hyperparameter(@handle, hyperparameter)
CCS.error_check(res)
self
end
def add_hyperparameters(hyperparameters)
count = hyperparameters.size
return self if count == 0
p_hypers = MemoryPointer::new(:ccs_hyperparameter_t, count)
p_hypers.write_array_of_pointer(hyperparameters.collect(&:handle))
res = CCS.ccs_objective_space_add_hyperparameters(@handle, count, p_hypers)
CCS.error_check(res)
self
end
def hyperparameter(index)
ptr = MemoryPointer::new(:ccs_hyperparameter_t)
res = CCS.ccs_objective_space_get_hyperparameter(@handle, index, ptr)
CCS.error_check(res)
Hyperparameter.from_handle(ptr.read_ccs_hyperparameter_t)
end
def hyperparameter_by_name(name)
ptr = MemoryPointer::new(:ccs_hyperparameter_t)
res = CCS.ccs_objective_space_get_hyperparameter_by_name(@handle, name, ptr)
CCS.error_check(res)
Hyperparameter.from_handle(ptr.read_ccs_hyperparameter_t)
end
def hyperparameter_index(hyperparameter)
ptr = MemoryPointer::new(:size_t)
res = CCS.ccs_objective_space_get_hyperparameter_index(@handle, hyperparameter, ptr)
CCS.error_check(res)
ptr.read_size_t
end
def hyperparameters
count = num_hyperparameters
return [] if count == 0
ptr = MemoryPointer::new(:ccs_hyperparameter_t, count)
res = CCS.ccs_objective_space_get_hyperparameters(@handle, count, ptr, nil)
CCS.error_check(res)
count.times.collect { |i| Hyperparameter.from_handle(ptr[i].read_pointer) }
end
def add_objective(expression, type: :CCS_MINIMIZE)
res = CCS.ccs_objective_space_add_objective(@handle, expression, type)
CCS.error_check(res)
self
end
def add_objectives(expressions, types: nil)
count = expressions.length
return self if count == 0
if types
raise StandardError, :CCS_INVALID_VALUE if types.size != count
else
types = [:CCS_MINIMIZE] * count
end
p_types = MemoryPointer::new(:ccs_objective_type_t, count)
p_types.write_array_of_ccs_objective_type_t(types)
p_exprs = MemoryPointer::new(:ccs_expression_t, count)
p_exprs.write_array_of_pointer(expressions.collect(&:handle))
res = CCS.ccs_objective_space_add_objectives(@handle, count, p_exprs, p_types)
CCS.error_check(res)
self
end
def get_objective(index)
p_type = MemoryPointer::new(:ccs_objective_type_t)
p_expr = MemoryPointer::new(:ccs_expression_t)
res = CCS.ccs_objective_space_get_objective(@handle, index, p_expr, p_type)
CCS.error_check(res)
return [Expression::from_handle(p_expr.read_ccs_expression_t), p_type.read_ccs_objective_type_t]
end
def num_objectives
ptr = MemoryPointer::new(:size_t)
res = CCS.ccs_objective_space_get_objectives(@handle, 0, nil, nil, ptr)
CCS.error_check(res)
ptr.read_size_t
end
def objectives
count = num_objectives
return [] if count == 0
p_exprs = MemoryPointer::new(:ccs_expression_t, count)
p_types = MemoryPointer::new(:ccs_objective_type_t, count)
res = CCS.ccs_objective_space_get_objectives(@handle, count, p_exprs, p_types, nil)
CCS.error_check(res)
exprs = p_exprs.read_array_of_pointer(count).collect { |p| Expression.from_handle(p) }
types = p_types.read_array_of_ccs_objective_type_t(count)
exprs.zip types
end
end
end
...@@ -18,6 +18,12 @@ class CConfigSpaceTest < Minitest::Test ...@@ -18,6 +18,12 @@ class CConfigSpaceTest < Minitest::Test
assert_nil( d.value ) assert_nil( d.value )
d[:type] = :CCS_INACTIVE d[:type] = :CCS_INACTIVE
assert_equal( CCS::Inactive, d.value ) assert_equal( CCS::Inactive, d.value )
d[:type] = :CCS_BOOLEAN
d[:value][:i] = CCS::FALSE
assert_equal( false, d.value )
d[:type] = :CCS_BOOLEAN
d[:value][:i] = CCS::TRUE
assert_equal( true, d.value )
d[:type] = :CCS_FLOAT d[:type] = :CCS_FLOAT
d[:value][:f] = 15.0 d[:value][:f] = 15.0
assert_equal( 15.0, d.value ) assert_equal( 15.0, d.value )
......
[ '../lib', 'lib' ].each { |d| $:.unshift(d) if File::directory?(d) }
require 'minitest/autorun'
require 'cconfigspace'
class CConfigSpaceTestConfigurationSpace < Minitest::Test
def setup
CCS.init
end
def test_create
cs = CCS::ConfigurationSpace::new(name: "space")
assert_equal( :CCS_CONFIGURATION_SPACE, cs.object_type )
assert_equal( "space", cs.name )
assert( cs.rng.kind_of?(CCS::Rng) )
assert_equal( 0, cs.num_hyperparameters )
assert_equal( [], cs.conditions )
assert_equal( [], cs.forbidden_clauses )
h1 = CCS::NumericalHyperparameter::new
h2 = CCS::NumericalHyperparameter::new
h3 = CCS::NumericalHyperparameter::new
cs.add_hyperparameter(h1)
cs.add_hyperparameters([h2, h3])
assert_equal( 3, cs.num_hyperparameters )
assert_equal( h1, cs.hyperparameter(0) )
assert_equal( h2, cs.hyperparameter(1) )
assert_equal( h3, cs.hyperparameter(2) )
assert_equal( [h1, h2, h3], cs.hyperparameters )
assert_equal( h2, cs.hyperparameter_by_name(h2.name) )
cs.check(cs.default_configuration)
cs.check(cs.sample)
cs.check_values(cs.sample.values)
cs.samples(100).each { |c|
cs.check(cs.sample)
}
end
def test_conditions
h1 = CCS::NumericalHyperparameter::new(lower: -1.0, upper: 1.0, default: 0.0)
h2 = CCS::NumericalHyperparameter::new(lower: -1.0, upper: 1.0)
h3 = CCS::NumericalHyperparameter::new(lower: -1.0, upper: 1.0)
cs = CCS::ConfigurationSpace::new(name: "space")
cs.add_hyperparameters([h1, h2, h3])
e1 = CCS::Expression::new(type: :CCS_LESS, nodes: [h2, 0.0])
cs.set_condition(h3, e1)
e2 = CCS::Expression::new(type: :CCS_LESS, nodes: [h3, 0.0])
cs.set_condition(h1, e2)
e3 = CCS::Expression::new(type: :CCS_LESS, nodes: [h1, 0.0])
cs.add_forbidden_clause(e3)
conditions = cs.conditions
assert_equal( 3, conditions.length )
assert_equal( e2.handle, conditions[0].handle )
assert_nil( conditions[1] )
assert_equal( e1.handle, conditions[2].handle )
forbidden_clauses = cs.forbidden_clauses
assert_equal( 1, forbidden_clauses.length )
assert_equal( e3.handle, forbidden_clauses[0].handle )
end
end
...@@ -42,4 +42,27 @@ class CConfigSpaceTestExpression < Minitest::Test ...@@ -42,4 +42,27 @@ class CConfigSpaceTestExpression < Minitest::Test
e = CCS::Variable::new(hyperparameter: h) e = CCS::Variable::new(hyperparameter: h)
assert_equal( h.name , e.to_s ) assert_equal( h.name , e.to_s )
end end
def test_list
e = CCS::List::new(values: ["foo", 1, 2.0])
assert_equal( "[ \"foo\", 1, 2.0 ]", e.to_s )
assert_equal( "foo", e.eval(0) )
assert_equal( 1, e.eval(1) )
assert_equal( 2.0, e.eval(2) )
h = CCS::NumericalHyperparameter::new(name: "test")
e2 = CCS::Expression::new(type: :CCS_IN, nodes: [h, e])
assert_equal( "test # [ \"foo\", 1, 2.0 ]", e2.to_s )
end
def test_unary
e = CCS::Expression::unary(type: :CCS_NOT, node: true)
assert_equal( "!true", e.to_s )
assert_equal( false, e.eval )
end
def test_binary
e = CCS::Expression::binary(type: :CCS_OR, left: true, right: false)
assert_equal( "true || false", e.to_s)
assert_equal( true, e.eval )
end
end end
[ '../lib', 'lib' ].each { |d| $:.unshift(d) if File::directory?(d) }
require 'minitest/autorun'
require 'cconfigspace'
class CConfigSpaceTestObjectiveSpace < Minitest::Test
def setup
CCS.init
end
def test_create
os = CCS::ObjectiveSpace::new(name: "space")
assert_equal( :CCS_OBJECTIVE_SPACE, os.object_type )
assert_equal( "space", os.name )
assert_equal( 0, os.num_hyperparameters )
assert_equal( [], os.objectives )
h1 = CCS::NumericalHyperparameter::new
h2 = CCS::NumericalHyperparameter::new
h3 = CCS::NumericalHyperparameter::new
os.add_hyperparameter(h1)
os.add_hyperparameters([h2, h3])
assert_equal( 3, os.num_hyperparameters )
assert_equal( h1, os.hyperparameter(0) )
assert_equal( h2, os.hyperparameter(1) )
assert_equal( h3, os.hyperparameter(2) )
assert_equal( [h1, h2, h3], os.hyperparameters )
assert_equal( h2, os.hyperparameter_by_name(h2.name) )
e1 = CCS::Expression::new(type: :CCS_ADD, nodes: [h1, h2])
e2 = CCS::Variable::new(hyperparameter: h3)
os.add_objective(e1)
assert_equal( 1, os.objectives.size )
os.add_objectives([e2], types: [:CCS_MAXIMIZE])
assert_equal( 2, os.objectives.size )
objs = os.objectives
assert_equal( e1.handle, objs[0][0].handle )
assert_equal( :CCS_MINIMIZE, objs[0][1] )
assert_equal( e2.handle, objs[1][0].handle )
assert_equal( :CCS_MAXIMIZE, objs[1][1] )
end
end
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