ASP-based solver: fix issue with conditional requirements and trigger conditions (#42566)
The lack of a rule to avoid enforcing requirements on multi-valued variants, when the condition activating the environment was not met, resulted in multiple optimal solutions. The fix is to prevent imposing a requirement if the when= rule activating it is not met.
This commit is contained in:
parent
2883559b49
commit
eb27ee7ae8
4 changed files with 92 additions and 0 deletions
|
@ -698,6 +698,14 @@ requirement_group_satisfied(node(ID, Package), X) :-
|
|||
activate_requirement(node(ID, Package), X),
|
||||
requirement_group(Package, X).
|
||||
|
||||
% Do not impose requirements, if the conditional requirement is not active
|
||||
do_not_impose(EffectID, node(ID, Package)) :-
|
||||
trigger_condition_holds(TriggerID, node(ID, Package)),
|
||||
pkg_fact(Package, condition_trigger(ConditionID, TriggerID)),
|
||||
pkg_fact(Package, condition_effect(ConditionID, EffectID)),
|
||||
requirement_group_member(ConditionID , Package, RequirementID),
|
||||
not activate_requirement(node(ID, Package), RequirementID).
|
||||
|
||||
% When we have a required provider, we need to ensure that the provider/2 facts respect
|
||||
% the requirement. This is particularly important for packages that could provide multiple
|
||||
% virtuals independently
|
||||
|
|
|
@ -919,3 +919,46 @@ def test_requiring_package_on_multiple_virtuals(concretize_scope, mock_packages)
|
|||
assert s["blas"].name == "intel-parallel-studio"
|
||||
assert s["lapack"].name == "intel-parallel-studio"
|
||||
assert s["scalapack"].name == "intel-parallel-studio"
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"spec_str,expected,not_expected",
|
||||
[
|
||||
(
|
||||
"forward-multi-value +cuda cuda_arch=10 ^dependency-mv~cuda",
|
||||
["cuda_arch=10", "^dependency-mv~cuda"],
|
||||
["cuda_arch=11", "^dependency-mv cuda_arch=10", "^dependency-mv cuda_arch=11"],
|
||||
),
|
||||
(
|
||||
"forward-multi-value +cuda cuda_arch=10 ^dependency-mv+cuda",
|
||||
["cuda_arch=10", "^dependency-mv cuda_arch=10"],
|
||||
["cuda_arch=11", "^dependency-mv cuda_arch=11"],
|
||||
),
|
||||
(
|
||||
"forward-multi-value +cuda cuda_arch=11 ^dependency-mv+cuda",
|
||||
["cuda_arch=11", "^dependency-mv cuda_arch=11"],
|
||||
["cuda_arch=10", "^dependency-mv cuda_arch=10"],
|
||||
),
|
||||
(
|
||||
"forward-multi-value +cuda cuda_arch=10,11 ^dependency-mv+cuda",
|
||||
["cuda_arch=10,11", "^dependency-mv cuda_arch=10,11"],
|
||||
[],
|
||||
),
|
||||
],
|
||||
)
|
||||
def test_forward_multi_valued_variant_using_requires(
|
||||
spec_str, expected, not_expected, config, mock_packages
|
||||
):
|
||||
"""Tests that a package can forward multivalue variants to dependencies, using
|
||||
`requires` directives of the form:
|
||||
|
||||
for _val in ("shared", "static"):
|
||||
requires(f"^some-virtual-mv libs={_val}", when=f"libs={_val} ^some-virtual-mv")
|
||||
"""
|
||||
s = Spec(spec_str).concretized()
|
||||
|
||||
for constraint in expected:
|
||||
assert s.satisfies(constraint)
|
||||
|
||||
for constraint in not_expected:
|
||||
assert not s.satisfies(constraint)
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
# Copyright 2013-2024 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.package import *
|
||||
|
||||
|
||||
class DependencyMv(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", md5="0123456789abcdef0123456789abcdef")
|
||||
|
||||
variant("cuda", default=False, description="Build with CUDA")
|
||||
variant("cuda_arch", values=any_combination_of("10", "11"), when="+cuda")
|
|
@ -0,0 +1,23 @@
|
|||
# Copyright 2013-2024 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.package import *
|
||||
|
||||
|
||||
class ForwardMultiValue(Package):
|
||||
"""A package that forwards the value of a multi-valued variant to a dependency"""
|
||||
|
||||
homepage = "http://www.llnl.gov"
|
||||
url = "http://www.llnl.gov/mpileaks-1.0.tar.gz"
|
||||
|
||||
version("1.0", md5="0123456789abcdef0123456789abcdef")
|
||||
|
||||
variant("cuda", default=False, description="Build with CUDA")
|
||||
variant("cuda_arch", values=any_combination_of("10", "11"), when="+cuda")
|
||||
|
||||
depends_on("dependency-mv")
|
||||
|
||||
requires("^dependency-mv cuda_arch=10", when="+cuda cuda_arch=10 ^dependency-mv+cuda")
|
||||
requires("^dependency-mv cuda_arch=11", when="+cuda cuda_arch=11 ^dependency-mv+cuda")
|
Loading…
Reference in a new issue