summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMassimiliano Culpo <massimiliano.culpo@gmail.com>2022-06-21 02:32:13 +0200
committerMassimiliano Culpo <massimiliano.culpo@gmail.com>2022-07-20 08:10:41 +0200
commit53cb6312a84c3e310adcdaa4c531b5b86db88819 (patch)
treec327ce6d7a12af9d7b4275929df65c4c112a42fa
parent7371fef3cac885eb71bb25d6826ec6f0d45bb429 (diff)
downloadspack-53cb6312a84c3e310adcdaa4c531b5b86db88819.tar.gz
spack-53cb6312a84c3e310adcdaa4c531b5b86db88819.tar.bz2
spack-53cb6312a84c3e310adcdaa4c531b5b86db88819.tar.xz
spack-53cb6312a84c3e310adcdaa4c531b5b86db88819.zip
Stricter compatibility rules for OS and compiler when reusing specs (#31170)
* Stricter compatibility rules for OS and compiler when reusing specs * Add unit test
-rw-r--r--lib/spack/spack/solver/asp.py1
-rw-r--r--lib/spack/spack/solver/concretize.lp15
-rw-r--r--lib/spack/spack/solver/os_facts.lp22
-rw-r--r--lib/spack/spack/test/concretize.py22
4 files changed, 57 insertions, 3 deletions
diff --git a/lib/spack/spack/solver/asp.py b/lib/spack/spack/solver/asp.py
index d9b8fae725..3b475c2c77 100644
--- a/lib/spack/spack/solver/asp.py
+++ b/lib/spack/spack/solver/asp.py
@@ -631,6 +631,7 @@ class PyclingoDriver(object):
# Load the file itself
self.control.load(os.path.join(parent_dir, 'concretize.lp'))
+ self.control.load(os.path.join(parent_dir, "os_facts.lp"))
self.control.load(os.path.join(parent_dir, "display.lp"))
timer.phase("load")
diff --git a/lib/spack/spack/solver/concretize.lp b/lib/spack/spack/solver/concretize.lp
index 94a4bedcfe..6f767e317c 100644
--- a/lib/spack/spack/solver/concretize.lp
+++ b/lib/spack/spack/solver/concretize.lp
@@ -737,9 +737,14 @@ node_os_mismatch(Package, Dependency) :-
% every OS is compatible with itself. We can use `os_compatible` to declare
os_compatible(OS, OS) :- os(OS).
-% OS compatibility rules for reusing solves.
-% catalina binaries can be used on bigsur. Direction is package -> dependency.
-os_compatible("bigsur", "catalina").
+% Transitive compatibility among operating systems
+os_compatible(OS1, OS3) :- os_compatible(OS1, OS2), os_compatible(OS2, OS3).
+
+% We can select only operating systems compatible with the ones
+% for which we can build software. We need a cardinality constraint
+% since we might have more than one "buildable_os(OS)" fact.
+:- not 1 { os_compatible(CurrentOS, ReusedOS) : buildable_os(CurrentOS) },
+ node_os(Package, ReusedOS).
% If an OS is set explicitly respect the value
node_os(Package, OS) :- node_os_set(Package, OS), node(Package).
@@ -961,6 +966,9 @@ compiler_weight(Package, 100)
not node_compiler_preference(Package, Compiler, Version, _),
not default_compiler_preference(Compiler, Version, _).
+% For the time being, be strict and reuse only if the compiler match one we have on the system
+:- node_compiler_version(Package, Compiler, Version), not compiler_version(Compiler, Version).
+
#defined node_compiler_preference/4.
#defined default_compiler_preference/3.
@@ -1269,6 +1277,7 @@ opt_criterion(1, "non-preferred targets").
#heuristic variant_value(Package, Variant, Value) : variant_default_value(Package, Variant, Value), node(Package). [10, true]
#heuristic provider(Package, Virtual) : possible_provider_weight(Package, Virtual, 0, _), virtual_node(Virtual). [10, true]
#heuristic node(Package) : possible_provider_weight(Package, Virtual, 0, _), virtual_node(Virtual). [10, true]
+#heuristic node_os(Package, OS) : buildable_os(OS). [10, true]
%-----------
% Notes
diff --git a/lib/spack/spack/solver/os_facts.lp b/lib/spack/spack/solver/os_facts.lp
new file mode 100644
index 0000000000..e3d322b8f6
--- /dev/null
+++ b/lib/spack/spack/solver/os_facts.lp
@@ -0,0 +1,22 @@
+% Copyright 2013-2022 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)
+
+% OS compatibility rules for reusing solves.
+% os_compatible(RecentOS, OlderOS)
+% OlderOS binaries can be used on RecentOS
+
+% macOS
+os_compatible("monterey", "bigsur").
+os_compatible("bigsur", "catalina").
+
+% Ubuntu
+os_compatible("ubuntu22.04", "ubuntu21.10").
+os_compatible("ubuntu21.10", "ubuntu21.04").
+os_compatible("ubuntu21.04", "ubuntu20.10").
+os_compatible("ubuntu20.10", "ubuntu20.04").
+os_compatible("ubuntu20.04", "ubuntu19.10").
+os_compatible("ubuntu19.10", "ubuntu19.04").
+os_compatible("ubuntu19.04", "ubuntu18.10").
+os_compatible("ubuntu18.10", "ubuntu18.04").
diff --git a/lib/spack/spack/test/concretize.py b/lib/spack/spack/test/concretize.py
index ceb72078e6..25728a0c13 100644
--- a/lib/spack/spack/test/concretize.py
+++ b/lib/spack/spack/test/concretize.py
@@ -1786,3 +1786,25 @@ class TestConcretize(object):
]:
assert criterion in result.criteria
assert result.specs[0].satisfies('^b@1.0')
+
+ @pytest.mark.regression('31169')
+ def test_not_reusing_incompatible_os_or_compiler(self):
+ import spack.solver.asp
+ if spack.config.get('config:concretizer') == 'original':
+ pytest.skip('Original concretizer cannot reuse')
+
+ root_spec = spack.spec.Spec('b')
+ s = root_spec.concretized()
+ wrong_compiler, wrong_os = s.copy(), s.copy()
+ wrong_compiler.compiler = spack.spec.CompilerSpec('gcc@12.1.0')
+ wrong_os.architecture = spack.spec.ArchSpec('test-ubuntu2204-x86_64')
+ reusable_specs = [wrong_compiler, wrong_os]
+ with spack.config.override("concretizer:reuse", True):
+ solver = spack.solver.asp.Solver()
+ setup = spack.solver.asp.SpackSolverSetup()
+ result = solver.driver.solve(
+ setup, [root_spec], reuse=reusable_specs, out=sys.stdout
+ )
+ concrete_spec = result.specs[0]
+ assert concrete_spec.satisfies('%gcc@4.5.0')
+ assert concrete_spec.satisfies('os=debian6')