Skip to content

Commit

Permalink
ASP-based solver: rescale target weights so that 0 is always the best…
Browse files Browse the repository at this point in the history
… 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.
  • Loading branch information
alalazo committed Jun 24, 2022
1 parent d8a5638 commit 70650ca
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 49 deletions.
37 changes: 14 additions & 23 deletions lib/spack/spack/solver/asp.py
Original file line number Diff line number Diff line change
Expand Up @@ -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 = []

Expand Down Expand Up @@ -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):
Expand Down Expand Up @@ -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):
Expand Down
27 changes: 1 addition & 26 deletions lib/spack/spack/solver/concretize.lp
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand All @@ -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)
Expand Down

0 comments on commit 70650ca

Please sign in to comment.