Skip to content

Commit

Permalink
Forbidden clauses are now given at configuration space creation.
Browse files Browse the repository at this point in the history
  • Loading branch information
Kerilk committed Nov 3, 2023
1 parent e1c738c commit 5058a45
Show file tree
Hide file tree
Showing 26 changed files with 648 additions and 1,045 deletions.
44 changes: 22 additions & 22 deletions bindings/python/cconfigspace/configuration_space.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,12 @@
from .rng import Rng
from parglare.parser import Context as PContext

ccs_create_configuration_space = _ccs_get_function("ccs_create_configuration_space", [ct.c_char_p, ct.c_size_t, ct.POINTER(ccs_parameter), ct.POINTER(ccs_configuration_space)])
ccs_create_configuration_space = _ccs_get_function("ccs_create_configuration_space", [ct.c_char_p, ct.c_size_t, ct.POINTER(ccs_parameter), ct.c_size_t, ct.POINTER(ccs_expression), ct.POINTER(ccs_configuration_space)])
ccs_configuration_space_set_rng = _ccs_get_function("ccs_configuration_space_set_rng", [ccs_configuration_space, ccs_rng])
ccs_configuration_space_get_rng = _ccs_get_function("ccs_configuration_space_get_rng", [ccs_configuration_space, ct.POINTER(ccs_rng)])
ccs_configuration_space_set_condition = _ccs_get_function("ccs_configuration_space_set_condition", [ccs_configuration_space, ct.c_size_t, ccs_expression])
ccs_configuration_space_get_condition = _ccs_get_function("ccs_configuration_space_get_condition", [ccs_configuration_space, ct.c_size_t, ct.POINTER(ccs_expression)])
ccs_configuration_space_get_conditions = _ccs_get_function("ccs_configuration_space_get_conditions", [ccs_configuration_space, ct.c_size_t, ct.POINTER(ccs_expression), ct.POINTER(ct.c_size_t)])
ccs_configuration_space_add_forbidden_clause = _ccs_get_function("ccs_configuration_space_add_forbidden_clause", [ccs_configuration_space, ccs_expression])
ccs_configuration_space_add_forbidden_clauses = _ccs_get_function("ccs_configuration_space_add_forbidden_clauses", [ccs_configuration_space, ct.c_size_t, ccs_expression])
ccs_configuration_space_get_forbidden_clause = _ccs_get_function("ccs_configuration_space_get_forbidden_clause", [ccs_configuration_space, ct.c_size_t, ct.POINTER(ccs_expression)])
ccs_configuration_space_get_forbidden_clauses = _ccs_get_function("ccs_configuration_space_get_forbidden_clauses", [ccs_configuration_space, ct.c_size_t, ct.POINTER(ccs_expression), ct.POINTER(ct.c_size_t)])
ccs_configuration_space_check_configuration = _ccs_get_function("ccs_configuration_space_check_configuration", [ccs_configuration_space, ccs_configuration, ct.POINTER(ccs_bool)])
Expand All @@ -26,12 +24,23 @@

class ConfigurationSpace(Context):
def __init__(self, handle = None, retain = False, auto_release = True,
name = "", parameters = None):
name = "", parameters = None, forbidden_clauses = None):
if handle is None:
count = len(parameters)
if forbidden_clauses is not None:
numfc = len(forbidden_clauses)
if numfc > 0:
ctx = dict(zip([x.name for x in parameters], parameters))
fc_expressions = [ parser.parse(fc, context = PContext(extra=ctx)) if isinstance(fc, str) else fc for fc in forbidden_clauses ]
fcv = (ccs_expression * numfc)(*[x.handle.value for x in fc_expressions])
else:
fcv = None
else:
numfc = 0
fcv = None
parameters = (ccs_parameter * count)(*[x.handle.value for x in parameters])
handle = ccs_configuration_space()
res = ccs_create_configuration_space(str.encode(name), count, parameters, ct.byref(handle))
res = ccs_create_configuration_space(str.encode(name), count, parameters, numfc, fcv, ct.byref(handle))
Error.check(res)
super().__init__(handle = handle, retain = False)
else:
Expand Down Expand Up @@ -100,21 +109,6 @@ def unconditional_parameters(self):
conds = self.conditions
return [x for x, y in zip(hps, conds) if y is None]

def add_forbidden_clause(self, expression):
if isinstance(expression, str):
expression = parser.parse(expression, context = PContext(extra=self))
res = ccs_configuration_space_add_forbidden_clause(self.handle, expression.handle)
Error.check(res)

