concretizer: generate facts for externals
Generate only facts for external specs. Substitute the use of already grounded rules with non-grounded rules in concretize.lp
This commit is contained in:
		 Massimiliano Culpo
					Massimiliano Culpo
				
			
				
					committed by
					
						 Tamara Dahlgren
						Tamara Dahlgren
					
				
			
			
				
	
			
			
			 Tamara Dahlgren
						Tamara Dahlgren
					
				
			
						parent
						
							f7195123d4
						
					
				
				
					commit
					ec42016241
				
			| @@ -793,9 +793,6 @@ def external_packages(self): | |||||||
|             if pkg_name not in spack.repo.path: |             if pkg_name not in spack.repo.path: | ||||||
|                 continue |                 continue | ||||||
| 
 | 
 | ||||||
|             if 'externals' not in data: |  | ||||||
|                 self.gen.fact(fn.external(pkg_name).symbol(positive=False)) |  | ||||||
| 
 |  | ||||||
|             self.gen.h2('External package: {0}'.format(pkg_name)) |             self.gen.h2('External package: {0}'.format(pkg_name)) | ||||||
|             # Check if the external package is buildable. If it is |             # Check if the external package is buildable. If it is | ||||||
|             # not then "external(<pkg>)" is a fact. |             # not then "external(<pkg>)" is a fact. | ||||||
| @@ -807,52 +804,40 @@ def external_packages(self): | |||||||
|             externals = data.get('externals', []) |             externals = data.get('externals', []) | ||||||
|             external_specs = [spack.spec.Spec(x['spec']) for x in externals] |             external_specs = [spack.spec.Spec(x['spec']) for x in externals] | ||||||
| 
 | 
 | ||||||
|             # Compute versions with appropriate weights |             # Compute versions with appropriate weights. This accounts for the | ||||||
|  |             # fact that we should prefer more recent versions, but specs in | ||||||
|  |             # packages.yaml may not be ordered in that sense. | ||||||
|             external_versions = [ |             external_versions = [ | ||||||
|                 (x.version, idx) for idx, x in enumerate(external_specs) |                 (x.version, local_idx) | ||||||
|  |                 for local_idx, x in enumerate(external_specs) | ||||||
|             ] |             ] | ||||||
|             external_versions = [ |             external_versions = [ | ||||||
|                 (v, -(w + 1), idx) |                 (v, -(w + 1), local_idx) | ||||||
|                 for w, (v, idx) in enumerate(sorted(external_versions)) |                 for w, (v, local_idx) in enumerate(sorted(external_versions)) | ||||||
|             ] |             ] | ||||||
|             for version, weight, id in external_versions: |             for version, weight, id in external_versions: | ||||||
|                 self.gen.fact(fn.external_version_declared( |                 self.gen.fact(fn.external_version_declared( | ||||||
|                     pkg_name, str(version), weight, id |                     pkg_name, str(version), weight, id | ||||||
|                 )) |                 )) | ||||||
| 
 | 
 | ||||||
|             # Establish an equivalence between "external_spec(pkg, id)" |             for local_idx, spec in enumerate(external_specs): | ||||||
|             # and the clauses of that spec, so that we have a uniform |                 global_id = self._condition_id_counter | ||||||
|             # way to identify it |                 self._condition_id_counter += 1 | ||||||
|             spec_id_list = [] | 
 | ||||||
|             for id, spec in enumerate(external_specs): |                 # Declare the global ID associated with this external spec | ||||||
|                 self.gen.newline() |                 self.gen.fact(fn.external_spec(global_id, pkg_name)) | ||||||
|                 spec_id = fn.external_spec(pkg_name, id) | 
 | ||||||
|  |                 # Local index into packages.yaml | ||||||
|  |                 self.gen.fact(fn.external_spec_index(global_id, pkg_name, local_idx)) | ||||||
|  | 
 | ||||||
