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(
|
||||
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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -896,3 +896,26 @@ def test_requires_directive(concretize_scope, mock_packages):
|
|||
# This package can only be compiled with clang
|
||||
with pytest.raises(spack.error.SpackError, match="can only be compiled with Clang"):
|
||||
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