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)
This commit is contained in:
parent
67344326c3
commit
9c23ed6484
2 changed files with 45 additions and 9 deletions
|
@ -997,14 +997,13 @@ def external_packages(self):
|
|||
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 @@ def concretization_preferences(self, pkg_name):
|
|||
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 @@ def target_defaults(self, specs):
|
|||
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 @@ def target_defaults(self, specs):
|
|||
# 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 @@ def setup(self, driver, specs):
|
|||
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):
|
||||
|
|
|
@ -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) }.
|
||||
|
|
Loading…
Reference in a new issue