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).
This commit is contained in:
Massimiliano Culpo 2021-04-21 10:02:43 +02:00 committed by GitHub
parent 9a473d6ab3
commit 3325eff486
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 26 additions and 32 deletions

View File

@ -603,32 +603,19 @@ node_compiler_version(Package, Compiler, Version) :- node_compiler_version_set(P
not compiler_supports_os(Compiler, Version, OS), not compiler_supports_os(Compiler, Version, OS),
not allow_compiler(Compiler, Version). not allow_compiler(Compiler, Version).
% If the compiler is what was prescribed from command line etc. % If a package and one of its dependencies don't have the
% or is the same as a root node, there is a version match % 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 prescribed in the root spec compiler_mismatch(Package, Dependency)
node_compiler_version_match_pref(Package, Compiler, V) :- depends_on(Package, Dependency),
:- node_compiler_set(Package, Compiler), node_compiler_version(Package, Compiler, Version1),
node_compiler_version(Package, Compiler, V), node_compiler_version(Dependency, Compiler, Version2),
not external(Package). Version1 != Version2.
% 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).
compiler_version_match(Package, 1)
:- node_compiler_version(Package, Compiler, V),
node_compiler_version_match_pref(Package, Compiler, V).
#defined node_compiler_set/2. #defined node_compiler_set/2.
#defined node_compiler_version_set/3. #defined node_compiler_version_set/3.
@ -772,14 +759,10 @@ opt_criterion(8, "count of non-root multi-valued variants").
not root(Package) not root(Package)
}. }.
% Try to maximize the number of compiler matches in the DAG, % Try to minimize the number of compiler mismatches in the DAG.
% while minimizing the number of nodes. This is done because opt_criterion(7, "compiler mismatches").
% a maximization on the number of matches for compilers is highly
% correlated to a preference to have as many nodes as possible
opt_criterion(7, "compiler matches + number of nodes").
#minimize{ 0@7 : #true }. #minimize{ 0@7 : #true }.
#minimize{ 1@7,Package : node(Package) }. #minimize{ 1@7,Package,Dependency : compiler_mismatch(Package, Dependency) }.
#maximize{ Weight@7,Package : compiler_version_match(Package, Weight) }.
% Choose more recent versions for nodes % Choose more recent versions for nodes
opt_criterion(6, "version badness"). opt_criterion(6, "version badness").

View File

@ -1199,3 +1199,14 @@ def test_os_selection_when_multiple_choices_are_possible(
for node in s.traverse(): for node in s.traverse():
assert node.satisfies(expected_os) 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)