def add_forbidden_clauses(self, expressions):
sz = len(expressions)
if sz == 0:
return None
expressions = [ parser.parse(expression, context = PContext(extra=self)) if isinstance(expression, str) else expression for expression in expressions ]
v = (ccs_expression * sz)(*[x.handle.value for x in expressions])
res = ccs_configuration_space_add_forbidden_clauses(self.handle, sz, v)
Error.check(res)

def forbidden_clause(self, index):
v = ccs_expression()
res = ccs_configuration_space_get_forbidden_clause(self.handle, index, ct.byref(v))
Expand All @@ -123,18 +117,24 @@ def forbidden_clause(self, index):

@property
def num_forbidden_clauses(self):
if hasattr(self, "_num_forbidden_clauses"):
return self._num_forbidden_clauses
v = ct.c_size_t()
res = ccs_configuration_space_get_forbidden_clauses(self.handle, 0, None, ct.byref(v))
Error.check(res)
return v.value
self._num_forbidden_clauses = v.value
return self._num_forbidden_clauses

@property
def forbidden_clauses(self):
if hasattr(self, "_forbidden_clauses"):
return self._forbidden_clauses
sz = self.num_forbidden_clauses
v = (ccs_expression * sz)()
res = ccs_configuration_space_get_forbidden_clauses(self.handle, sz, v, None)
Error.check(res)
return [Expression.from_handle(ccs_expression(x)) for x in v]
self._forbidden_clauses = tuple(Expression.from_handle(ccs_expression(x)) for x in v)
return self._forbidden_clauses

def check(self, configuration):
valid = ccs_bool()
Expand Down
35 changes: 16 additions & 19 deletions bindings/python/test/test_configuration_space.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ def test_create(self):
self.assertIsInstance( cs.rng, ccs.Rng )
self.assertEqual( 3, cs.num_parameters )
self.assertEqual( [None, None, None], cs.conditions )
self.assertEqual( [], cs.forbidden_clauses )
self.assertEqual( (), cs.forbidden_clauses )
self.assertEqual( h1, cs.parameter(0) )
self.assertEqual( h2, cs.parameter(1) )
self.assertEqual( h3, cs.parameter(2) )
Expand Down Expand Up @@ -60,13 +60,12 @@ def test_conditions(self):
h1 = ccs.NumericalParameter.Float(lower = -1.0, upper = 1.0, default = 0.0)
h2 = ccs.NumericalParameter.Float(lower = -1.0, upper = 1.0)
h3 = ccs.NumericalParameter.Float(lower = -1.0, upper = 1.0)
cs = ccs.ConfigurationSpace(name = "space", parameters = [h1, h2, h3])
f1 = ccs.Expression.Less(left = h1, right = 0.0)
cs = ccs.ConfigurationSpace(name = "space", parameters = [h1, h2, h3], forbidden_clauses = [f1])
e1 = ccs.Expression.Less(left = h2, right = 0.0)
cs.set_condition(h3, e1)
e2 = ccs.Expression.Less(left = h3, right = 0.0)
cs.set_condition(h1, e2)
e3 = ccs.Expression.Less(left = h1, right = 0.0)
cs.add_forbidden_clause(e3)
conditions = cs.conditions
conditional_parameters = cs.conditional_parameters
unconditional_parameters = cs.unconditional_parameters
Expand All @@ -81,7 +80,7 @@ def test_conditions(self):
self.assertEqual( h2.handle.value, unconditional_parameters[0].handle.value )
forbidden_clauses = cs.forbidden_clauses
self.assertEqual( 1, len(forbidden_clauses) )
self.assertEqual( e3.handle.value, forbidden_clauses[0].handle.value )
self.assertEqual( f1.handle.value, forbidden_clauses[0].handle.value )

def extract_active_parameters(self, values):
res = ['p1']
Expand Down Expand Up @@ -138,7 +137,15 @@ def test_omp(self):
name = 'p9',
values = ['1', '8', '16'])

cs = ccs.ConfigurationSpace(name = "omp", parameters = [p1, p2, p3, p4, p5, p6, p7, p8, p9])
forbiddena = ccs.ExpressionEqual(left = p1, right = '#pragma omp #P2')
forbiddenb = ccs.ExpressionEqual(left = p2, right = ' ')
forbidden0 = ccs.Expression.And(left = forbiddena, right = forbiddenb)

forbiddenc = ccs.Expression.Equal(left = p1, right = '#pragma omp #P3')
forbiddend = ccs.Expression.Equal(left = p3, right = ' ')
forbidden1 = ccs.Expression.And(left = forbiddenc, right = forbiddend)

