diff options
author | Massimiliano Culpo <massimiliano.culpo@gmail.com> | 2024-02-09 20:50:04 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-02-09 20:50:04 +0100 |
commit | 7ff3b17f14e7d0c2033589e8b3e2f2afaa87c784 (patch) | |
tree | 1b04f071ee21265c29d92beb82003dc5d05ac2d0 /lib | |
parent | f71669175fb7f84052503e8cad955edc30f703df (diff) | |
download | spack-7ff3b17f14e7d0c2033589e8b3e2f2afaa87c784.tar.gz spack-7ff3b17f14e7d0c2033589e8b3e2f2afaa87c784.tar.bz2 spack-7ff3b17f14e7d0c2033589e8b3e2f2afaa87c784.tar.xz spack-7ff3b17f14e7d0c2033589e8b3e2f2afaa87c784.zip |
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.
Diffstat (limited to 'lib')
-rw-r--r-- | lib/spack/spack/solver/concretize.lp | 8 | ||||
-rw-r--r-- | lib/spack/spack/test/concretize_requirements.py | 43 |
2 files changed, 51 insertions, 0 deletions
diff --git a/lib/spack/spack/solver/concretize.lp b/lib/spack/spack/solver/concretize.lp index c8d96eed9c..7f06d6f3a9 100644 --- a/lib/spack/spack/solver/concretize.lp +++ b/lib/spack/spack/solver/concretize.lp @@ -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 diff --git a/lib/spack/spack/test/concretize_requirements.py b/lib/spack/spack/test/concretize_requirements.py index 3ef143fd36..ea1dc526df 100644 --- a/lib/spack/spack/test/concretize_requirements.py +++ b/lib/spack/spack/test/concretize_requirements.py @@ -1133,3 +1133,46 @@ def test_conflict_packages_yaml(packages_yaml, spec_str, concretize_scope, mock_ update_packages_config(packages_yaml) with pytest.raises(UnsatisfiableSpecError): Spec(spec_str).concretized() + + +@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) |