ASP-based solver: fix for unsplittable providers (#40859)

Some providers must provide virtuals "together", i.e.
if they provide one virtual of a set, they must be the
providers also of the others.

There was a bug though, where we were not checking if
the other virtuals in the set were needed at all in
the DAG.

This commit fixes the bug.
This commit is contained in:
Massimiliano Culpo 2023-11-03 12:56:37 +01:00 committed by GitHub
parent 3082ce6a22
commit db16335aec
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 57 additions and 1 deletions

View file

@ -492,7 +492,9 @@ error(100, "Package '{0}' needs to provide both '{1}' and '{2}' together, but pr
pkg_fact(Package, provided_together(ID, SetID, Virtual2)),
Virtual1 != Virtual2,
attr("virtual_on_incoming_edges", node(X, Package), Virtual1),
not attr("virtual_on_incoming_edges", node(X, Package), Virtual2).
not attr("virtual_on_incoming_edges", node(X, Package), Virtual2),
attr("virtual_node", node(_, Virtual1)),
attr("virtual_node", node(_, Virtual2)).
% if a package depends on a virtual, it's not external and we have a
% provider for that virtual then it depends on the provider

View file

@ -2360,3 +2360,16 @@ def test_condition_triggered_by_edge_property(
for not_expected in expected_not_satisfies:
assert not s.satisfies(not_expected), str(not_expected)
def test_virtuals_provided_together_but_only_one_required_in_dag(self):
"""Tests that we can use a provider that provides more than one virtual together,
and is providing only one, iff the others are not needed in the DAG.
o blas-only-client
| [virtual=blas]
o openblas (provides blas and lapack together)
"""
s = Spec("blas-only-client ^openblas").concretized()
assert s.satisfies("^[virtuals=blas] openblas")
assert not s.satisfies("^[virtuals=blas,lapack] openblas")

View file

@ -0,0 +1,19 @@
# Copyright 2013-2023 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 BlasOnlyClient(Package):
"""This package depends on the 'blas' virtual only, but should be able to use also provider
that provide e.g. 'blas' together with 'lapack'.
"""
homepage = "http://www.openblas.net"
url = "http://github.com/xianyi/OpenBLAS/archive/v0.2.15.tar.gz"
version("0.2.16", md5="b1190f3d3471685f17cfd1ec1d252ac9")
depends_on("blas")

View file

@ -0,0 +1,22 @@
# Copyright 2013-2023 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 Openblas(Package):
"""This package provides two virtuals together, so if one is chosen the other
must be used too if needed.
"""
homepage = "http://www.openblas.net"
url = "http://github.com/xianyi/OpenBLAS/archive/v0.2.15.tar.gz"
version("0.2.16", md5="b1190f3d3471685f17cfd1ec1d252ac9")
version("0.2.15", md5="b1190f3d3471685f17cfd1ec1d252ac9")
version("0.2.14", md5="b1190f3d3471685f17cfd1ec1d252ac9")
version("0.2.13", md5="b1190f3d3471685f17cfd1ec1d252ac9")
provides("blas", "lapack")