From 76c5a02125b31a7d50dab10a51d526c8594aefb6 Mon Sep 17 00:00:00 2001 From: Massimiliano Culpo Date: Wed, 21 Apr 2021 10:02:43 +0200 Subject: ASP-based solve: minimize compiler mismatches (#23016) fixes #22718 Instead of trying to maximize the number of matches (preferred behavior), try to minimize the number of mismatches (unwanted behavior). --- lib/spack/spack/concretize.py | 2 +- lib/spack/spack/solver/concretize.lp | 47 ++++++++++++------------------------ lib/spack/spack/test/concretize.py | 11 +++++++++ 3 files changed, 28 insertions(+), 32 deletions(-) diff --git a/lib/spack/spack/concretize.py b/lib/spack/spack/concretize.py index 7c00b4dd55..48210f0959 100644 --- a/lib/spack/spack/concretize.py +++ b/lib/spack/spack/concretize.py @@ -714,7 +714,7 @@ def _compiler_concretization_failure(compiler_spec, arch): raise UnavailableCompilerVersionError(compiler_spec, arch) -def concretize_specs_together(*abstract_specs): +def concretize_specs_together(*abstract_specs, **kwargs): """Given a number of specs as input, tries to concretize them together. Args: diff --git a/lib/spack/spack/solver/concretize.lp b/lib/spack/spack/solver/concretize.lp index 3d250ac821..145c00ab67 100644 --- a/lib/spack/spack/solver/concretize.lp +++ b/lib/spack/spack/solver/concretize.lp @@ -597,36 +597,24 @@ node_compiler_version(Package, Compiler, Version) :- node_compiler_version_set(P not compiler_supports_os(Compiler, Version, OS), not allow_compiler(Compiler, Version). -% If the compiler is what was prescribed from command line etc. -% or is the same as a root node, there is a version match - -% Compiler prescribed in the root spec -node_compiler_version_match_pref(Package, Compiler, V) - :- node_compiler_set(Package, Compiler), - node_compiler_version(Package, Compiler, V), - not external(Package). - -% Compiler inherited from a parent node -node_compiler_version_match_pref(Dependency, Compiler, V) - :- depends_on(Package, Dependency), - node_compiler_version_match_pref(Package, Compiler, V), - node_compiler_version(Dependency, Compiler, V), - not node_compiler_set(Dependency, Compiler). - -% Compiler inherited from the root package -node_compiler_version_match_pref(Dependency, Compiler, V) - :- depends_on(Package, Dependency), - node_compiler_version(Package, Compiler, V), root(Package), - node_compiler_version(Dependency, Compiler, V), - not node_compiler_set(Dependency, Compiler). +% If a package and one of its dependencies don't have the +% same compiler there's a mismatch. +compiler_mismatch(Package, Dependency) + :- depends_on(Package, Dependency), + node_compiler_version(Package, Compiler1, _), + node_compiler_version(Dependency, Compiler2, _), + Compiler1 != Compiler2. -compiler_version_match(Package, 1) - :- node_compiler_version(Package, Compiler, V), - node_compiler_version_match_pref(Package, Compiler, V). +compiler_mismatch(Package, Dependency) + :- depends_on(Package, Dependency), + node_compiler_version(Package, Compiler, Version1), + node_compiler_version(Dependency, Compiler, Version2), + Version1 != Version2. #defined node_compiler_set/2. #defined node_compiler_version_set/3. #defined compiler_supports_os/3. +#defined compiler_version_match/2. #defined allow_compiler/2. % compilers weighted by preference according to packages.yaml @@ -766,12 +754,9 @@ root(Dependency, 1) :- not root(Dependency), node(Dependency). not root(Package) }. -% Try to maximize the number of compiler matches in the DAG, -% while minimizing the number of nodes. This is done because -% a maximization on the number of matches for compilers is highly -% correlated to a preference to have as many nodes as possible -#minimize{ 1@7,Package : node(Package) }. -#maximize{ Weight@7,Package : compiler_version_match(Package, Weight) }. +% Try to minimize the number of compiler mismatches in the DAG. +#minimize{ 0@7 : #true }. +#minimize{ 1@7,Package,Dependency : compiler_mismatch(Package, Dependency) }. % Choose more recent versions for nodes #minimize{ diff --git a/lib/spack/spack/test/concretize.py b/lib/spack/spack/test/concretize.py index 56e111e220..6f87381e3f 100644 --- a/lib/spack/spack/test/concretize.py +++ b/lib/spack/spack/test/concretize.py @@ -1171,3 +1171,14 @@ class TestConcretize(object): for node in s.traverse(): assert node.satisfies(expected_os) + + @pytest.mark.regression('22718') + @pytest.mark.parametrize('spec_str,expected_compiler', [ + ('mpileaks', '%gcc@4.5.0'), + ('mpileaks ^mpich%clang@3.3', '%clang@3.3') + ]) + def test_compiler_is_unique(self, spec_str, expected_compiler): + s = Spec(spec_str).concretized() + + for node in s.traverse(): + assert node.satisfies(expected_compiler) -- cgit v1.2.3-70-g09d2