Fix a bug when a required provider is requested for multiple virtuals (#42088)
This commit is contained in:
parent
9af5eca9ec
commit
b23a829c4c
4 changed files with 60 additions and 3 deletions
|
@ -1676,9 +1676,10 @@ def provider_requirements(self):
|
||||||
rules = self._rules_from_requirements(
|
rules = self._rules_from_requirements(
|
||||||
virtual_str, requirements, kind=RequirementKind.VIRTUAL
|
virtual_str, requirements, kind=RequirementKind.VIRTUAL
|
||||||
)
|
)
|
||||||
self.emit_facts_from_requirement_rules(rules)
|
if rules:
|
||||||
self.trigger_rules()
|
self.emit_facts_from_requirement_rules(rules)
|
||||||
self.effect_rules()
|
self.trigger_rules()
|
||||||
|
self.effect_rules()
|
||||||
|
|
||||||
def emit_facts_from_requirement_rules(self, rules: List[RequirementRule]):
|
def emit_facts_from_requirement_rules(self, rules: List[RequirementRule]):
|
||||||
"""Generate facts to enforce requirements.
|
"""Generate facts to enforce requirements.
|
||||||
|
|
|
@ -698,6 +698,18 @@ requirement_group_satisfied(node(ID, Package), X) :-
|
||||||
activate_requirement(node(ID, Package), X),
|
activate_requirement(node(ID, Package), X),
|
||||||
requirement_group(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
|
% 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
|
% 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
|
% and should use a more-generic approach like in https://github.com/spack/spack/pull/37180
|
||||||
|
|
|
@ -896,3 +896,26 @@ def test_requires_directive(concretize_scope, mock_packages):
|
||||||
# This package can only be compiled with clang
|
# This package can only be compiled with clang
|
||||||
with pytest.raises(spack.error.SpackError, match="can only be compiled with Clang"):
|
with pytest.raises(spack.error.SpackError, match="can only be compiled with Clang"):
|
||||||
Spec("requires_clang").concretized()
|
Spec("requires_clang").concretized()
|
||||||
|
|
||||||
|
|
||||||
|
@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"
|
||||||
|
|
21
var/spack/repos/builtin.mock/packages/dla-future/package.py
Normal file
21
var/spack/repos/builtin.mock/packages/dla-future/package.py
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
# 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 DlaFuture(Package):
|
||||||
|
"""A package that depends on 3 different virtuals, that might or might not be provided
|
||||||
|
by the same node.
|
||||||
|
"""
|
||||||
|
|
||||||
|
homepage = "http://www.example.com"
|
||||||
|
url = "http://www.example.com/dla-1.0.tar.gz"
|
||||||
|
|
||||||
|
version("1.0", md5="0123456789abcdef0123456789abcdef")
|
||||||
|
|
||||||
|
depends_on("blas")
|
||||||
|
depends_on("lapack")
|
||||||
|
depends_on("scalapack")
|
Loading…
Reference in a new issue