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