cs = ccs.ConfigurationSpace(name = "omp", parameters = [p1, p2, p3, p4, p5, p6, p7, p8, p9], forbidden_clauses = [forbidden0, forbidden1])

cond0 = ccs.Expression.Equal(left = p1, right = '#pragma omp #P2')
cond1 = ccs.Expression.Equal(left = p1, right = '#pragma omp target teams distribute #P2')
Expand All @@ -165,15 +172,6 @@ def test_omp(self):
cs.set_condition(p8, ccs.Expression.Or(left = cond7, right = cond9))
cs.set_condition(p9, cond10)

forbiddena = ccs.ExpressionEqual(left = p1, right = '#pragma omp #P2')
forbiddenb = ccs.ExpressionEqual(left = p2, right = ' ')
forbidden0 = ccs.Expression.And(left = forbiddena, right = forbiddenb)

forbiddenc = ccs.Expression.Equal(left = p1, right = '#pragma omp #P3')
forbiddend = ccs.Expression.Equal(left = p3, right = ' ')
forbidden1 = ccs.Expression.And(left = forbiddenc, right = forbiddend)
cs.add_forbidden_clauses([forbidden0, forbidden1])

all_params = [ "p{}".format(i) for i in range(1,10) ]
for i in range(1000):
s = cs.sample()
Expand Down Expand Up @@ -234,7 +232,9 @@ def test_omp_parse(self):
name = 'p9',
values = ['1', '8', '16'])

cs = ccs.ConfigurationSpace(name = "omp", parameters = [p1, p2, p3, p4, p5, p6, p7, p8, p9])
cs = ccs.ConfigurationSpace(name = "omp", parameters = [p1, p2, p3, p4, p5, p6, p7, p8, p9],
forbidden_clauses = ["p1 == '#pragma omp #P2' && p2 == ' '",
"p1 == '#pragma omp #P3' && p3 == ' '"])

cs.set_condition(p2, "p1 # ['#pragma omp #P2', '#pragma omp target teams distribute #P2']")
cs.set_condition(p4, "p1 == '#pragma omp target teams distribute #P4'")
Expand All @@ -245,9 +245,6 @@ def test_omp_parse(self):
cs.set_condition(p8, "p4 == 'dist_schedule(static, #P8)' || p5 == 'schedule(#P7,#P8)'")
cs.set_condition(p9, "p6 == 'numthreads(#P9)'")

cs.add_forbidden_clauses(["p1 == '#pragma omp #P2' && p2 == ' '",
"p1 == '#pragma omp #P3' && p3 == ' '"])

all_params = [ "p{}".format(i) for i in range(1,10) ]
for i in range(1000):
s = cs.sample()
Expand Down
61 changes: 25 additions & 36 deletions bindings/ruby/lib/cconfigspace/configuration_space.rb
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
module CCS
attach_function :ccs_create_configuration_space, [:string, :size_t, :pointer, :pointer], :ccs_result_t
attach_function :ccs_create_configuration_space, [:string, :size_t, :pointer, :size_t, :pointer, :pointer], :ccs_result_t
attach_function :ccs_configuration_space_set_rng, [:ccs_configuration_space_t, :ccs_rng_t], :ccs_result_t
attach_function :ccs_configuration_space_get_rng, [:ccs_configuration_space_t, :pointer], :ccs_result_t
attach_function :ccs_configuration_space_set_condition, [:ccs_configuration_space_t, :size_t, :ccs_expression_t], :ccs_result_t
attach_function :ccs_configuration_space_get_condition, [:ccs_configuration_space_t, :size_t, :pointer], :ccs_result_t
attach_function :ccs_configuration_space_get_conditions, [:ccs_configuration_space_t, :size_t, :pointer, :pointer], :ccs_result_t
attach_function :ccs_configuration_space_add_forbidden_clause, [:ccs_configuration_space_t, :ccs_expression_t], :ccs_result_t
attach_function :ccs_configuration_space_add_forbidden_clauses, [:ccs_configuration_space_t, :size_t, :ccs_expression_t], :ccs_result_t
attach_function :ccs_configuration_space_get_forbidden_clause, [:ccs_configuration_space_t, :size_t, :pointer], :ccs_result_t
attach_function :ccs_configuration_space_get_forbidden_clauses, [:ccs_configuration_space_t, :size_t, :pointer, :pointer], :ccs_result_t
attach_function :ccs_configuration_space_check_configuration, [:ccs_configuration_space_t, :ccs_configuration_t, :pointer], :ccs_result_t
Expand All @@ -18,15 +16,26 @@ module CCS
class ConfigurationSpace < Context

