ASP-based solver: rescale target weights so that 0 is always the best score (#31226)
fixes #30997 Instead of giving a penalty of 30 to all nodes when preferences are not package specific, give a penalty of 100 to all targets of a node where we have package specific preferences, if the target is not explicitly preferred.
This commit is contained in:
parent
d8a5638d9f
commit
70650cacbd
@ -717,7 +717,7 @@ def __init__(self, tests=False):
|
||||
self.variant_values_from_specs = set()
|
||||
self.version_constraints = set()
|
||||
self.target_constraints = set()
|
||||
self.default_targets = {}
|
||||
self.default_targets = []
|
||||
self.compiler_version_constraints = set()
|
||||
self.post_facts = []
|
||||
|
||||
@ -1178,29 +1178,19 @@ def target_preferences(self, pkg_name):
|
||||
if not self.target_specs_cache:
|
||||
self.target_specs_cache = [
|
||||
spack.spec.Spec('target={0}'.format(target_name))
|
||||
for target_name in archspec.cpu.TARGETS
|
||||
for _, target_name in self.default_targets
|
||||
]
|
||||
|
||||
target_specs = self.target_specs_cache
|
||||
preferred_targets = [x for x in target_specs if key_fn(x) < 0]
|
||||
package_targets = self.target_specs_cache[:]
|
||||
package_targets.sort(key=key_fn)
|
||||
|
||||
for i, preferred in enumerate(preferred_targets):
|
||||
self.gen.fact(fn.package_target_weight(
|
||||
str(preferred.architecture.target), pkg_name, i
|
||||
))
|
||||
|
||||
# generate weights for non-preferred targets on a per-package basis
|
||||
default_targets = {
|
||||
name: weight for
|
||||
name, weight in self.default_targets.items()
|
||||
if not any(preferred.architecture.target.name == name
|
||||
for preferred in preferred_targets)
|
||||
}
|
||||
|
||||
num_preferred = len(preferred_targets)
|
||||
for name, weight in default_targets.items():
|
||||
self.gen.fact(fn.default_target_weight(
|
||||
name, pkg_name, weight + num_preferred + 30
|
||||
offset = 0
|
||||
best_default = self.default_targets[0][1]
|
||||
for i, preferred in enumerate(package_targets):
|
||||
if str(preferred.architecture.target) == best_default and i != 0:
|
||||
offset = 100
|
||||
self.gen.fact(fn.target_weight(
|
||||
pkg_name, str(preferred.architecture.target), i + offset
|
||||
))
|
||||
|
||||
def flag_defaults(self):
|
||||
@ -1604,11 +1594,12 @@ def target_defaults(self, specs):
|
||||
# these are stored to be generated as facts later offset by the
|
||||
# number of preferred targets
|
||||
if target.name in best_targets:
|
||||
self.default_targets[target.name] = i
|
||||
self.default_targets.append((i, target.name))
|
||||
i += 1
|
||||
else:
|
||||
self.default_targets[target.name] = 100
|
||||
self.default_targets.append((100, target.name))
|
||||
|
||||
self.default_targets = list(sorted(set(self.default_targets)))
|
||||
self.gen.newline()
|
||||
|
||||
def virtual_providers(self):
|
||||
|
@ -807,27 +807,6 @@ target_compatible(Descendent, Ancestor)
|
||||
#defined target_satisfies/2.
|
||||
#defined target_parent/2.
|
||||
|
||||
% If the package does not have any specific weight for this
|
||||
% target, offset the default weights by the number of specific
|
||||
% weights and use that. We additionally offset by 30 to ensure
|
||||
% preferences are propagated even against large numbers of
|
||||
% otherwise "better" matches.
|
||||
target_weight(Target, Package, Weight)
|
||||
:- default_target_weight(Target, Package, Weight),
|
||||
node(Package),
|
||||
not derive_target_from_parent(_, Package),
|
||||
not package_target_weight(Target, Package, _).
|
||||
|
||||
% TODO: Need to account for the case of more than one parent
|
||||
% TODO: each of which sets different targets
|
||||
target_weight(Target, Dependency, Weight)
|
||||
:- depends_on(Package, Dependency),
|
||||
derive_target_from_parent(Package, Dependency),
|
||||
target_weight(Target, Package, Weight).
|
||||
|
||||
target_weight(Target, Package, Weight)
|
||||
:- package_target_weight(Target, Package, Weight).
|
||||
|
||||
% can't use targets on node if the compiler for the node doesn't support them
|
||||
error(2, "{0} compiler '{2}@{3}' incompatible with 'target={1}'", Package, Target, Compiler, Version)
|
||||
:- node_target(Package, Target),
|
||||
@ -844,11 +823,7 @@ node_target(Package, Target)
|
||||
node_target_weight(Package, Weight)
|
||||
:- node(Package),
|
||||
node_target(Package, Target),
|
||||
target_weight(Target, Package, Weight).
|
||||
|
||||
derive_target_from_parent(Parent, Package)
|
||||
:- depends_on(Parent, Package),
|
||||
not package_target_weight(_, Package, _).
|
||||
target_weight(Package, Target, Weight).
|
||||
|
||||
% compatibility rules for targets among nodes
|
||||
node_target_match(Parent, Dependency)
|
||||
|
Loading…
Reference in New Issue
Block a user