ASP-based solver: decrease the priority of multi-valued variant optimization for root (#26677)

The ASP-based solver maximizes the number of values in multi-valued
variants (if other higher order constraints are met), to avoid cases
where only a subset of the values that have been specified on the
command line or imposed by another constraint are selected.

Here we swap the priority of this optimization target with the
selection of the default providers, to avoid unexpected results
like the one in #26598
This commit is contained in:
Massimiliano Culpo 2021-10-12 14:15:48 +02:00 committed by GitHub
parent c2bf585d17
commit 551120ee0b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 70 additions and 10 deletions

View File

@ -732,23 +732,24 @@ opt_criterion(14, "number of non-default variants (roots)").
: variant_not_default(Package, Variant, Value, Weight), root(Package) : variant_not_default(Package, Variant, Value, Weight), root(Package)
}. }.
opt_criterion(13, "preferred providers for roots").
#minimize{ 0@13 : #true }.
#minimize{
Weight@13,Provider,Virtual
: provider_weight(Provider, Virtual, Weight), root(Provider)
}.
% If the value is a multivalued variant there could be multiple % If the value is a multivalued variant there could be multiple
% values set as default. Since a default value has a weight of 0 we % values set as default. Since a default value has a weight of 0 we
% need to maximize their number below to ensure they're all set % need to maximize their number below to ensure they're all set
opt_criterion(13, "multi-valued variants"). opt_criterion(12, "number of values in multi valued variants (root)").
#minimize{ 0@13 : #true }. #minimize{ 0@12 : #true }.
#maximize { #maximize {
1@13,Package,Variant,Value 1@12,Package,Variant,Value
: variant_not_default(Package, Variant, Value, Weight), : variant_not_default(Package, Variant, Value, Weight),
not variant_single_value(Package, Variant), not variant_single_value(Package, Variant),
root(Package) root(Package)
}. }.
opt_criterion(12, "preferred providers for roots").
#minimize{ 0@12 : #true }.
#minimize{
Weight@12,Provider,Virtual
: provider_weight(Provider, Virtual, Weight), root(Provider)
}.
% Try to use default variants or variants that have been set % Try to use default variants or variants that have been set
opt_criterion(11, "number of non-default variants (non-roots)"). opt_criterion(11, "number of non-default variants (non-roots)").
@ -782,7 +783,7 @@ opt_criterion(7, "version badness").
% If the value is a multivalued variant there could be multiple % If the value is a multivalued variant there could be multiple
% values set as default. Since a default value has a weight of 0 we % values set as default. Since a default value has a weight of 0 we
% need to maximize their number below to ensure they're all set % need to maximize their number below to ensure they're all set
opt_criterion(6, "count of non-root multi-valued variants"). opt_criterion(6, "number of values in multi valued variants (non-root)").
#minimize{ 0@6 : #true }. #minimize{ 0@6 : #true }.
#maximize { #maximize {
1@6,Package,Variant,Value 1@6,Package,Variant,Value

View File

@ -396,3 +396,23 @@ def test_dependencies_cant_make_version_parent_score_better(self):
assert s.satisfies('^version-test-pkg@2.4.6') assert s.satisfies('^version-test-pkg@2.4.6')
assert 'version-test-dependency-preferred' not in s assert 'version-test-dependency-preferred' not in s
@pytest.mark.regression('26598')
def test_multivalued_variants_are_lower_priority_than_providers(self):
"""Test that the rule to maximize the number of values for multivalued
variants is considered at lower priority than selecting the default
provider for virtual dependencies.
This ensures that we don't e.g. select openmpi over mpich even if we
specified mpich as the default mpi provider, just because openmpi supports
more fabrics by default.
"""
with spack.config.override(
'packages:all', {
'providers': {
'somevirtual': ['some-virtual-preferred']
}
}
):
s = Spec('somevirtual').concretized()
assert s.name == 'some-virtual-preferred'

View File

@ -0,0 +1,22 @@
# Copyright 2013-2021 Lawrence Livermore National Security, LLC and other
# Spack Project Developers. See the top-level COPYRIGHT file for details.
#
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
from spack import *
class SomeVirtualMv(Package):
"""Package providing a virtual dependency and with a multivalued variant."""
homepage = "http://www.example.com"
url = "http://www.example.com/foo-1.0.tar.gz"
version('1.0', '0123456789abcdef0123456789abcdef')
provides('somevirtual')
# This multi valued variant is needed to trigger an optimization
# criteria for clingo
variant('libs', default='shared,static', values=('shared', 'static'),
multi=True, description='Build shared libs, static libs or both')

View File

@ -0,0 +1,17 @@
# Copyright 2013-2021 Lawrence Livermore National Security, LLC and other
# Spack Project Developers. See the top-level COPYRIGHT file for details.
#
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
from spack import *
class SomeVirtualPreferred(Package):
"""Package providing a virtual dependency with a preference in packages.yaml"""
homepage = "http://www.example.com"
url = "http://www.example.com/foo-1.0.tar.gz"
version('1.0', '0123456789abcdef0123456789abcdef')
provides('somevirtual')