From 9c23ed6484abb0f31e408ae5bc91e56526a12742 Mon Sep 17 00:00:00 2001 From: Massimiliano Culpo Date: Tue, 13 Oct 2020 15:11:32 +0200 Subject: concretizer: handle target preferences from packages.yaml The weight of the target used in concretization is, in order: 1. A specific per package weight, if set in packages.yaml 2. Inherited from the parent, if possible 3. The default target weight (always set) --- lib/spack/spack/solver/asp.py | 27 ++++++++++++++++++++------- lib/spack/spack/solver/concretize.lp | 27 +++++++++++++++++++++++++-- 2 files changed, 45 insertions(+), 9 deletions(-) diff --git a/lib/spack/spack/solver/asp.py b/lib/spack/spack/solver/asp.py index 448291cd29..6695dd7b18 100644 --- a/lib/spack/spack/solver/asp.py +++ b/lib/spack/spack/solver/asp.py @@ -997,14 +997,13 @@ class SpackSolverSetup(object): self.gen.out.write(external_rule) self.gen.control.add("base", [], external_rule) - def concretization_preferences(self, pkg_name): + def preferred_variants(self, pkg_name): """Facts on concretization preferences, as read from packages.yaml""" preferences = spack.package_prefs.PackagePrefs preferred_variants = preferences.preferred_variants(pkg_name) if not preferred_variants: return - self.gen.h2('Concretization preferences {0}'.format(pkg_name)) for variant_name in sorted(preferred_variants): variant = preferred_variants[variant_name] values = variant.value @@ -1017,6 +1016,21 @@ class SpackSolverSetup(object): pkg_name, variant.name, value )) + def preferred_targets(self, pkg_name): + key_fn = spack.package_prefs.PackagePrefs(pkg_name, 'target') + target_specs = [ + spack.spec.Spec('target={0}'.format(target_name)) + for target_name in llnl.util.cpu.targets + ] + preferred_targets = [x for x in target_specs if key_fn(x) < 0] + if not preferred_targets: + return + + preferred = preferred_targets[0] + self.gen.fact(fn.package_target_weight( + str(preferred.architecture.target), pkg_name, -10 + )) + def flag_defaults(self): self.gen.h2("Compiler flag defaults") @@ -1193,8 +1207,6 @@ class SpackSolverSetup(object): for compiler in sorted(compilers): supported = self._supported_targets(compiler, compatible_targets) -# print(" ", compiler, "supports", [t.name for t in supported]) - if not supported: continue @@ -1227,10 +1239,10 @@ class SpackSolverSetup(object): # prefer best possible targets; weight others poorly so # they're not used unless set explicitly if target.name in best_targets: - self.gen.fact(fn.target_weight(target.name, i)) + self.gen.fact(fn.default_target_weight(target.name, i)) i += 1 else: - self.gen.fact(fn.target_weight(target.name, 100)) + self.gen.fact(fn.default_target_weight(target.name, 100)) self.gen.newline() @@ -1394,7 +1406,8 @@ class SpackSolverSetup(object): for pkg in sorted(pkgs): self.gen.h2('Package: %s' % pkg) self.pkg_rules(pkg) - self.concretization_preferences(pkg) + self.preferred_variants(pkg) + self.preferred_targets(pkg) self.gen.h1('Spec Constraints') for spec in sorted(specs): diff --git a/lib/spack/spack/solver/concretize.lp b/lib/spack/spack/solver/concretize.lp index 22bb1dff3f..af168ce109 100644 --- a/lib/spack/spack/solver/concretize.lp +++ b/lib/spack/spack/solver/concretize.lp @@ -235,6 +235,22 @@ node_os(Package, OS) % one target per node -- optimization will pick the "best" one 1 { node_target(Package, Target) : target(Target) } 1 :- node(Package). +% The target weight is either the default target weight +% or a more specific per-package weight if set +target_weight(Target, Package, Weight) + :- default_target_weight(Target, Weight), + node(Package), + not derive_target_from_parent(_, Package), + not package_target_weight(Target, Package, _). + +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 :- node_target(Package, Target), not compiler_supports_target(Compiler, Version, Target), @@ -247,7 +263,9 @@ node_target(Package, Target) % each node has the weight of its assigned target node_target_weight(Package, Weight) - :- node(Package), node_target(Package, Target), target_weight(Target, Weight). + :- node(Package), + node_target(Package, Target), + target_weight(Target, Package, Weight). % compatibility rules for targets among nodes node_target_match_pref(Package, Target) :- node_target_set(Package, Target). @@ -257,7 +275,12 @@ node_target_match_pref(Dependency, Target) node_target_match(Package, 1) :- node_target(Package, Target), node_target_match_pref(Package, Target). +derive_target_from_parent(Parent, Package) + :- depends_on(Parent, Package), not package_target_weight(_, Package, _). + + #defined node_target_set/2. +#defined package_target_weight/3. %----------------------------------------------------------------------------- % Compiler semantics @@ -422,7 +445,7 @@ root(Dependency, 1) :- not root(Dependency), node(Dependency). % fastest target for node % TODO: if these are slightly different by compiler (e.g., skylake is -% best, gcc supports skylake and broadweell, clang's best is haswell) +% best, gcc supports skylake and broadwell, clang's best is haswell) % things seem to get really slow. #maximize{ Weight@5,Package : node_target_match(Package, Weight) }. #minimize{ Weight@4,Package : node_target_weight(Package, Weight) }. -- cgit v1.2.3-60-g2f50