Memoize a few hot functions during module file generation (#37739)
This commit is contained in:
parent
9924c92c40
commit
9fb25b7404
@ -170,11 +170,9 @@ def merge_config_rules(configuration, spec):
|
|||||||
Returns:
|
Returns:
|
||||||
dict: actions to be taken on the spec passed as an argument
|
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
|
# The keyword 'all' is always evaluated first, all the others are
|
||||||
# evaluated in order of appearance in the module file
|
# 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():
|
for constraint, action in configuration.items():
|
||||||
if spec.satisfies(constraint):
|
if spec.satisfies(constraint):
|
||||||
if hasattr(constraint, "override") and constraint.override:
|
if hasattr(constraint, "override") and constraint.override:
|
||||||
|
@ -134,6 +134,7 @@ def filter_hierarchy_specs(self):
|
|||||||
return configuration(self.name).get("filter_hierarchy_specs", {})
|
return configuration(self.name).get("filter_hierarchy_specs", {})
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
@lang.memoized
|
||||||
def hierarchy_tokens(self):
|
def hierarchy_tokens(self):
|
||||||
"""Returns the list of tokens that are part of the modulefile
|
"""Returns the list of tokens that are part of the modulefile
|
||||||
hierarchy. 'compiler' is always present.
|
hierarchy. 'compiler' is always present.
|
||||||
@ -158,6 +159,7 @@ def hierarchy_tokens(self):
|
|||||||
return tokens
|
return tokens
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
@lang.memoized
|
||||||
def requires(self):
|
def requires(self):
|
||||||
"""Returns a dictionary mapping all the requirements of this spec
|
"""Returns a dictionary mapping all the requirements of this spec
|
||||||
to the actual provider. 'compiler' is always present among the
|
to the actual provider. 'compiler' is always present among the
|
||||||
@ -224,6 +226,7 @@ def available(self):
|
|||||||
return available
|
return available
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
@lang.memoized
|
||||||
def missing(self):
|
def missing(self):
|
||||||
"""Returns the list of tokens that are not available."""
|
"""Returns the list of tokens that are not available."""
|
||||||
return [x for x in self.hierarchy_tokens if x not in self.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
|
return parts
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
@lang.memoized
|
||||||
def unlocked_paths(self):
|
def unlocked_paths(self):
|
||||||
"""Returns a dictionary mapping conditions to a list of unlocked
|
"""Returns a dictionary mapping conditions to a list of unlocked
|
||||||
paths.
|
paths.
|
||||||
@ -428,6 +432,7 @@ def missing(self):
|
|||||||
return self.conf.missing
|
return self.conf.missing
|
||||||
|
|
||||||
@tengine.context_property
|
@tengine.context_property
|
||||||
|
@lang.memoized
|
||||||
def unlocked_paths(self):
|
def unlocked_paths(self):
|
||||||
"""Returns the list of paths that are unlocked unconditionally."""
|
"""Returns the list of paths that are unlocked unconditionally."""
|
||||||
layout = make_layout(self.spec, self.conf.name, self.conf.explicit)
|
layout = make_layout(self.spec, self.conf.name, self.conf.explicit)
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
|
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
|
||||||
import itertools
|
import itertools
|
||||||
import textwrap
|
import textwrap
|
||||||
from typing import List
|
from typing import List, Optional, Tuple
|
||||||
|
|
||||||
import llnl.util.lang
|
import llnl.util.lang
|
||||||
|
|
||||||
@ -66,17 +66,17 @@ def to_dict(self):
|
|||||||
return dict(d)
|
return dict(d)
|
||||||
|
|
||||||
|
|
||||||
def make_environment(dirs=None):
|
@llnl.util.lang.memoized
|
||||||
"""Returns an configured environment for template rendering."""
|
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:
|
if dirs is None:
|
||||||
# Default directories where to search for templates
|
# Default directories where to search for templates
|
||||||
builtins = spack.config.get("config:template_dirs", ["$spack/share/spack/templates"])
|
builtins = spack.config.get("config:template_dirs", ["$spack/share/spack/templates"])
|
||||||
extensions = spack.extensions.get_template_dirs()
|
extensions = spack.extensions.get_template_dirs()
|
||||||
dirs = [canonicalize_path(d) for d in itertools.chain(builtins, extensions)]
|
dirs = tuple(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
|
|
||||||
|
|
||||||
# Loader for the templates
|
# Loader for the templates
|
||||||
loader = jinja2.FileSystemLoader(dirs)
|
loader = jinja2.FileSystemLoader(dirs)
|
||||||
|
@ -62,7 +62,7 @@ def source_file(tmpdir, is_relocatable):
|
|||||||
src = tmpdir.join("relocatable.c")
|
src = tmpdir.join("relocatable.c")
|
||||||
shutil.copy(template_src, str(src))
|
shutil.copy(template_src, str(src))
|
||||||
else:
|
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)
|
env = spack.tengine.make_environment(template_dirs)
|
||||||
template = env.get_template("non_relocatable.c")
|
template = env.get_template("non_relocatable.c")
|
||||||
text = template.render({"prefix": spack.store.layout.root})
|
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"""
|
"""Tests the template retrieval mechanism hooked into config files"""
|
||||||
# Check the directories are correct
|
# Check the directories are correct
|
||||||
template_dirs = spack.config.get("config:template_dirs")
|
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
|
assert len(template_dirs) == 3
|
||||||
|
|
||||||
env = tengine.make_environment(template_dirs)
|
env = tengine.make_environment(template_dirs)
|
||||||
|
Loading…
Reference in New Issue
Block a user