def initialize(handle = nil, retain: false, auto_release: true,
name: "", parameters: nil)
name: "", parameters: nil, forbidden_clauses: nil)
if handle
super(handle, retain: retain, auto_release: auto_release)
else
count = parameters.size
p_parameters = MemoryPointer::new(:ccs_parameter_t, count)
p_parameters.write_array_of_pointer(parameters.collect(&:handle))
ptr = MemoryPointer::new(:ccs_configuration_space_t)
CCS.error_check CCS.ccs_create_configuration_space(name, count, p_parameters, ptr)
if forbidden_clauses
ctx = parameters.map { |p| [p.name, p] }.to_h
p = ExpressionParser::new(ctx)
forbidden_clauses = forbidden_clauses.collect { |e| e.kind_of?(String) ? p.parse(e) : e }
fccount = forbidden_clauses.size
fcptr = MemoryPointer::new(:ccs_expression_t, count)
fcptr.write_array_of_pointer(forbidden_clauses.collect(&:handle))
else
fccount = 0
fcptr = nil
end
CCS.error_check CCS.ccs_create_configuration_space(name, count, p_parameters, fccount, fcptr, ptr)
super(ptr.read_ccs_configuration_space_t, retain:false)
end
end
Expand Down Expand Up @@ -94,47 +103,27 @@ def unconditional_parameters
hps.each_with_index.select { |h, i| !conds[i] }.collect { |h, i| h }.to_a
end

def add_forbidden_clause(expression)
if expression.kind_of? String
expression = ExpressionParser::new(self).parse(expression)
end
CCS.error_check CCS.ccs_configuration_space_add_forbidden_clause(@handle, expression)
self
end

def add_forbidden_clauses(expressions)
p = ExpressionParser::new(self)
expressions = expressions.collect { |e|
if e.kind_of? String
e = p.parse(e)
else
e
end
}
count = expressions.size
ptr = MemoryPointer::new(:ccs_expression_t, count)
ptr.write_array_of_pointer(expressions.collect(&:handle))
CCS.error_check CCS.ccs_configuration_space_add_forbidden_clauses(@handle, count, ptr)
self
end

def forbidden_clause(index)
ptr = MemoryPointer::new(:ccs_expression_t)
CCS.error_check CCS.ccs_configuration_space_get_forbidden_clause(@handle, index, ptr)
Expression.from_handle(ptr.read_ccs_expression_t)
end

def num_forbidden_clauses
ptr = MemoryPointer::new(:size_t)
CCS.error_check CCS.ccs_configuration_space_get_forbidden_clauses(@handle, 0, nil, ptr)
ptr.read_size_t
@num_forbidden_clauses ||= begin
ptr = MemoryPointer::new(:size_t)
CCS.error_check CCS.ccs_configuration_space_get_forbidden_clauses(@handle, 0, nil, ptr)
ptr.read_size_t
end
end

def forbidden_clauses
count = num_forbidden_clauses
ptr = MemoryPointer::new(:ccs_expression_t, count)
CCS.error_check CCS.ccs_configuration_space_get_forbidden_clauses(@handle, count, ptr, nil)
count.times.collect { |i| Expression::from_handle(ptr[i].read_pointer) }
@forbidden_clauses ||= begin
count = num_forbidden_clauses
ptr = MemoryPointer::new(:ccs_expression_t, count)
CCS.error_check CCS.ccs_configuration_space_get_forbidden_clauses(@handle, count, ptr, nil)
count.times.collect { |i| Expression::from_handle(ptr[i].read_pointer) }.freeze
end
end

def check(configuration)
Expand Down
34 changes: 16 additions & 18 deletions bindings/ruby/test/test_configuration_space.rb
Original file line number Diff line number Diff line change
Expand Up @@ -60,13 +60,12 @@ def test_conditions
h1 = CCS::NumericalParameter::Float.new(lower: -1.0, upper: 1.0, default: 0.0)
h2 = CCS::NumericalParameter::Float.new(lower: -1.0, upper: 1.0)
h3 = CCS::NumericalParameter::Float.new(lower: -1.0, upper: 1.0)
cs = CCS::ConfigurationSpace::new(name: "space", parameters: [h1, h2, h3])
f1 = CCS::Expression::Less.new(left: h1, right: 0.0)
cs = CCS::ConfigurationSpace::new(name: "space", parameters: [h1, h2, h3], forbidden_clauses: [f1])
e1 = CCS::Expression::Less.new(left: h2, right: 0.0)
cs.set_condition(h3, e1)
e2 = CCS::Expression::Less.new(left: h3, right: 0.0)
cs.set_condition(h1, e2)
e3 = CCS::Expression::Less.new(left: h1, right: 0.0)
cs.add_forbidden_clause(e3)
conditions = cs.conditions
conditional_parameters = cs.conditional_parameters
unconditional_parameters = cs.unconditional_parameters
Expand All @@ -81,7 +80,7 @@ def test_conditions
assert_equal( h2.handle, unconditional_parameters[0].handle )
forbidden_clauses = cs.forbidden_clauses
assert_equal( 1, forbidden_clauses.length )
assert_equal( e3.handle, forbidden_clauses[0].handle )
assert_equal( f1.handle, forbidden_clauses[0].handle )
end

