Memoize a few hot functions during module file generation (#37739)
This commit is contained in:
		 Massimiliano Culpo
					Massimiliano Culpo
				
			
				
					committed by
					
						 GitHub
						GitHub
					
				
			
			
				
	
			
			
			 GitHub
						GitHub
					
				
			
						parent
						
							cd27611d2f
						
					
				
				
					commit
					42667fe7fa
				
			| @@ -170,11 +170,9 @@ def merge_config_rules(configuration, spec): | ||||
|     Returns: | ||||
|         dict: actions to be taken on the spec passed as an argument | ||||
|     """ | ||||
|     # Construct a dictionary with the actions we need to perform on the spec passed as a parameter | ||||
|     spec_configuration = {} | ||||
|     # The keyword 'all' is always evaluated first, all the others are | ||||
|     # evaluated in order of appearance in the module file | ||||
|     spec_configuration.update(copy.deepcopy(configuration.get("all", {}))) | ||||
|     spec_configuration = copy.deepcopy(configuration.get("all", {})) | ||||
|     for constraint, action in configuration.items(): | ||||
|         if spec.satisfies(constraint): | ||||
|             if hasattr(constraint, "override") and constraint.override: | ||||
|   | ||||
| @@ -134,6 +134,7 @@ def filter_hierarchy_specs(self): | ||||
|         return configuration(self.name).get("filter_hierarchy_specs", {}) | ||||
| 
 | ||||
|     @property | ||||
|     @lang.memoized | ||||
|     def hierarchy_tokens(self): | ||||
|         """Returns the list of tokens that are part of the modulefile | ||||
|         hierarchy. 'compiler' is always present. | ||||
| @@ -158,6 +159,7 @@ def hierarchy_tokens(self): | ||||
|         return tokens | ||||
| 
 | ||||
|     @property | ||||
|     @lang.memoized | ||||
|     def requires(self): | ||||
|         """Returns a dictionary mapping all the requirements of this spec | ||||
|         to the actual provider. 'compiler' is always present among the | ||||
| @@ -224,6 +226,7 @@ def available(self): | ||||
|         return available | ||||
| 
 | ||||
|     @property | ||||
|     @lang.memoized | ||||
|     def missing(self): | ||||
|         """Returns the list of tokens that are not available.""" | ||||
|         return [x for x in self.hierarchy_tokens if x not in self.available] | ||||
| @@ -317,6 +320,7 @@ def available_path_parts(self): | ||||
|         return parts | ||||
| 
 | ||||
|     @property | ||||
|     @lang.memoized | ||||
|     def unlocked_paths(self): | ||||
|         """Returns a dictionary mapping conditions to a list of unlocked | ||||
|         paths. | ||||
| @@ -428,6 +432,7 @@ def missing(self): | ||||
|         return self.conf.missing | ||||
| 
 | ||||
|     @tengine.context_property | ||||
|     @lang.memoized | ||||
|     def unlocked_paths(self): | ||||
|         """Returns the list of paths that are unlocked unconditionally.""" | ||||
|         layout = make_layout(self.spec, self.conf.name, self.conf.explicit) | ||||
|   | ||||
| @@ -4,7 +4,7 @@ | ||||
| # SPDX-License-Identifier: (Apache-2.0 OR MIT) | ||||
| import itertools | ||||
| import textwrap | ||||
| from typing import List | ||||
| from typing import List, Optional, Tuple | ||||
| 
 | ||||
| import llnl.util.lang | ||||
| 
 | ||||
| @@ -66,17 +66,17 @@ def to_dict(self): | ||||
|         return dict(d) | ||||
| 
 | ||||
| 
 | ||||
| def make_environment(dirs=None): | ||||
|     """Returns an configured environment for template rendering.""" | ||||
| @llnl.util.lang.memoized | ||||
| def make_environment(dirs: Optional[Tuple[str, ...]] = None): | ||||
|     """Returns a configured environment for template rendering.""" | ||||
|     # Import at this scope to avoid slowing Spack startup down | ||||
|     import jinja2 | ||||
| 
 | ||||
|     if dirs is None: | ||||
|         # Default directories where to search for templates | ||||
|         builtins = spack.config.get("config:template_dirs", ["$spack/share/spack/templates"]) | ||||
|         extensions = spack.extensions.get_template_dirs() | ||||
|         dirs = [canonicalize_path(d) for d in itertools.chain(builtins, extensions)] | ||||
| 
 | ||||
|     # avoid importing this at the top level as it's used infrequently and | ||||
|     # slows down startup a bit. | ||||
|     import jinja2 | ||||
|         dirs = tuple(canonicalize_path(d) for d in itertools.chain(builtins, extensions)) | ||||
| 
 | ||||
|     # Loader for the templates | ||||
|     loader = jinja2.FileSystemLoader(dirs) | ||||
|   | ||||
| @@ -62,7 +62,7 @@ def source_file(tmpdir, is_relocatable): | ||||
|         src = tmpdir.join("relocatable.c") | ||||
|         shutil.copy(template_src, str(src)) | ||||
|     else: | ||||
|         template_dirs = [os.path.join(spack.paths.test_path, "data", "templates")] | ||||
|         template_dirs = (os.path.join(spack.paths.test_path, "data", "templates"),) | ||||
|         env = spack.tengine.make_environment(template_dirs) | ||||
|         template = env.get_template("non_relocatable.c") | ||||
|         text = template.render({"prefix": spack.store.layout.root}) | ||||
|   | ||||
| @@ -71,7 +71,7 @@ def test_template_retrieval(self): | ||||
|         """Tests the template retrieval mechanism hooked into config files""" | ||||
|         # Check the directories are correct | ||||
|         template_dirs = spack.config.get("config:template_dirs") | ||||
|         template_dirs = [canonicalize_path(x) for x in template_dirs] | ||||
|         template_dirs = tuple([canonicalize_path(x) for x in template_dirs]) | ||||
|         assert len(template_dirs) == 3 | ||||
| 
 | ||||
|         env = tengine.make_environment(template_dirs) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user