diff options
author | Massimiliano Culpo <massimiliano.culpo@gmail.com> | 2024-01-16 11:50:33 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-01-16 11:50:33 +0100 |
commit | f0c69ff3bfbb0edcc22e7058091d529b979cef75 (patch) | |
tree | dd690a231338e6adce356b68134e2e03614bb18c /lib | |
parent | ddae696cf8f2a130773f9b21490c95ed7a30b5c4 (diff) | |
download | spack-f0c69ff3bfbb0edcc22e7058091d529b979cef75.tar.gz spack-f0c69ff3bfbb0edcc22e7058091d529b979cef75.tar.bz2 spack-f0c69ff3bfbb0edcc22e7058091d529b979cef75.tar.xz spack-f0c69ff3bfbb0edcc22e7058091d529b979cef75.zip |
Fix a bug when a required provider is requested for multiple virtuals (#42088)
Diffstat (limited to 'lib')
-rw-r--r-- | lib/spack/spack/solver/asp.py | 7 | ||||
-rw-r--r-- | lib/spack/spack/solver/concretize.lp | 12 | ||||
-rw-r--r-- | lib/spack/spack/test/concretize_requirements.py | 23 |
3 files changed, 39 insertions, 3 deletions
diff --git a/lib/spack/spack/solver/asp.py b/lib/spack/spack/solver/asp.py index bc9a3e2fd7..7df2e0ff8a 100644 --- a/lib/spack/spack/solver/asp.py +++ b/lib/spack/spack/solver/asp.py @@ -1747,9 +1747,10 @@ class SpackSolverSetup: rules = self._rules_from_requirements( virtual_str, requirements, kind=RequirementKind.VIRTUAL ) - self.emit_facts_from_requirement_rules(rules) - self.trigger_rules() - self.effect_rules() + if rules: + self.emit_facts_from_requirement_rules(rules) + self.trigger_rules() + self.effect_rules() def emit_facts_from_requirement_rules(self, rules: List[RequirementRule]): """Generate facts to enforce requirements. diff --git a/lib/spack/spack/solver/concretize.lp b/lib/spack/spack/solver/concretize.lp index c56f2bcc66..c8d96eed9c 100644 --- a/lib/spack/spack/solver/concretize.lp +++ b/lib/spack/spack/solver/concretize.lp @@ -698,6 +698,18 @@ requirement_group_satisfied(node(ID, Package), X) :- activate_requirement(node(ID, Package), X), requirement_group(Package, X). +% 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 +required_provider(Provider, Virtual) + :- requirement_group_member(ConditionID, Virtual, RequirementID), + condition_holds(ConditionID, _), + virtual(Virtual), + pkg_fact(Virtual, condition_effect(ConditionID, EffectID)), + imposed_constraint(EffectID, "node", Provider). + +:- provider(node(Y, Package), node(X, Virtual)), required_provider(Provider, Virtual), Package != Provider. + % TODO: the following two choice rules allow the solver to add compiler % flags if their only source is from a requirement. This is overly-specific % and should use a more-generic approach like in https://github.com/spack/spack/pull/37180 diff --git a/lib/spack/spack/test/concretize_requirements.py b/lib/spack/spack/test/concretize_requirements.py index 7b8f825eae..3a6b2b75c4 100644 --- a/lib/spack/spack/test/concretize_requirements.py +++ b/lib/spack/spack/test/concretize_requirements.py @@ -1012,3 +1012,26 @@ def test_default_requirements_semantic_with_mv_variants( for constraint in not_expected: assert not s.satisfies(constraint), constraint + + +@pytest.mark.regression("42084") +def test_requiring_package_on_multiple_virtuals(concretize_scope, mock_packages): + update_packages_config( + """ + packages: + all: + providers: + scalapack: [netlib-scalapack] + blas: + require: intel-parallel-studio + lapack: + require: intel-parallel-studio + scalapack: + require: intel-parallel-studio + """ + ) + s = Spec("dla-future").concretized() + + assert s["blas"].name == "intel-parallel-studio" + assert s["lapack"].name == "intel-parallel-studio" + assert s["scalapack"].name == "intel-parallel-studio" |