concretizer: added logic for preferred variants
If preferred variants are present, they'll set the default value of a variant. Otherwise the default value is what is encoded in package.py
This commit is contained in:
parent
81c7cf45e1
commit
d4b83daa48
@ -819,12 +819,16 @@ def pkg_rules(self, pkg):
|
||||
if single_value:
|
||||
self.gen.fact(fn.variant_single_value(pkg.name, name))
|
||||
self.gen.fact(
|
||||
fn.variant_default_value(pkg.name, name, variant.default))
|
||||
fn.variant_default_value_from_package_py(
|
||||
pkg.name, name, variant.default)
|
||||
)
|
||||
else:
|
||||
defaults = variant.default.split(',')
|
||||
for val in sorted(defaults):
|
||||
self.gen.fact(
|
||||
fn.variant_default_value(pkg.name, name, val))
|
||||
fn.variant_default_value_from_package_py(
|
||||
pkg.name, name, val)
|
||||
)
|
||||
|
||||
values = variant.values
|
||||
if values is None:
|
||||
@ -947,16 +951,16 @@ def external_packages(self):
|
||||
self.gen.fact(fn.external_only(pkg_name))
|
||||
|
||||
# Read a list of all the specs for this package
|
||||
externals = data['externals']
|
||||
externals = data.get('externals', [])
|
||||
external_specs = [spack.spec.Spec(x['spec']) for x in externals]
|
||||
|
||||
# Compute versions with appropriate weights
|
||||
external_versions = [
|
||||
(x.version, id) for id, x in enumerate(external_specs)
|
||||
(x.version, idx) for idx, x in enumerate(external_specs)
|
||||
]
|
||||
external_versions = [
|
||||
(v, -(w + 1), id)
|
||||
for w, (v, id) in enumerate(sorted(external_versions))
|
||||
(v, -(w + 1), idx)
|
||||
for w, (v, idx) in enumerate(sorted(external_versions))
|
||||
]
|
||||
for version, weight, id in external_versions:
|
||||
self.gen.fact(fn.external_version_declared(
|
||||
@ -993,6 +997,26 @@ def external_packages(self):
|
||||
self.gen.out.write(external_rule)
|
||||
self.gen.control.add("base", [], external_rule)
|
||||
|
||||
def concretization_preferences(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
|
||||
|
||||
if not isinstance(values, tuple):
|
||||
values = (values,)
|
||||
|
||||
for value in values:
|
||||
self.gen.fact(fn.variant_default_value_from_packages_yaml(
|
||||
pkg_name, variant.name, value
|
||||
))
|
||||
|
||||
def flag_defaults(self):
|
||||
self.gen.h2("Compiler flag defaults")
|
||||
|
||||
@ -1370,6 +1394,7 @@ 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.gen.h1('Spec Constraints')
|
||||
for spec in sorted(specs):
|
||||
|
@ -163,7 +163,16 @@ variant_not_default(Package, Variant, Value, 0)
|
||||
variant_default_value(Package, Variant, Value),
|
||||
node(Package).
|
||||
|
||||
% suppress wranings about this atom being unset. It's only set if some
|
||||
% The default value for a variant in a package is what is written
|
||||
% in the package.py file, unless some preference is set in packages.yaml
|
||||
variant_default_value(Package, Variant, Value)
|
||||
:- variant_default_value_from_package_py(Package, Variant, Value),
|
||||
not variant_default_value_from_packages_yaml(Package, Variant, _).
|
||||
|
||||
variant_default_value(Package, Variant, Value)
|
||||
:- variant_default_value_from_packages_yaml(Package, Variant, Value).
|
||||
|
||||
% suppress warnings about this atom being unset. It's only set if some
|
||||
% spec or some package sets it, and without this, clingo will give
|
||||
% warnings like 'info: atom does not occur in any rule head'.
|
||||
#defined variant/2.
|
||||
@ -171,6 +180,7 @@ variant_not_default(Package, Variant, Value, 0)
|
||||
#defined variant_single_value/2.
|
||||
#defined variant_default_value/3.
|
||||
#defined variant_possible_value/3.
|
||||
#defined variant_default_value_from_packages_yaml/3.
|
||||
|
||||
%-----------------------------------------------------------------------------
|
||||
% Platform semantics
|
||||
|
@ -70,19 +70,22 @@ def assert_variant_values(spec, **variants):
|
||||
|
||||
@pytest.mark.usefixtures('concretize_scope', 'mock_packages')
|
||||
class TestConcretizePreferences(object):
|
||||
def test_preferred_variants(self):
|
||||
"""Test preferred variants are applied correctly
|
||||
"""
|
||||
update_packages('mpileaks', 'variants', '~debug~opt+shared+static')
|
||||
assert_variant_values(
|
||||
'mpileaks', debug=False, opt=False, shared=True, static=True
|
||||
)
|
||||
update_packages(
|
||||
'mpileaks', 'variants', ['+debug', '+opt', '~shared', '-static']
|
||||
)
|
||||
assert_variant_values(
|
||||
'mpileaks', debug=True, opt=True, shared=False, static=False
|
||||
)
|
||||
@pytest.mark.parametrize('package_name,variant_value,expected_results', [
|
||||
('mpileaks', '~debug~opt+shared+static',
|
||||
{'debug': False, 'opt': False, 'shared': True, 'static': True}),
|
||||
# Check that using a list of variants instead of a single string works
|
||||
('mpileaks', ['~debug', '~opt', '+shared', '+static'],
|
||||
{'debug': False, 'opt': False, 'shared': True, 'static': True}),
|
||||
# Use different values for the variants and check them again
|
||||
('mpileaks', ['+debug', '+opt', '~shared', '-static'],
|
||||
{'debug': True, 'opt': True, 'shared': False, 'static': False}),
|
||||
])
|
||||
def test_preferred_variants(
|
||||
self, package_name, variant_value, expected_results
|
||||
):
|
||||
"""Test preferred variants are applied correctly"""
|
||||
update_packages(package_name, 'variants', variant_value)
|
||||
assert_variant_values(package_name, **expected_results)
|
||||
|
||||
def test_preferred_variants_from_wildcard(self):
|
||||
"""
|
||||
|
@ -42,16 +42,16 @@ class Plasma(CMakePackage):
|
||||
depends_on("blas")
|
||||
depends_on("lapack")
|
||||
|
||||
conflicts("atlas") # does not have LAPACKE interface
|
||||
conflicts("^atlas") # does not have LAPACKE interface
|
||||
|
||||
# missing LAPACKE features and/or CBLAS headers
|
||||
conflicts("netlib-lapack@:3.5.999")
|
||||
conflicts("^netlib-lapack@:3.5.999")
|
||||
|
||||
# clashes with OpenBLAS declarations and has a problem compiling on its own
|
||||
conflicts("cblas")
|
||||
conflicts("^cblas")
|
||||
|
||||
conflicts("openblas-with-lapack") # incomplete LAPACK implementation
|
||||
conflicts("veclibfort")
|
||||
conflicts("^openblas-with-lapack") # incomplete LAPACK implementation
|
||||
conflicts("^veclibfort")
|
||||
|
||||
# only GCC 4.9+ and higher have sufficient support for OpenMP 4+ tasks+deps
|
||||
conflicts("%gcc@:4.8.99", when='@:17.1')
|
||||
|
Loading…
Reference in New Issue
Block a user