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
					Massimiliano Culpo
				
			
				
					committed by
					
						 Todd Gamblin
						Todd Gamblin
					
				
			
			
				
	
			
			
			 Todd Gamblin
						Todd Gamblin
					
				
			
						parent
						
							30dd61264a
						
					
				
				
					commit
					76c5a02125
				
			| @@ -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: | ||||
|   | ||||
| @@ -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 | ||||
| % 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 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). | ||||
|  | ||||
| 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{ | ||||
|   | ||||
| @@ -1171,3 +1171,14 @@ def test_os_selection_when_multiple_choices_are_possible( | ||||
| 
 | ||||
|         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) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user