|  |                 # Add conditions to be satisfied for this external | ||||||
|                 self.possible_versions[spec.name].add(spec.version) |                 self.possible_versions[spec.name].add(spec.version) | ||||||
|                 clauses = self.spec_clauses(spec, body=True) |                 clauses = self.spec_clauses(spec, body=True) | ||||||
|                 # This is an iff below, wish it could be written in a |  | ||||||
|                 # more compact form |  | ||||||
|                 self.gen.rule(head=spec_id.symbol(), body=AspAnd(*clauses)) |  | ||||||
|                 for clause in clauses: |                 for clause in clauses: | ||||||
|                     self.gen.rule(clause, spec_id.symbol()) |                     self.gen.fact( | ||||||
|                 spec_id_list.append(spec_id) |                         fn.external_spec_condition(global_id, clause.name, *clause.args) | ||||||
| 
 |  | ||||||
|             # TODO: find another way to do everything below, without |  | ||||||
|             # TODO: generating ground rules. |  | ||||||
| 
 |  | ||||||
|             # If one of the external specs is selected then the package |  | ||||||
|             # is external and viceversa |  | ||||||
|             # TODO: make it possible to declare the rule like below |  | ||||||
|             # self.gen.iff(expr1=fn.external(pkg_name), |  | ||||||
|             #              expr2=one_of_the_externals) |  | ||||||
|             self.gen.newline() |  | ||||||
|             # FIXME: self.gen.one_of_iff(fn.external(pkg_name), spec_id_list) |  | ||||||
|             one_of_the_externals = self.gen.one_of(*spec_id_list) |  | ||||||
|             external_str = fn.external(pkg_name) |  | ||||||
|             external_rule = "{0} :- {1}.\n{1} :- {0}.\n".format( |  | ||||||
|                 external_str, str(one_of_the_externals) |  | ||||||
|                     ) |                     ) | ||||||
|             self.gen.out.write(external_rule) |                 self.gen.newline() | ||||||
|             self.gen.control.add("base", [], external_rule) |  | ||||||
| 
 | 
 | ||||||
|     def preferred_variants(self, pkg_name): |     def preferred_variants(self, pkg_name): | ||||||
|         """Facts on concretization preferences, as read from packages.yaml""" |         """Facts on concretization preferences, as read from packages.yaml""" | ||||||
| @@ -1514,7 +1499,7 @@ def node_flag_source(self, pkg, source): | |||||||
|     def no_flags(self, pkg, flag_type): |     def no_flags(self, pkg, flag_type): | ||||||
|         self._specs[pkg].compiler_flags[flag_type] = [] |         self._specs[pkg].compiler_flags[flag_type] = [] | ||||||
| 
 | 
 | ||||||
|     def external_spec(self, pkg, idx): |     def external_spec_selected(self, global_id, pkg, idx): | ||||||
|         """This means that the external spec and index idx |         """This means that the external spec and index idx | ||||||
|         has been selected for this package. |         has been selected for this package. | ||||||
|         """ |         """ | ||||||
|   | |||||||
| @@ -258,9 +258,25 @@ external(Package) :- | |||||||
|     version(Package, Version), version_weight(Package, Weight), |     version(Package, Version), version_weight(Package, Weight), | ||||||
|     external_version_declared(Package, Version, Weight, ID). |     external_version_declared(Package, Version, Weight, ID). | ||||||
|  |  | ||||||
| external_spec(Package, ID) :- | % determine if an external spec has been selected | ||||||
|  | external_spec_selected(ID, Package, LocalIndex) :- | ||||||
|     version(Package, Version), version_weight(Package, Weight), |     version(Package, Version), version_weight(Package, Weight), | ||||||
|     external_version_declared(Package, Version, Weight, ID). |     external_spec_index(ID, Package, LocalIndex), | ||||||
|  |     external_version_declared(Package, Version, Weight, LocalIndex), | ||||||
|  |     external_spec_conditions_hold(ID, Package). | ||||||
|  |  | ||||||
|  | % determine if all the conditions on an external spec hold. If they do | ||||||
|  | % the spec can be selected. | ||||||
|  | external_spec_conditions_hold(ID, Package) :- | ||||||
|  |   attr(Name, Arg1)             : external_spec_condition(ID, Name, Arg1); | ||||||
|  |   attr(Name, Arg1, Arg2)       : external_spec_condition(ID, Name, Arg1, Arg2); | ||||||
|  |   attr(Name, Arg1, Arg2, Arg3) : external_spec_condition(ID, Name, Arg1, Arg2, Arg3); | ||||||
|  |   external_spec(ID, Package); | ||||||
|  |   node(Package). | ||||||
|  |  | ||||||
|  | % it cannot happen that a spec is external, but none of the external specs | ||||||
|  | % conditions hold. | ||||||
|  | :- external(Package), not external_spec_conditions_hold(_, Package). | ||||||
|  |  | ||||||
| %----------------------------------------------------------------------------- | %----------------------------------------------------------------------------- | ||||||
| % Variant semantics | % Variant semantics | ||||||
|   | |||||||
| @@ -24,4 +24,4 @@ | |||||||
| #show compiler_weight/2. | #show compiler_weight/2. | ||||||
| #show node_target_match/2. | #show node_target_match/2. | ||||||
| #show node_target_weight/2. | #show node_target_weight/2. | ||||||
| #show external_spec/2. | #show external_spec_selected/3. | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user