def extract_active_parameters(values)
Expand Down Expand Up @@ -147,7 +146,16 @@ def test_omp
name: 'p9',
values: ['1', '8', '16'])

cs = CCS::ConfigurationSpace::new(name: "omp", parameters: [p1, p2, p3, p4, p5, p6, p7, p8, p9])
forbiddena = CCS::Expression::Equal.new(left: p1, right: '#pragma omp #P2')
forbiddenb = CCS::Expression::Equal.new(left: p2, right: ' ')
forbidden0 = CCS::Expression::And.new(left: forbiddena, right: forbiddenb)

forbiddenc = CCS::Expression::Equal.new(left: p1, right: '#pragma omp #P3')
forbiddend = CCS::Expression::Equal.new(left: p3, right: ' ')
forbidden1 = CCS::Expression::And.new(left: forbiddenc, right: forbiddend)

cs = CCS::ConfigurationSpace::new(name: "omp", parameters: [p1, p2, p3, p4, p5, p6, p7, p8, p9],
forbidden_clauses: [forbidden0, forbidden1])

cond0 = CCS::Expression::Equal.new(left: p1, right: '#pragma omp #P2')
cond1 = CCS::Expression::Equal.new(left: p1, right: '#pragma omp target teams distribute #P2')
Expand Down Expand Up @@ -175,15 +183,6 @@ def test_omp
cs.set_condition(p8, cond_p8)
cs.set_condition(p9, cond10)

forbiddena = CCS::Expression::Equal.new(left: p1, right: '#pragma omp #P2')
forbiddenb = CCS::Expression::Equal.new(left: p2, right: ' ')
forbidden0 = CCS::Expression::And.new(left: forbiddena, right: forbiddenb)

forbiddenc = CCS::Expression::Equal.new(left: p1, right: '#pragma omp #P3')
forbiddend = CCS::Expression::Equal.new(left: p3, right: ' ')
forbidden1 = CCS::Expression::And.new(left: forbiddenc, right: forbiddend)
cs.add_forbidden_clauses([forbidden0, forbidden1])

all_params = (1..9).collect { |i| "p#{i}" }

1000.times {
Expand Down Expand Up @@ -249,7 +248,9 @@ def test_omp_parse
name: 'p9',
values: ['1', '8', '16'])

cs = CCS::ConfigurationSpace::new(name: "omp", parameters: [p1, p2, p3, p4, p5, p6, p7, p8, p9])
cs = CCS::ConfigurationSpace::new(name: "omp", parameters: [p1, p2, p3, p4, p5, p6, p7, p8, p9],
forbidden_clauses: ["p1 == '#pragma omp #P2' && p2 == ' '",
"p1 == '#pragma omp #P3' && p3 == ' '"])

cs.set_condition(p2, "p1 # ['#pragma omp #P2', '#pragma omp target teams distribute #P2']")
cs.set_condition(p4, "p1 == '#pragma omp target teams distribute #P4'")
Expand All @@ -260,9 +261,6 @@ def test_omp_parse
cs.set_condition(p8, "p4 == 'dist_schedule(static, #P8)' || p5 == 'schedule(#P7,#P8)'")
cs.set_condition(p9, "p6 == 'numthreads(#P9)'")

cs.add_forbidden_clauses(["p1 == '#pragma omp #P2' && p2 == ' '",
"p1 == '#pragma omp #P3' && p3 == ' '"])

all_params = (1..9).collect { |i| "p#{i}" }

1000.times {
Expand Down
2 changes: 1 addition & 1 deletion connectors/kokkos/ccs-kokkos-connector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -515,7 +515,7 @@ kokkosp_request_values(

CCS_CHECK(ccs_create_configuration_space(
("cs (region: " + std::to_string(regionCounter) + ")").c_str(),
numTuningVariables, cs_parameters, &cs));
numTuningVariables, cs_parameters, 0, NULL, &cs));
delete[] cs_parameters;

#if CCS_DEBUG
Expand Down
Loading

0 comments on commit 5058a45

Please sign in to comment.