modules: allow autoload: run, like in environment views (#42743)

This commit is contained in:
Harmen Stoppels 2024-03-04 08:49:45 +01:00 committed by GitHub
parent d1fa23e9c6
commit 5d994e48d5
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 29 additions and 34 deletions

View file

@ -273,9 +273,21 @@ builtin support through the ``depends_on`` function, the latter simply uses a ``
statement. Both module systems (at least in newer versions) do reference counting, so that if a
module is loaded by two different modules, it will only be unloaded after the others are.
The ``autoload`` key accepts the values ``none``, ``direct``, and ``all``. To disable it, use
``none``, and to enable, it's best to stick to ``direct``, which only autoloads the direct link and
run type dependencies, relying on recursive autoloading to load the rest.
The ``autoload`` key accepts the values:
* ``none``: no autoloading
* ``run``: autoload direct *run* type dependencies
* ``direct``: autoload direct *link and run* type dependencies
* ``all``: autoload all dependencies
In case of ``run`` and ``direct``, a ``module load`` triggers a recursive load.
The ``direct`` option is most correct: there are cases where pure link dependencies need to set
variables for themselves, or need to have variables of their own dependencies set.
In practice however, ``run`` is often sufficient, and may make ``module load`` snappier.
The ``all`` option is discouraged and seldomly used.
A common complaint about autoloading is the large number of modules that are visible to the user.
Spack has a solution for this as well: ``hide_implicits: true``. This ensures that only those
@ -297,11 +309,11 @@ Environment Modules requires version 4.7 or higher.
tcl:
hide_implicits: true
all:
autoload: direct
autoload: direct # or `run`
lmod:
hide_implicits: true
all:
autoload: direct
autoload: direct # or `run`
.. _anonymous_specs:

View file

@ -121,43 +121,26 @@ def update_dictionary_extending_lists(target, update):
target[key] = update[key]
def dependencies(spec, request="all"):
"""Returns the list of dependent specs for a given spec, according to the
request passed as parameter.
def dependencies(spec: spack.spec.Spec, request: str = "all") -> List[spack.spec.Spec]:
"""Returns the list of dependent specs for a given spec.
Args:
spec: spec to be analyzed
request: either 'none', 'direct' or 'all'
request: one of "none", "run", "direct", "all"
Returns:
list of dependencies
The return list will be empty if request is 'none', will contain
the direct dependencies if request is 'direct', or the entire DAG
if request is 'all'.
list of requested dependencies
"""
if request not in ("none", "direct", "all"):
message = "Wrong value for argument 'request' : "
message += "should be one of ('none', 'direct', 'all')"
raise tty.error(message + " [current value is '%s']" % request)
if request == "none":
return []
elif request == "run":
return spec.dependencies(deptype=dt.RUN)
elif request == "direct":
return spec.dependencies(deptype=dt.RUN | dt.LINK)
elif request == "all":
return list(spec.traverse(order="topo", deptype=dt.LINK | dt.RUN, root=False))
if request == "direct":
return spec.dependencies(deptype=("link", "run"))
# FIXME : during module file creation nodes seem to be visited multiple
# FIXME : times even if cover='nodes' is given. This work around permits
# FIXME : to get a unique list of spec anyhow. Do we miss a merge
# FIXME : step among nodes that refer to the same package?
seen = set()
seen_add = seen.add
deps = sorted(
spec.traverse(order="post", cover="nodes", deptype=("link", "run"), root=False),
reverse=True,
)
return [d for d in deps if not (d in seen or seen_add(d))]
raise ValueError(f'request "{request}" is not one of "none", "direct", "run", "all"')
def merge_config_rules(configuration, spec):

View file

@ -34,7 +34,7 @@
dictionary_of_strings = {"type": "object", "patternProperties": {r"\w[\w-]*": {"type": "string"}}}
dependency_selection = {"type": "string", "enum": ["none", "direct", "all"]}
dependency_selection = {"type": "string", "enum": ["none", "run", "direct", "all"]}
module_file_configuration = {
"type": "object",