ASP: targets, compilers and providers soft-preferences are only global (#31261)
Modify the packages.yaml schema so that soft-preferences on targets, compilers and providers can only be specified under the "all" attribute. This makes them effectively global preferences. Version preferences instead can only be specified under a package specific section. If a preference attribute is found in a section where it should not be, it will be ignored and a warning is printed to screen.
This commit is contained in:
parent
4004f27bc0
commit
f3537bc66b
11 changed files with 207 additions and 205 deletions
|
@ -526,56 +526,52 @@ Package Preferences
|
|||
In some cases package requirements can be too strong, and package
|
||||
preferences are the better option. Package preferences do not impose
|
||||
constraints on packages for particular versions or variants values,
|
||||
they rather only set defaults -- the concretizer is free to change
|
||||
them if it must due to other constraints. Also note that package
|
||||
preferences are of lower priority than reuse of already installed
|
||||
packages.
|
||||
they rather only set defaults. The concretizer is free to change
|
||||
them if it must, due to other constraints, and also prefers reusing
|
||||
installed packages over building new ones that are a better match for
|
||||
preferences.
|
||||
|
||||
Here's an example ``packages.yaml`` file that sets preferred packages:
|
||||
Most package preferences (``compilers``, ``target`` and ``providers``)
|
||||
can only be set globally under the ``all`` section of ``packages.yaml``:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
packages:
|
||||
all:
|
||||
compiler: [gcc@12.2.0, clang@12:, oneapi@2023:]
|
||||
target: [x86_64_v3]
|
||||
providers:
|
||||
mpi: [mvapich2, mpich, openmpi]
|
||||
|
||||
These preferences override Spack's default and effectively reorder priorities
|
||||
when looking for the best compiler, target or virtual package provider. Each
|
||||
preference takes an ordered list of spec constraints, with earlier entries in
|
||||
the list being preferred over later entries.
|
||||
|
||||
In the example above all packages prefer to be compiled with ``gcc@12.2.0``,
|
||||
to target the ``x86_64_v3`` microarchitecture and to use ``mvapich2`` if they
|
||||
depend on ``mpi``.
|
||||
|
||||
The ``variants`` and ``version`` preferences can be set under
|
||||
package specific sections of the ``packages.yaml`` file:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
packages:
|
||||
opencv:
|
||||
compiler: [gcc@4.9]
|
||||
variants: +debug
|
||||
gperftools:
|
||||
version: [2.2, 2.4, 2.3]
|
||||
all:
|
||||
compiler: [gcc@4.4.7, 'gcc@4.6:', intel, clang, pgi]
|
||||
target: [sandybridge]
|
||||
providers:
|
||||
mpi: [mvapich2, mpich, openmpi]
|
||||
|
||||
At a high level, this example is specifying how packages are preferably
|
||||
concretized. The opencv package should prefer using GCC 4.9 and
|
||||
be built with debug options. The gperftools package should prefer version
|
||||
2.2 over 2.4. Every package on the system should prefer mvapich2 for
|
||||
its MPI and GCC 4.4.7 (except for opencv, which overrides this by preferring GCC 4.9).
|
||||
These options are used to fill in implicit defaults. Any of them can be overwritten
|
||||
on the command line if explicitly requested.
|
||||
In this case, the preference for ``opencv`` is to build with debug options, while
|
||||
``gperftools`` prefers version 2.2 over 2.4.
|
||||
|
||||
Package preferences accept the follow keys or components under
|
||||
the specific package (or ``all``) section: ``compiler``, ``variants``,
|
||||
``version``, ``providers``, and ``target``. Each component has an
|
||||
ordered list of spec ``constraints``, with earlier entries in the
|
||||
list being preferred over later entries.
|
||||
Any preference can be overwritten on the command line if explicitly requested.
|
||||
|
||||
Sometimes a package installation may have constraints that forbid
|
||||
the first concretization rule, in which case Spack will use the first
|
||||
legal concretization rule. Going back to the example, if a user
|
||||
requests gperftools 2.3 or later, then Spack will install version 2.4
|
||||
as the 2.4 version of gperftools is preferred over 2.3.
|
||||
|
||||
An explicit concretization rule in the preferred section will always
|
||||
take preference over unlisted concretizations. In the above example,
|
||||
xlc isn't listed in the compiler list. Every listed compiler from
|
||||
gcc to pgi will thus be preferred over the xlc compiler.
|
||||
|
||||
The syntax for the ``provider`` section differs slightly from other
|
||||
concretization rules. A provider lists a value that packages may
|
||||
``depends_on`` (e.g, MPI) and a list of rules for fulfilling that
|
||||
dependency.
|
||||
Preferences cannot overcome explicit constraints, as they only set a preferred
|
||||
ordering among homogeneous attribute values. Going back to the example, if
|
||||
``gperftools@2.3:`` was requested, then Spack will install version 2.4
|
||||
since the most preferred version 2.2 is prohibited by the version constraint.
|
||||
|
||||
.. _package_permissions:
|
||||
|
||||
|
|
|
@ -407,7 +407,9 @@ def config_prefer_upstream(args):
|
|||
pkgs = {}
|
||||
for spec in pref_specs:
|
||||
# Collect all the upstream compilers and versions for this package.
|
||||
pkg = pkgs.get(spec.name, {"version": [], "compiler": []})
|
||||
pkg = pkgs.get(spec.name, {"version": []})
|
||||
all = pkgs.get("all", {"compiler": []})
|
||||
pkgs["all"] = all
|
||||
pkgs[spec.name] = pkg
|
||||
|
||||
# We have no existing variant if this is our first added version.
|
||||
|
@ -418,8 +420,8 @@ def config_prefer_upstream(args):
|
|||
pkg["version"].append(version)
|
||||
|
||||
compiler = str(spec.compiler)
|
||||
if compiler not in pkg["compiler"]:
|
||||
pkg["compiler"].append(compiler)
|
||||
if compiler not in all["compiler"]:
|
||||
all["compiler"].append(compiler)
|
||||
|
||||
# Get and list all the variants that differ from the default.
|
||||
variants = []
|
||||
|
|
|
@ -8,6 +8,66 @@
|
|||
:lines: 13-
|
||||
"""
|
||||
|
||||
permissions = {
|
||||
"type": "object",
|
||||
"additionalProperties": False,
|
||||
"properties": {
|
||||
"read": {"type": "string", "enum": ["user", "group", "world"]},
|
||||
"write": {"type": "string", "enum": ["user", "group", "world"]},
|
||||
"group": {"type": "string"},
|
||||
},
|
||||
}
|
||||
|
||||
variants = {"oneOf": [{"type": "string"}, {"type": "array", "items": {"type": "string"}}]}
|
||||
|
||||
requirements = {
|
||||
"oneOf": [
|
||||
# 'require' can be a list of requirement_groups.
|
||||
# each requirement group is a list of one or more
|
||||
# specs. Either at least one or exactly one spec
|
||||
# in the group must be satisfied (depending on
|
||||
# whether you use "any_of" or "one_of",
|
||||
# repectively)
|
||||
{
|
||||
"type": "array",
|
||||
"items": {
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "object",
|
||||
"additionalProperties": False,
|
||||
"properties": {
|
||||
"one_of": {"type": "array", "items": {"type": "string"}},
|
||||
"any_of": {"type": "array", "items": {"type": "string"}},
|
||||
"spec": {"type": "string"},
|
||||
"message": {"type": "string"},
|
||||
"when": {"type": "string"},
|
||||
},
|
||||
},
|
||||
{"type": "string"},
|
||||
]
|
||||
},
|
||||
},
|
||||
# Shorthand for a single requirement group with
|
||||
# one member
|
||||
{"type": "string"},
|
||||
]
|
||||
}
|
||||
|
||||
permissions = {
|
||||
"type": "object",
|
||||
"additionalProperties": False,
|
||||
"properties": {
|
||||
"read": {"type": "string", "enum": ["user", "group", "world"]},
|
||||
"write": {"type": "string", "enum": ["user", "group", "world"]},
|
||||
"group": {"type": "string"},
|
||||
},
|
||||
}
|
||||
|
||||
package_attributes = {
|
||||
"type": "object",
|
||||
"additionalProperties": False,
|
||||
"patternProperties": {r"\w+": {}},
|
||||
}
|
||||
|
||||
#: Properties for inclusion in other schemas
|
||||
properties = {
|
||||
|
@ -15,57 +75,14 @@
|
|||
"type": "object",
|
||||
"default": {},
|
||||
"additionalProperties": False,
|
||||
"patternProperties": {
|
||||
r"\w[\w-]*": { # package name
|
||||
"properties": {
|
||||
"all": { # package name
|
||||
"type": "object",
|
||||
"default": {},
|
||||
"additionalProperties": False,
|
||||
"properties": {
|
||||
"require": {
|
||||
"oneOf": [
|
||||
# 'require' can be a list of requirement_groups.
|
||||
# each requirement group is a list of one or more
|
||||
# specs. Either at least one or exactly one spec
|
||||
# in the group must be satisfied (depending on
|
||||
# whether you use "any_of" or "one_of",
|
||||
# repectively)
|
||||
{
|
||||
"type": "array",
|
||||
"items": {
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "object",
|
||||
"additionalProperties": False,
|
||||
"properties": {
|
||||
"one_of": {
|
||||
"type": "array",
|
||||
"items": {"type": "string"},
|
||||
},
|
||||
"any_of": {
|
||||
"type": "array",
|
||||
"items": {"type": "string"},
|
||||
},
|
||||
"spec": {"type": "string"},
|
||||
"message": {"type": "string"},
|
||||
"when": {"type": "string"},
|
||||
},
|
||||
},
|
||||
{"type": "string"},
|
||||
]
|
||||
},
|
||||
},
|
||||
# Shorthand for a single requirement group with
|
||||
# one member
|
||||
{"type": "string"},
|
||||
]
|
||||
},
|
||||
"version": {
|
||||
"type": "array",
|
||||
"default": [],
|
||||
# version strings (type should be string, number is still possible
|
||||
# but deprecated. this is to avoid issues with e.g. 3.10 -> 3.1)
|
||||
"items": {"anyOf": [{"type": "string"}, {"type": "number"}]},
|
||||
},
|
||||
"require": requirements,
|
||||
"version": {}, # Here only to warn users on ignored properties
|
||||
"target": {
|
||||
"type": "array",
|
||||
"default": [],
|
||||
|
@ -78,22 +95,10 @@
|
|||
"items": {"type": "string"},
|
||||
}, # compiler specs
|
||||
"buildable": {"type": "boolean", "default": True},
|
||||
"permissions": {
|
||||
"type": "object",
|
||||
"additionalProperties": False,
|
||||
"properties": {
|
||||
"read": {"type": "string", "enum": ["user", "group", "world"]},
|
||||
"write": {"type": "string", "enum": ["user", "group", "world"]},
|
||||
"group": {"type": "string"},
|
||||
},
|
||||
},
|
||||
"permissions": permissions,
|
||||
# If 'get_full_repo' is promoted to a Package-level
|
||||
# attribute, it could be useful to set it here
|
||||
"package_attributes": {
|
||||
"type": "object",
|
||||
"additionalProperties": False,
|
||||
"patternProperties": {r"\w+": {}},
|
||||
},
|
||||
"package_attributes": package_attributes,
|
||||
"providers": {
|
||||
"type": "object",
|
||||
"default": {},
|
||||
|
@ -106,12 +111,40 @@
|
|||
}
|
||||
},
|
||||
},
|
||||
"variants": {
|
||||
"oneOf": [
|
||||
{"type": "string"},
|
||||
{"type": "array", "items": {"type": "string"}},
|
||||
]
|
||||
"variants": variants,
|
||||
},
|
||||
"deprecatedProperties": {
|
||||
"properties": ["version"],
|
||||
"message": "setting version preferences in the 'all' section of packages.yaml "
|
||||
"is deprecated and will be removed in v0.22\n\n\tThese preferences "
|
||||
"will be ignored by Spack. You can set them only in package specific sections "
|
||||
"of the same file.\n",
|
||||
"error": False,
|
||||
},
|
||||
}
|
||||
},
|
||||
"patternProperties": {
|
||||
r"(?!^all$)(^\w[\w-]*)": { # package name
|
||||
"type": "object",
|
||||
"default": {},
|
||||
"additionalProperties": False,
|
||||
"properties": {
|
||||
"require": requirements,
|
||||
"version": {
|
||||
"type": "array",
|
||||
"default": [],
|
||||
# version strings
|
||||
"items": {"anyOf": [{"type": "string"}, {"type": "number"}]},
|
||||
},
|
||||
"target": {}, # Here only to warn users on ignored properties
|
||||
"compiler": {}, # Here only to warn users on ignored properties
|
||||
"buildable": {"type": "boolean", "default": True},
|
||||
"permissions": permissions,
|
||||
# If 'get_full_repo' is promoted to a Package-level
|
||||
# attribute, it could be useful to set it here
|
||||
"package_attributes": package_attributes,
|
||||
"providers": {}, # Here only to warn users on ignored properties
|
||||
"variants": variants,
|
||||
"externals": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
|
@ -127,6 +160,14 @@
|
|||
},
|
||||
},
|
||||
},
|
||||
"deprecatedProperties": {
|
||||
"properties": ["target", "compiler", "providers"],
|
||||
"message": "setting compiler, target or provider preferences in a package "
|
||||
"specific section of packages.yaml is deprecated, and will be removed in "
|
||||
"v0.22.\n\n\tThese preferences will be ignored by Spack. You "
|
||||
"can set them only in the 'all' section of the same file.\n",
|
||||
"error": False,
|
||||
},
|
||||
}
|
||||
},
|
||||
}
|
||||
|
|
|
@ -1258,32 +1258,9 @@ def compiler_facts(self):
|
|||
matches = sorted(indexed_possible_compilers, key=lambda x: ppk(x[1].spec))
|
||||
|
||||
for weight, (compiler_id, cspec) in enumerate(matches):
|
||||
f = fn.default_compiler_preference(compiler_id, weight)
|
||||
f = fn.compiler_weight(compiler_id, weight)
|
||||
self.gen.fact(f)
|
||||
|
||||
def package_compiler_defaults(self, pkg):
|
||||
"""Facts about packages' compiler prefs."""
|
||||
|
||||
packages = spack.config.get("packages")
|
||||
pkg_prefs = packages.get(pkg.name)
|
||||
if not pkg_prefs or "compiler" not in pkg_prefs:
|
||||
return
|
||||
|
||||
compiler_list = self.possible_compilers
|
||||
compiler_list = sorted(compiler_list, key=lambda x: (x.name, x.version), reverse=True)
|
||||
ppk = spack.package_prefs.PackagePrefs(pkg.name, "compiler", all=False)
|
||||
matches = sorted(compiler_list, key=lambda x: ppk(x.spec))
|
||||
|
||||
for i, compiler in enumerate(reversed(matches)):
|
||||
self.gen.fact(
|
||||
fn.pkg_fact(
|
||||
pkg.name,
|
||||
fn.node_compiler_preference(
|
||||
compiler.spec.name, compiler.spec.version, -i * 100
|
||||
),
|
||||
)
|
||||
)
|
||||
|
||||
def package_requirement_rules(self, pkg):
|
||||
rules = self.requirement_rules_from_package_py(pkg)
|
||||
rules.extend(self.requirement_rules_from_packages_yaml(pkg))
|
||||
|
@ -1375,9 +1352,6 @@ def pkg_rules(self, pkg, tests):
|
|||
# conflicts
|
||||
self.conflict_rules(pkg)
|
||||
|
||||
# default compilers for this package
|
||||
self.package_compiler_defaults(pkg)
|
||||
|
||||
# virtuals
|
||||
self.package_provider_rules(pkg)
|
||||
|
||||
|
@ -1673,6 +1647,7 @@ def virtual_preferences(self, pkg_name, func):
|
|||
for i, provider in enumerate(providers):
|
||||
provider_name = spack.spec.Spec(provider).name
|
||||
func(vspec, provider_name, i)
|
||||
self.gen.newline()
|
||||
|
||||
def provider_defaults(self):
|
||||
self.gen.h2("Default virtual providers")
|
||||
|
@ -1865,8 +1840,8 @@ def preferred_variants(self, pkg_name):
|
|||
fn.variant_default_value_from_packages_yaml(pkg_name, variant.name, value)
|
||||
)
|
||||
|
||||
def target_preferences(self, pkg_name):
|
||||
key_fn = spack.package_prefs.PackagePrefs(pkg_name, "target")
|
||||
def target_preferences(self):
|
||||
key_fn = spack.package_prefs.PackagePrefs("all", "target")
|
||||
|
||||
if not self.target_specs_cache:
|
||||
self.target_specs_cache = [
|
||||
|
@ -1876,17 +1851,25 @@ def target_preferences(self, pkg_name):
|
|||
|
||||
package_targets = self.target_specs_cache[:]
|
||||
package_targets.sort(key=key_fn)
|
||||
|
||||
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.pkg_fact(
|
||||
pkg_name, fn.target_weight(str(preferred.architecture.target), i + offset)
|
||||
)
|
||||
)
|
||||
self.gen.fact(fn.target_weight(str(preferred.architecture.target), i))
|
||||
|
||||
def flag_defaults(self):
|
||||
self.gen.h2("Compiler flag defaults")
|
||||
|
||||
# types of flags that can be on specs
|
||||
for flag in spack.spec.FlagMap.valid_compiler_flags():
|
||||
self.gen.fact(fn.flag_type(flag))
|
||||
self.gen.newline()
|
||||
|
||||
# flags from compilers.yaml
|
||||
compilers = all_compilers_in_config()
|
||||
for compiler in compilers:
|
||||
for name, flags in compiler.flags.items():
|
||||
for flag in flags:
|
||||
self.gen.fact(
|
||||
fn.compiler_version_flag(compiler.name, compiler.version, name, flag)
|
||||
)
|
||||
|
||||
def spec_clauses(self, *args, **kwargs):
|
||||
"""Wrap a call to `_spec_clauses()` into a try/except block that
|
||||
|
@ -2340,6 +2323,8 @@ def target_defaults(self, specs):
|
|||
|
||||
self.default_targets = list(sorted(set(self.default_targets)))
|
||||
|
||||
self.target_preferences()
|
||||
|
||||
def virtual_providers(self):
|
||||
self.gen.h2("Virtual providers")
|
||||
msg = (
|
||||
|
@ -2661,7 +2646,6 @@ def setup(
|
|||
self.pkg_rules(pkg, tests=self.tests)
|
||||
self.gen.h2("Package preferences: %s" % pkg)
|
||||
self.preferred_variants(pkg)
|
||||
self.target_preferences(pkg)
|
||||
|
||||
self.gen.h1("Develop specs")
|
||||
# Inject dev_path from environment
|
||||
|
|
|
@ -589,21 +589,15 @@ possible_provider_weight(DependencyNode, VirtualNode, 0, "external")
|
|||
:- provider(DependencyNode, VirtualNode),
|
||||
external(DependencyNode).
|
||||
|
||||
% A provider mentioned in packages.yaml can use a weight
|
||||
% according to its priority in the list of providers
|
||||
possible_provider_weight(node(DependencyID, Dependency), node(VirtualID, Virtual), Weight, "packages_yaml")
|
||||
:- provider(node(DependencyID, Dependency), node(VirtualID, Virtual)),
|
||||
depends_on(node(ID, Package), node(DependencyID, Dependency)),
|
||||
pkg_fact(Package, provider_preference(Virtual, Dependency, Weight)).
|
||||
|
||||
% A provider mentioned in the default configuration can use a weight
|
||||
% according to its priority in the list of providers
|
||||
possible_provider_weight(node(DependencyID, Dependency), node(VirtualID, Virtual), Weight, "default")
|
||||
:- provider(node(DependencyID, Dependency), node(VirtualID, Virtual)),
|
||||
default_provider_preference(Virtual, Dependency, Weight).
|
||||
possible_provider_weight(node(ProviderID, Provider), node(VirtualID, Virtual), Weight, "default")
|
||||
:- provider(node(ProviderID, Provider), node(VirtualID, Virtual)),
|
||||
default_provider_preference(Virtual, Provider, Weight).
|
||||
|
||||
% Any provider can use 100 as a weight, which is very high and discourage its use
|
||||
possible_provider_weight(node(DependencyID, Dependency), VirtualNode, 100, "fallback") :- provider(node(DependencyID, Dependency), VirtualNode).
|
||||
possible_provider_weight(node(ProviderID, Provider), VirtualNode, 100, "fallback")
|
||||
:- provider(node(ProviderID, Provider), VirtualNode).
|
||||
|
||||
% do not warn if generated program contains none of these.
|
||||
#defined virtual/1.
|
||||
|
@ -1059,7 +1053,7 @@ attr("node_target", PackageNode, Target)
|
|||
node_target_weight(node(ID, Package), Weight)
|
||||
:- attr("node", node(ID, Package)),
|
||||
attr("node_target", node(ID, Package), Target),
|
||||
pkg_fact(Package, target_weight(Target, Weight)).
|
||||
target_weight(Target, Weight).
|
||||
|
||||
% compatibility rules for targets among nodes
|
||||
node_target_match(ParentNode, DependencyNode)
|
||||
|
@ -1181,23 +1175,17 @@ compiler_mismatch_required(PackageNode, DependencyNode)
|
|||
#defined allow_compiler/2.
|
||||
|
||||
% compilers weighted by preference according to packages.yaml
|
||||
compiler_weight(node(ID, Package), Weight)
|
||||
node_compiler_weight(node(ID, Package), Weight)
|
||||
:- node_compiler(node(ID, Package), CompilerID),
|
||||
compiler_name(CompilerID, Compiler),
|
||||
compiler_version(CompilerID, V),
|
||||
pkg_fact(Package, node_compiler_preference(Compiler, V, Weight)).
|
||||
compiler_weight(node(ID, Package), Weight)
|
||||
compiler_weight(CompilerID, Weight).
|
||||
|
||||
node_compiler_weight(node(ID, Package), 100)
|
||||
:- node_compiler(node(ID, Package), CompilerID),
|
||||
compiler_name(CompilerID, Compiler),
|
||||
compiler_version(CompilerID, V),
|
||||
not pkg_fact(Package, node_compiler_preference(Compiler, V, _)),
|
||||
default_compiler_preference(CompilerID, Weight).
|
||||
compiler_weight(node(ID, Package), 100)
|
||||
:- node_compiler(node(ID, Package), CompilerID),
|
||||
compiler_name(CompilerID, Compiler),
|
||||
compiler_version(CompilerID, V),
|
||||
not pkg_fact(Package, node_compiler_preference(Compiler, V, _)),
|
||||
not default_compiler_preference(CompilerID, _).
|
||||
not compiler_weight(CompilerID, _).
|
||||
|
||||
% For the time being, be strict and reuse only if the compiler match one we have on the system
|
||||
error(100, "Compiler {1}@{2} requested for {0} cannot be found. Set install_missing_compilers:true if intended.", Package, Compiler, Version)
|
||||
|
@ -1205,7 +1193,7 @@ error(100, "Compiler {1}@{2} requested for {0} cannot be found. Set install_miss
|
|||
not node_compiler(node(ID, Package), _).
|
||||
|
||||
#defined node_compiler_preference/4.
|
||||
#defined default_compiler_preference/3.
|
||||
#defined compiler_weight/3.
|
||||
|
||||
%-----------------------------------------------------------------------------
|
||||
% Compiler flags
|
||||
|
@ -1529,7 +1517,7 @@ opt_criterion(15, "non-preferred compilers").
|
|||
#minimize{ 0@15: #true }.
|
||||
#minimize{
|
||||
Weight@15+Priority,PackageNode
|
||||
: compiler_weight(PackageNode, Weight),
|
||||
: node_compiler_weight(PackageNode, Weight),
|
||||
build_priority(PackageNode, Priority)
|
||||
}.
|
||||
|
||||
|
|
|
@ -16,9 +16,9 @@
|
|||
#heuristic attr("version", node(0, Package), Version) : pkg_fact(Package, version_declared(Version, 0)), attr("root", node(0, Package)). [35, true]
|
||||
#heuristic version_weight(node(0, Package), 0) : pkg_fact(Package, version_declared(Version, 0)), attr("root", node(0, Package)). [35, true]
|
||||
#heuristic attr("variant_value", node(0, Package), Variant, Value) : variant_default_value(Package, Variant, Value), attr("root", node(0, Package)). [35, true]
|
||||
#heuristic attr("node_target", node(0, Package), Target) : pkg_fact(Package, target_weight(Target, 0)), attr("root", node(0, Package)). [35, true]
|
||||
#heuristic attr("node_target", node(0, Package), Target) : target_weight(Target, 0), attr("root", node(0, Package)). [35, true]
|
||||
#heuristic node_target_weight(node(0, Package), 0) : attr("root", node(0, Package)). [35, true]
|
||||
#heuristic node_compiler(node(0, Package), CompilerID) : default_compiler_preference(ID, 0), compiler_id(ID), attr("root", node(0, Package)). [35, true]
|
||||
#heuristic node_compiler(node(0, Package), CompilerID) : compiler_weight(ID, 0), compiler_id(ID), attr("root", node(0, Package)). [35, true]
|
||||
|
||||
% Providers
|
||||
#heuristic attr("node", node(0, Package)) : default_provider_preference(Virtual, Package, 0), possible_in_link_run(Package). [30, true]
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
#heuristic attr("variant_value", node(ID, Package), Variant, Value) : variant_default_value(Package, Variant, Value), attr("node", node(ID, Package)), ID > 0. [25-5*ID, true]
|
||||
#heuristic attr("node_target", node(ID, Package), Target) : pkg_fact(Package, target_weight(Target, 0)), attr("node", node(ID, Package)), ID > 0. [25-5*ID, true]
|
||||
#heuristic node_target_weight(node(ID, Package), 0) : attr("node", node(ID, Package)), ID > 0. [25-5*ID, true]
|
||||
#heuristic node_compiler(node(ID, Package), CompilerID) : default_compiler_preference(CompilerID, 0), compiler_id(CompilerID), attr("node", node(ID, Package)), ID > 0. [25-5*ID, true]
|
||||
#heuristic node_compiler(node(ID, Package), CompilerID) : compiler_weight(CompilerID, 0), compiler_id(CompilerID), attr("node", node(ID, Package)), ID > 0. [25-5*ID, true]
|
||||
|
||||
% node(ID, _), split build dependencies
|
||||
#heuristic attr("version", node(ID, Package), Version) : pkg_fact(Package, version_declared(Version, 0)), attr("node", node(ID, Package)), multiple_unification_sets(Package), ID > 0. [25, true]
|
||||
|
@ -21,4 +21,4 @@
|
|||
#heuristic attr("variant_value", node(ID, Package), Variant, Value) : variant_default_value(Package, Variant, Value), attr("node", node(ID, Package)), multiple_unification_sets(Package), ID > 0. [25, true]
|
||||
#heuristic attr("node_target", node(ID, Package), Target) : pkg_fact(Package, target_weight(Target, 0)), attr("node", node(ID, Package)), multiple_unification_sets(Package), ID > 0. [25, true]
|
||||
#heuristic node_target_weight(node(ID, Package), 0) : attr("node", node(ID, Package)), multiple_unification_sets(Package), ID > 0. [25, true]
|
||||
#heuristic node_compiler(node(ID, Package), CompilerID) : default_compiler_preference(CompilerID, 0), compiler_id(CompilerID), attr("node", node(ID, Package)), multiple_unification_sets(Package), ID > 0. [25, true]
|
||||
#heuristic node_compiler(node(ID, Package), CompilerID) : compiler_weight(CompilerID, 0), compiler_id(CompilerID), attr("node", node(ID, Package)), multiple_unification_sets(Package), ID > 0. [25, true]
|
||||
|
|
|
@ -215,10 +215,10 @@ def test_config_add_override_leaf(mutable_empty_config):
|
|||
|
||||
|
||||
def test_config_add_update_dict(mutable_empty_config):
|
||||
config("add", "packages:all:version:[1.0.0]")
|
||||
config("add", "packages:hdf5:version:[1.0.0]")
|
||||
output = config("get", "packages")
|
||||
|
||||
expected = "packages:\n all:\n version: [1.0.0]\n"
|
||||
expected = "packages:\n hdf5:\n version: [1.0.0]\n"
|
||||
assert output == expected
|
||||
|
||||
|
||||
|
@ -352,8 +352,7 @@ def test_config_add_update_dict_from_file(mutable_empty_config, tmpdir):
|
|||
contents = """spack:
|
||||
packages:
|
||||
all:
|
||||
version:
|
||||
- 1.0.0
|
||||
target: [x86_64]
|
||||
"""
|
||||
|
||||
# create temp file and add it to config
|
||||
|
@ -368,8 +367,7 @@ def test_config_add_update_dict_from_file(mutable_empty_config, tmpdir):
|
|||
# added config comes before prior config
|
||||
expected = """packages:
|
||||
all:
|
||||
version:
|
||||
- 1.0.0
|
||||
target: [x86_64]
|
||||
compiler: [gcc]
|
||||
"""
|
||||
|
||||
|
@ -381,7 +379,7 @@ def test_config_add_invalid_file_fails(tmpdir):
|
|||
# invalid because version requires a list
|
||||
contents = """spack:
|
||||
packages:
|
||||
all:
|
||||
hdf5:
|
||||
version: 1.0.0
|
||||
"""
|
||||
|
||||
|
@ -631,14 +629,11 @@ def test_config_prefer_upstream(
|
|||
packages = syaml.load(open(cfg_file))["packages"]
|
||||
|
||||
# Make sure only the non-default variants are set.
|
||||
assert packages["boost"] == {
|
||||
"compiler": ["gcc@=10.2.1"],
|
||||
"variants": "+debug +graph",
|
||||
"version": ["1.63.0"],
|
||||
}
|
||||
assert packages["dependency-install"] == {"compiler": ["gcc@=10.2.1"], "version": ["2.0"]}
|
||||
assert packages["all"] == {"compiler": ["gcc@=10.2.1"]}
|
||||
assert packages["boost"] == {"variants": "+debug +graph", "version": ["1.63.0"]}
|
||||
assert packages["dependency-install"] == {"version": ["2.0"]}
|
||||
# Ensure that neither variant gets listed for hdf5, since they conflict
|
||||
assert packages["hdf5"] == {"compiler": ["gcc@=10.2.1"], "version": ["2.3"]}
|
||||
assert packages["hdf5"] == {"version": ["2.3"]}
|
||||
|
||||
# Make sure a message about the conflicting hdf5's was given.
|
||||
assert "- hdf5" in output
|
||||
|
|
|
@ -2621,7 +2621,7 @@ def test_env_write_only_non_default_nested(tmpdir):
|
|||
- matrix:
|
||||
- [mpileaks]
|
||||
packages:
|
||||
mpileaks:
|
||||
all:
|
||||
compiler: [gcc]
|
||||
view: true
|
||||
"""
|
||||
|
|
|
@ -105,17 +105,13 @@ def test_preferred_variants_from_wildcard(self):
|
|||
|
||||
@pytest.mark.parametrize(
|
||||
"compiler_str,spec_str",
|
||||
[("gcc@4.5.0", "mpileaks"), ("clang@12.0.0", "mpileaks"), ("gcc@4.5.0", "openmpi")],
|
||||
[("gcc@=4.5.0", "mpileaks"), ("clang@=12.0.0", "mpileaks"), ("gcc@=4.5.0", "openmpi")],
|
||||
)
|
||||
def test_preferred_compilers(self, compiler_str, spec_str):
|
||||
"""Test preferred compilers are applied correctly"""
|
||||
spec = Spec(spec_str)
|
||||
update_packages(spec.name, "compiler", [compiler_str])
|
||||
spec.concretize()
|
||||
# note: lhs has concrete compiler version, rhs still abstract.
|
||||
# Could be made more strict by checking for equality with `gcc@=4.5.0`
|
||||
# etc.
|
||||
assert spec.compiler.satisfies(CompilerSpec(compiler_str))
|
||||
update_packages("all", "compiler", [compiler_str])
|
||||
spec = spack.spec.Spec(spec_str).concretized()
|
||||
assert spec.compiler == CompilerSpec(compiler_str)
|
||||
|
||||
@pytest.mark.only_clingo("Use case not supported by the original concretizer")
|
||||
def test_preferred_target(self, mutable_mock_repo):
|
||||
|
@ -124,7 +120,7 @@ def test_preferred_target(self, mutable_mock_repo):
|
|||
default = str(spec.target)
|
||||
preferred = str(spec.target.family)
|
||||
|
||||
update_packages("mpich", "target", [preferred])
|
||||
update_packages("all", "target", [preferred])
|
||||
spec = concretize("mpich")
|
||||
assert str(spec.target) == preferred
|
||||
|
||||
|
@ -132,7 +128,7 @@ def test_preferred_target(self, mutable_mock_repo):
|
|||
assert str(spec["mpileaks"].target) == preferred
|
||||
assert str(spec["mpich"].target) == preferred
|
||||
|
||||
update_packages("mpileaks", "target", [default])
|
||||
update_packages("all", "target", [default])
|
||||
spec = concretize("mpileaks")
|
||||
assert str(spec["mpileaks"].target) == default
|
||||
assert str(spec["mpich"].target) == default
|
||||
|
|
|
@ -78,7 +78,7 @@ def env_yaml(tmpdir):
|
|||
verify_ssl: False
|
||||
dirty: False
|
||||
packages:
|
||||
libelf:
|
||||
all:
|
||||
compiler: [ 'gcc@4.5.3' ]
|
||||
repos:
|
||||
- /x/y/z
|
||||
|
@ -942,7 +942,7 @@ def test_single_file_scope(config, env_yaml):
|
|||
# from the single-file config
|
||||
assert spack.config.get("config:verify_ssl") is False
|
||||
assert spack.config.get("config:dirty") is False
|
||||
assert spack.config.get("packages:libelf:compiler") == ["gcc@4.5.3"]
|
||||
assert spack.config.get("packages:all:compiler") == ["gcc@4.5.3"]
|
||||
|
||||
# from the lower config scopes
|
||||
assert spack.config.get("config:checksum") is True
|
||||
|
@ -965,7 +965,7 @@ def test_single_file_scope_section_override(tmpdir, config):
|
|||
config:
|
||||
verify_ssl: False
|
||||
packages::
|
||||
libelf:
|
||||
all:
|
||||
compiler: [ 'gcc@4.5.3' ]
|
||||
repos:
|
||||
- /x/y/z
|
||||
|
@ -977,7 +977,7 @@ def test_single_file_scope_section_override(tmpdir, config):
|
|||
with spack.config.override(scope):
|
||||
# from the single-file config
|
||||
assert spack.config.get("config:verify_ssl") is False
|
||||
assert spack.config.get("packages:libelf:compiler") == ["gcc@4.5.3"]
|
||||
assert spack.config.get("packages:all:compiler") == ["gcc@4.5.3"]
|
||||
|
||||
# from the lower config scopes
|
||||
assert spack.config.get("config:checksum") is True
|
||||
|
|
Loading…
Reference in a new issue