diff --git a/.hunspell.en.dic b/.hunspell.en.dic index cd0ef5637..7482eb4aa 100644 --- a/.hunspell.en.dic +++ b/.hunspell.en.dic @@ -1605,3 +1605,15 @@ TOOL2 sphinxext opengraph PNG +HPSFCon +pu +xargs +jq +PyPI +gui +spack +mpivars +cuda +lindex +defineModStartNbProc +isIcase diff --git a/NEWS.rst b/NEWS.rst index 24c149529..b30b07019 100644 --- a/NEWS.rst +++ b/NEWS.rst @@ -248,6 +248,9 @@ Modules 5.7.0 (not yet released) :ref:`CONTRIBUTING`: AI agents must never add their own ``Signed-off-by:`` trailer and their involvement must be disclosed with an ``Assisted-by:`` trailer. +* Doc: add the :ref:`user-guide` document that explains a selection of + useful but lesser known features through practical examples and common + use cases. .. _5.6 release notes: diff --git a/doc/source/index.rst b/doc/source/index.rst index fd404cfe4..15ef84fc5 100644 --- a/doc/source/index.rst +++ b/doc/source/index.rst @@ -184,6 +184,7 @@ or (at your option) any later version (`GPL-2.0-or-later`). INSTALL-win MIGRATING NEWS + user-guide FAQ changes other-implementations diff --git a/doc/source/latex_index.rst b/doc/source/latex_index.rst index 91f241e37..54208eb2c 100644 --- a/doc/source/latex_index.rst +++ b/doc/source/latex_index.rst @@ -18,4 +18,5 @@ Introduction .. include:: envml.rst .. include:: MIGRATING.rst .. include:: NEWS.rst +.. include:: user-guide.rst .. include:: changes.rst diff --git a/doc/source/modulefile.rst b/doc/source/modulefile.rst index 815b712f8..49194f469 100644 --- a/doc/source/modulefile.rst +++ b/doc/source/modulefile.rst @@ -2100,6 +2100,8 @@ or terse reporting of these sub-commands: :mconfig:`avail_output`, :mconfig:`list_terse_output`, :mconfig:`spider_output`, :mconfig:`spider_terse_output`. +.. _advanced_module_version_specifiers: + Advanced module version specifiers ---------------------------------- diff --git a/doc/source/user-guide.rst b/doc/source/user-guide.rst new file mode 100644 index 000000000..617294bad --- /dev/null +++ b/doc/source/user-guide.rst @@ -0,0 +1,1135 @@ +.. _user-guide: + +Lesser known features +===================== + +Environment Modules provides many capabilities beyond the commonly used +:command:`module` :subcmd:`load` command. Some features are lesser known, despite being very +useful for users, modulefile developers, and site administrators. + +This document gathers and explains a selection of these features through +practical examples and common use cases. + +It originates from the presentation *Beyond "module load": Exploring the +Capabilities of Environment Modules* given at `HPSFCon 2026 +`_. Original slides and video +demonstrations can be found on the `event session page +`_. + +Short command names +------------------- + +Most Modules sub-commands can be abbreviated. The :command:`ml` command also +provides a shorter alternative interface for common operations. + +.. list-table:: + :header-rows: 1 + :widths: 50 50 + + * - Standard command + - Short form + + * - ``module `` + - ``ml `` + + * - ``module avail`` + - ``module av`` + + * - ``module purge`` + - ``module pu`` + + * - ``module list`` + - ``ml`` + + * - ``module load `` + - ``ml `` + + * - ``module unload `` + - ``ml -`` + +Display/Parsing +--------------- + +``--output=LIST`` +^^^^^^^^^^^^^^^^^ + +The :option:`--output`, or :option:`-o`, option customizes the information +displayed by Modules commands. + +It is supported by :command:`module` :subcmd:`avail`, :subcmd:`list`, and +:subcmd:`spider` sub-commands. + +By default, these commands display additional formatting elements such as +modulepaths, tags, default markers, or variant information. With +:option:`--output`, it is possible to restrict the displayed information to +only the needed fields. + +This option is especially useful when parsing command output in shell scripts, +Python programs, or monitoring tools. + +For example, with the following available modulefiles: + +.. parsed-literal:: + + :ps:`$` module avail + ------------------- :sgrmp:`/usr/share/modulefiles` ------------------ + gcc/8.3 :sgrde:`gcc/11.1` gcc/14.0 openmpi/5.0.8 + +When *LIST* is set to an empty value, only module names are displayed: + +.. parsed-literal:: + + :ps:`$` module avail -o '' + gcc/8.3 gcc/11.1 gcc/14.0 openmpi/5.0.8 + +The output format is defined as a colon-separated list of elements. Supported +elements are documented in the corresponding sub-command manual pages. + +*LIST* may also be prefixed by ``+`` or ``-`` to respectively append elements +to or subtract them from the currently configured value. For example, report +the variants declared by each modulefile in addition to the default output: + +.. parsed-literal:: + + :ps:`$` module avail -o +variant + ------------------- :sgrmp:`/usr/share/modulefiles` ------------------ + gcc/8.3 :sgrde:`gcc/11.1` gcc/14.0 openmpi/5.0.8\ :sgrse:`{`:sgrva:`cuda=on`:sgrse:`,`\ :sgrva:`off`:sgrse:`}` + +This feature helps avoid fragile text parsing pipelines. + +Instead of parsing formatted output: + +.. code-block:: bash + + modules_list=$(module avail | grep -v '^---' \ + | sed 's/(default)//g' | head -n -2 | xargs) + +A simpler and more robust approach is: + +.. code-block:: bash + + modules_list=$(module avail -o '') + +``spider`` +^^^^^^^^^^ + +The :command:`module` :subcmd:`spider` sub-command lists all available +modulefiles found in enabled modulepaths, including modulepaths recursively +added by modulefiles. + +Unlike :subcmd:`avail`, :subcmd:`spider` explores the full dependency tree +created by :mfcmd:`module use`, :mfcmd:`append-path`, or +:mfcmd:`prepend-path` instructions. + +This command is especially useful with hierarchical module layouts, where some +modulefiles only become visible after loading compiler or MPI dependencies. + +The :subcmd:`spider` sub-command accepts the same display and formatting +options as :subcmd:`avail`, including :option:`--output`, +:option:`--latest`, :option:`--default`, :option:`--json`, +:option:`--indepth`, and :option:`--no-indepth`. + +For example, in a hierarchical environment: + +.. parsed-literal:: + + :ps:`$` module avail + ------------------- :sgrmp:`/usr/share/modulefiles/common` ------------------ + gcc/14.0 intel/25.0 + +Only compiler modules are initially visible. + +The :subcmd:`spider` sub-command reveals additional modules together with +their dependency path: + +.. parsed-literal:: + + :ps:`$` module spider + ------------------- :sgrmp:`/usr/share/modulefiles/common` ------------------ + gcc/14.0 intel/25.0 + + + ---------- :sgrmp:`/usr/share/modulefiles/intel` (via intel/25.0) ----------- + intelmpi/25.0 + + ------------ :sgrmp:`/usr/share/modulefiles/gcc` (via gcc/14.0) ------------- + openmpi/5.0.8 + + +This output indicates which modules must be loaded before these MPI stacks +become available. + +Modules caches are automatically used by :subcmd:`spider` when configured, +which significantly improves search performance on large installations. + +``--latest`` and ``--default`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The :option:`--latest`, or :option:`-L`, and :option:`--default`, or +:option:`-d`, options restrict the output of the :command:`module` +:subcmd:`avail` and :subcmd:`spider` sub-commands. + +For example, with the following available modulefiles: + +.. parsed-literal:: + + :ps:`$` module avail + ------------------- :sgrmp:`/usr/share/modulefiles` ------------------ + gcc/8.3 :sgrde:`gcc/11.1` gcc/14.0 intel/24.0 intel/25.0 + +The :option:`--latest` option displays only the highest numerically sorted +version of each module name. + +.. parsed-literal:: + + :ps:`$` module avail --latest + ------------------- :sgrmp:`/usr/share/modulefiles` ------------------ + gcc/14.0 intel/25.0 + +The :option:`--default` option displays only the default version of each +module name. This version is either explicitly defined (as here for ``gcc``) +or implicitly the highest one (as for ``intel``). + +.. parsed-literal:: + + :ps:`$` module avail --default + ------------------- :sgrmp:`/usr/share/modulefiles` ------------------ + :sgrde:`gcc/11.1` intel/25.0 + +These options may also be combined with other display options such as +:option:`--output` or :option:`--json`. + +``--indepth`` and ``--no-indepth`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The :option:`--indepth` and :option:`--no-indepth` options control how the +:command:`module` :subcmd:`avail` and :subcmd:`spider` sub-commands search +for matching modulefiles. + +By default, Modules searches recursively and returns all matching +modulefiles. This behavior is equivalent to :option:`--indepth` and +can be configured with :command:`module` :subcmd:`config` :mconfig:`avail_indepth` +and :mconfig:`spider_indepth`. + +.. parsed-literal:: + + :ps:`$` module avail + ------------------- :sgrmp:`/usr/share/modulefiles` ------------------ + intel/24.0 intel/25.0 gcc/8.3 gcc/11.1 gcc/14.0 + +The :option:`--no-indepth` option limits results to the depth level +expressed by the search query. Modulefiles contained in matching directories +are not displayed. + +.. parsed-literal:: + + :ps:`$` module avail --no-indepth + ------------------- :sgrmp:`/usr/share/modulefiles` ------------------ + :sgrdi:`intel`/ :sgrdi:`gcc`/ + +``--json`` +^^^^^^^^^^ + +The :option:`--json`, or :option:`-j`, option displays command results in +JSON format. + +It is supported by the :command:`module` :subcmd:`avail`, :subcmd:`list`, +:subcmd:`savelist`, :subcmd:`search`, :subcmd:`spider`, +:subcmd:`stashlist`, and :subcmd:`whatis` sub-commands. + +JSON output is intended for machine consumption and can be processed directly +by tools such as ``jq`` or Python scripts. + +.. parsed-literal:: + + :ps:`$` module avail -j | jq . + { + "/usr/share/modulefiles": { + "gcc/14.0": { + "name": "gcc/14.0", + "type": "modulefile", + "symbols": [], + "tags": [], + "pathname": "/usr/share/modulefiles/gcc/14.0", + "via": "" + }, + ... + } + +The JSON format is also useful for monitoring, reporting, and integration +with external tools. + +Manipulating the environment for users +-------------------------------------- + +Collections +^^^^^^^^^^^ + +Collections save and restore sets of loaded modules. + +They provide a convenient way to switch between software environments without +having to manually load and unload each module. + +Collections are managed through several :command:`module` sub-commands: + +.. list-table:: + :header-rows: 1 + :widths: 30 70 + + * - Sub-command + - Description + + * - :subcmd:`save` [collection] + - Save the current module environment to a collection. + + * - :subcmd:`restore` [collection] + - Restore a collection or collection file. + + * - :subcmd:`savelist` + - List saved collections. + + * - :subcmd:`saverm` [collection] + - Remove a saved collection. + + * - :subcmd:`saveshow` [collection] + - Display information about a collection. + + * - :subcmd:`is-saved` [collection] + - Test whether one or more collections exist. + +Collections are stored under the user collection directory, usually +:file:`$HOME/.module`. + +The :envvar:`MODULES_COLLECTION_TARGET` environment variable may be defined +to append a suffix to collection names. This feature is particularly useful +on systems sharing a common home directory across multiple clusters. + +.. parsed-literal:: + + :ps:`$` module save + :ps:`$` module purge + :ps:`$` module restore + +``stash`` commands +^^^^^^^^^^^^^^^^^^ + +Stash collections temporarily save the current module environment and make it +easy to switch to another environment. + +This feature is similar to the :command:`git stash` workflow: save the current +state, perform other work, then restore the original environment later. + +Stash collections are managed through several :command:`module` +sub-commands: + +.. list-table:: + :header-rows: 1 + :widths: 30 70 + + * - Sub-command + - Description + + * - :subcmd:`stash` + - Save the current environment and reset it. + + * - :subcmd:`stashpop` + - Restore and remove a stash collection. + + * - :subcmd:`stashrm` + - Remove a stash collection. + + * - :subcmd:`stashshow` + - Display information about a stash collection. + + * - :subcmd:`stashclear` + - Remove all stash collections. + + * - :subcmd:`stashlist` + - List stash collections. + +Save the current environment: + +.. parsed-literal:: + + :ps:`$` module stash + +Load a different software stack: + +.. parsed-literal:: + + :ps:`$` module purge + :ps:`$` module load ... + +Restore the original environment: + +.. parsed-literal:: + + :ps:`$` module stashpop + +Unlike regular collections, stash collections are intended to be short-lived +and are automatically removed when restored with +:subcmd:`stashpop`. + +``mogui`` +^^^^^^^^^ + +``mogui`` provides a graphical interface to browse available modules and +manage collections. + +It offers an alternative to the command line and can be useful for new users +discovering a software stack or for users who prefer an interactive +interface. + +Any environment change made from the GUI, such as loading modules or +restoring collections, is applied back to the shell session that launched +the application. + +The project is available on GitHub: +`cea-hpc/mogui `_. It can be installed +from PyPI with :command:`pip` or from Spack. + +.. parsed-literal:: + + :ps:`$` pip install modules-gui + +or: + +.. parsed-literal:: + + :ps:`$` spack install py-modules-gui + +Then start the graphical interface: + +.. parsed-literal:: + + :ps:`$` mogui + +.. image:: https://raw.githubusercontent.com/cea-hpc/mogui/main/doc/sneak_peek.gif + :alt: mogui graphical interface + :align: center + +``envml`` +^^^^^^^^^ + +The :ref:`envml(1)` command executes a command in a specific module +environment. + +It applies the requested module actions, executes the command, then restores +the original environment. As a result, the current shell session remains +unchanged. + +This feature is particularly useful in scripts, tests, and automation +workflows where commands must be executed in a controlled software +environment. + +Supported module actions include: + +.. list-table:: + :header-rows: 1 + :widths: 35 65 + + * - Action + - Description + + * - ``purge`` + - Purge all loaded modules. + + * - ``restore=`` + - Restore a saved collection. + + * - ``unload=`` + - Unload one or more modules. + + * - ``switch=&`` + - Switch from one module to another. + + * - ``load=`` + - Load one or more modules. + + * - ```` + - Shorthand form of ``load=``. + +Multiple actions may be chained with the ``:`` separator. When specifying +multiple modules for a single action, use the ``&`` separator. In some +shells, such as Bash, the ``&`` character must be escaped or quoted. + +For example, execute a command in a clean environment: + +.. parsed-literal:: + + :ps:`$` envml purge -- gcc hello.c + +The :ref:`envml(1)` command can simplify scripts by replacing sequences of +module operations with a single command. + +Instead of: + +.. code-block:: bash + + #!/bin/bash + module purge + module load gcc + gcc hello.c + +One can write: + +.. code-block:: bash + + #!/bin/bash + envml purge:gcc -- gcc hello.c + +Protected environment variables +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The :mconfig:`protected_envvars` configuration option prevents Modules from +modifying selected environment variables. Multiple variables may be specified +using the ``:`` separator. + +This feature is useful to protect critical environment settings from +unintended changes. + +When a modulefile attempts to modify a protected variable, Modules ignores +the modification and emits a warning. + +.. parsed-literal:: + + :ps:`$` module config protected_envvars LD_PRELOAD + :ps:`$` module load intel + Loading :sgrhi:`intel/25.0` + :sgrwa:`WARNING`: Modification of protected environment variable LD_PRELOAD ignored + +Developing and configuring modulefiles +-------------------------------------- + +``module edit`` +^^^^^^^^^^^^^^^ + +The :command:`module` :subcmd:`edit` sub-command opens a modulefile in the +configured text editor (cf. :subcmd:`config` :mconfig:`editor`). + +Instead of manually locating a modulefile: + +.. parsed-literal:: + + :ps:`$` vi $(module path appA) + +One can directly edit it with: + +.. parsed-literal:: + + :ps:`$` module edit appA + +``module lint`` +^^^^^^^^^^^^^^^ + +The :command:`module` :subcmd:`lint` sub-command analyzes modulefiles and +reports potential issues. + +It relies on the Nagelfar Tcl syntax checker to detect syntax errors and +common mistakes. + +Analyze a specific modulefile: + +.. parsed-literal:: + + :ps:`$` module lint appA + +Reported issues may include: + +* Unknown variables +* Unknown commands +* Invalid command arguments +* Tcl syntax errors + +``source-sh`` +^^^^^^^^^^^^^ + +The :mfcmd:`source-sh` modulefile command evaluates a shell script and tracks +the environment changes it performs. + +The detected changes are translated into modulefile actions, making it +possible to load and unload shell-based environments through Modules. + +It is particularly useful to integrate software distributions that provide +environment setup scripts such as ``setup-env.sh``, ``mpivars.sh``, or +similar rc-provided files. + +For example: + +.. code-block:: tcl + + #%Module + + source-sh bash /opt/spack/share/spack/setup-env.sh + +``sh-to-mod`` +^^^^^^^^^^^^^ + +The :command:`module` :subcmd:`sh-to-mod` sub-command evaluates a shell script +and reports the resulting environment changes as modulefile commands. + +It can be used to convert existing shell initialization scripts into +modulefiles. + +For example: + +.. parsed-literal:: + + :ps:`$` module sh-to-mod bash setup-env.sh > setup-env.mod + +.. tip:: + + Use :subcmd:`sh-to-mod` when you want to generate and maintain a regular + modulefile from an existing shell script. + +``mod-to-sh`` +^^^^^^^^^^^^^ + +The :command:`module` :subcmd:`mod-to-sh` sub-command evaluates one or more +modulefiles and reports the resulting environment changes as shell code. + +For example: + +.. parsed-literal:: + + :ps:`$` module mod-to-sh bash appA > setup-env.sh + +.. tip:: + + The :subcmd:`mod-to-sh` sub-command can be seen as the reverse operation of + :subcmd:`sh-to-mod`. + +``prereq`` +^^^^^^^^^^ + +The :mfcmd:`prereq` modulefile command declares one or more modules as a +requirement of the current modulefile. When the automated module handling +mode is enabled (see :mconfig:`auto_handling`), which is the default, a +requirement is automatically loaded if not yet present in the user +environment. + +Requirements are sometimes expressed with a condition block: + +.. code-block:: tcl + + if { ! [ is-loaded appA ] } { + module load appA + } + +This must be avoided: when ``appA`` is already loaded, the condition is +false and no requirement rule is defined, so Modules is not aware that the +current module depends on ``appA``. + +Declare the requirement unconditionally instead: + +.. code-block:: tcl + + prereq appA + +Loading a module declaring this requirement (here ``appB``) automatically +loads the required module when missing: + +.. parsed-literal:: + + :ps:`$` module load appB + Loading :sgrhi:`appB` + :sgrin:`Loading requirement`: appA + +When automated module handling is disabled, a missing requirement is not +automatically loaded: an error is reported and the modulefile load fails. + +The :mfcmd:`module load` modulefile command equally declares a +requirement rule, and it loads the missing required module even when +automated module handling is disabled. The two commands also differ when +several modules are specified: :mfcmd:`module load` loads them all +(logical AND) whereas :mfcmd:`prereq` requires only one of them (logical +OR). Multiple :mfcmd:`prereq` commands act as a logical AND. + +``conflict`` +^^^^^^^^^^^^ + +The :mfcmd:`conflict` modulefile command declares one or more modules that +cannot be loaded together with the current modulefile. + +Instead of manually checking for incompatible modules: + +.. code-block:: tcl + + if { [ is-loaded appB ] } { + puts stderr "ERROR: appB conflicts with appA!" + exit 1 + } + +Declare the conflict with: + +.. code-block:: tcl + + conflict appB + +When the :mconfig:`conflict_unload` configuration option is enabled in +addition to the automated module handling mode (see :mconfig:`auto_handling`), +loading a module automatically unloads the conflicting modules found in the +user environment: + +.. parsed-literal:: + + :ps:`$` module load appA + Loading :sgrhi:`appA` + :sgrin:`Unloading conflict`: appB + +When these options are disabled, an error is reported instead and the +modulefile load fails. + +A modulefile declaring a conflict on its own module name defines a +*reflexive conflict*: only one version of this module can then be loaded at +a time. + +.. code-block:: tcl + + conflict appA + +.. parsed-literal:: + + :ps:`$` module load appA/2.0 + Loading :sgrhi:`appA/2.0` + :sgrin:`Unloading conflict`: appA/1.0 + +.. tip:: + + When only one module should be loaded at a time for any given module + name, enable the :mconfig:`unique_name_loaded` configuration option + instead of declaring a reflexive conflict in every modulefile. As this + option applies to all existing modules, every module name must follow + this rule. It is generally the case when only *application* modules are + provided, but may not be if application configurations are also handled + through modulefiles. + +``variant`` +^^^^^^^^^^^ + +The :mfcmd:`variant` modulefile command declares variants and their accepted +values. + +This command is only available inside modulefiles. + +Variants allow users to customize the behavior of a modulefile at load time. +They follow the same syntax as Spack variants. + +Boolean variants are enabled with ``+`` and disabled with ``~``: + +.. code-block:: tcl + + #%Module + variant --boolean cuda + +.. parsed-literal:: + + :ps:`$` module load openmpi +cuda + +Variants with multiple values are declared by listing the accepted values: + +.. code-block:: tcl + + #%Module + variant compiler gcc intel + +And selected with the ``=`` syntax: + +.. parsed-literal:: + + :ps:`$` module load openmpi compiler=intel + +The :mfcmd:`getvariant` modulefile command retrieves the value of a declared +variant, allowing the modulefile to adapt its behavior. + +For example: + +.. code-block:: tcl + + switch -- [getvariant compiler] { + gcc { + prereq gcc + } + intel { + prereq intel + } + } + +Configuration option :mconfig:`variant_shortcut` defines shortcut characters +for variants. + +For example: + +.. parsed-literal:: + + :ps:`$` module config variant_shortcut compiler=% + +This allows users to write: + +.. parsed-literal:: + + :ps:`$` module load openmpi %gcc + +Advanced manipulations +---------------------- + +Advanced module version specifiers +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +:ref:`advanced_module_version_specifiers` provide a concise way to select modulefiles based on +their version or declared variants. They can be used with several +:command:`module` sub-commands, including :subcmd:`avail`, +:subcmd:`spider`, :subcmd:`load`, and :subcmd:`switch`. + +Version specifications use the ``@`` character: + +.. list-table:: + :header-rows: 1 + :widths: 40 60 + + * - Specification + - Description + + * - ``module avail cuda@default`` + - Select the default version. + + * - ``module avail cuda@latest`` + - Select the latest version. + + * - ``module avail cuda@12:`` + - Select versions greater than or equal to ``12``. + + * - ``module avail cuda@:12`` + - Select versions lower than or equal to ``12``. + + * - ``module avail cuda@12:13`` + - Select versions between ``12`` and ``13``. + +Variant specifications may also be used: + +.. list-table:: + :header-rows: 1 + :widths: 40 60 + + * - Specification + - Description + + * - ``module avail +mpi`` + - Select modules declaring the ``mpi`` variant. + + * - ``module avail cuda=12`` + - Select modules where the ``cuda`` variant is set to ``12``. + + * - ``module avail +mpi +cuda`` + - Select modules matching both variant requirements. + +``--timer`` and ``--debug`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The :option:`--timer` and :option:`--debug`, or :option:`-D`, options help +analyze and troubleshoot Modules commands. + +They are supported by most :command:`module` sub-commands. + +The :option:`--timer` option reports the total execution time of a command. + +For example: + +.. parsed-literal:: + + :ps:`$` module avail --timer + ------------------- :sgrmp:`/usr/share/modulefiles` ------------------ + gcc/8.3 :sgrde:`gcc/11.1` gcc/14.0 openmpi/5.0.8 + + :sgrtr:`TIMER Total execution took 20.045 ms` + +The :option:`--debug`, or :option:`-D`, option displays debugging messages +describing the internal execution of the command. + +For example: + +.. parsed-literal:: + + :ps:`$` module avail -D + :sgrtr:`DEBUG setState: cmdline set to 'modulecmd.tcl bash avail -D'` + :sgrtr:`DEBUG setState: shell set to 'bash'` + :sgrtr:`DEBUG setState: subcmd set to 'avail'` + :sgrtr:`DEBUG setConf: verbosity set to 'debug'` + ... + ------------------- :sgrmp:`/usr/share/modulefiles` ------------------ + gcc/8.3 :sgrde:`gcc/11.1` gcc/14.0 openmpi/5.0.8 + +The :option:`--timer` and :option:`--debug` options may be combined. In this +case, regular debug messages are replaced by execution time reports for each +internal procedure call. + +.. parsed-literal:: + + :ps:`$` module avail --timer -D + :sgrtr:`TIMER parseModuleCommandName avail help (0.151 ms)` + :sgrtr:`TIMER isIcase (0.088 ms)` + :sgrtr:`TIMER defineModStartNbProc 1 (0.060 ms)` + ... + :sgrtr:`TIMER Total execution took 31.722 ms` + +For even more detailed debugging information, use :option:`-DD`. + +``.modulerc`` files +^^^^^^^^^^^^^^^^^^^ + +A :file:`.modulerc` file contains Tcl code automatically evaluated by +Modules when encountered during a command execution. + +Rc files are used to define module aliases, virtual +modules, tags, hidden modules, forbidden modules, ... + +Several :file:`.modulerc` files may be evaluated during a single +:command:`module` command. + +Depending on the executed sub-command, Modules may evaluate +:file:`.modulerc` files found in different locations, including: + +* :envvar:`MODULERCFILE` +* :file:`$HOME/.modulerc` +* Modulepath and modules directories + +For example, the following directory hierarchy contains several +:file:`.modulerc` files: + +.. code-block:: text + + /home/user/.modulerc + modulefiles/ + ├── .modulerc + ├── app/ + │ ├── .modulerc + │ └── 1.0 + └── mpi/ + ├── .modulerc + └── openmpi/5.0 + +Depending on the requested operation, one or more of these files are +evaluated automatically. + +See :ref:`Modulecmd startup` for details on the startup sequence, +:mconfig:`rcfile` and :mconfig:`ignore_user_rc` to configure the evaluation +of user rc files, and :sitevar:`modulerc_extra_vars` and +:sitevar:`modulerc_extra_cmds` to extend :file:`.modulerc` files. + +``module-tag`` +^^^^^^^^^^^^^^ + +The :mfcmd:`module-tag` modulerc command associates one or more tags with +modulefiles. + +This command is only available inside :file:`.modulerc` files. + +Tags may be used to provide additional information about modulefiles or to +modify their behavior. + +For example: + +.. code-block:: tcl + + module-tag experimental app/2.0 + +The tag is then reported along the module name in search results: + +.. parsed-literal:: + + :ps:`$` module avail + ------------------- :sgrmp:`/usr/share/modulefiles` ------------------ + app/1.0 app/2.0 :sgrse:`<`\ experimental\ :sgrse:`>` + +Several predefined tags affect the behavior of Modules: + +.. list-table:: + :header-rows: 1 + :widths: 25 75 + + * - Tag + - Description + + * - ``keep-loaded`` + - Prevent automatic unloading when unloading dependent modules. + + * - ``sticky`` + - Prevent unloading unless :option:`--force` is specified. + + * - ``super-sticky`` + - Prevent unloading under any circumstances. + +For example: + +.. code-block:: tcl + + module-tag sticky core + +Once loaded, the ``core`` module cannot be unloaded, even with the +:subcmd:`purge` sub-command. The ``sticky`` tag is rendered with a specific +background color in the output. + +.. parsed-literal:: + + :ps:`$` module purge + Unloading :sgrshi:`core/1.0` + :sgrer:`ERROR`: Unload of sticky module skipped + :ps:`$` module list + Currently Loaded Modulefiles: + 1) :sgrs:`core/1.0` + +Sticky modules can help ensure that essential software stacks remain loaded. +The behavior of :subcmd:`purge` with sticky modules can be configured through +:mconfig:`sticky_purge`. + +``module-hide`` +^^^^^^^^^^^^^^^ + +The :mfcmd:`module-hide` modulerc command hides modulefiles from module +searches and selection. + +This command is only available inside :file:`.modulerc` files. + +A hidden module is excluded from regular searches but may still be selected +when explicitly referred to by its exact name. + +For example: + +.. code-block:: tcl + + module-hide app/1.0 + +Visibility may also be restricted to specific users or groups. + +Time-based restrictions can be defined with ``--after`` and ``--before``. + +For example: + +.. code-block:: tcl + + module-hide --after 2027-01-01 app/1.0 + +See :mfcmd:`module-hide` for additional visibility options, including **soft** +and **hard** hiding, as well as **users** and **groups** restrictions. + +``module-forbid`` +^^^^^^^^^^^^^^^^^ + +The :mfcmd:`module-forbid` modulerc command prevents designated modulefiles +from being loaded. + +This command is only available inside :file:`.modulerc` files. + +Unlike a hidden module, a forbidden module remains visible in module searches +but cannot be loaded. + +For example: + +.. code-block:: tcl + + module-forbid app/1.0 + +A custom message may be displayed when a user attempts to load a forbidden +module with the ``--message`` option. + +For example: + +.. code-block:: tcl + + module-forbid --message {Please use app/2.0 instead} app/1.0 + +See :mfcmd:`module-forbid` for additional restriction options, including +custom messages, as well as **after**/**before**, **users** and **groups** restrictions. + +``module-virtual`` +^^^^^^^^^^^^^^^^^^ + +The :mfcmd:`module-virtual` modulerc command associates a virtual module name +with an existing modulefile. + +This command is only available inside :file:`.modulerc` files. + +Several virtual modules may refer to the same modulefile, reducing the number +of files required to define similar modules. + +For example: + +.. code-block:: text + + modulefiles/app/ + ├── .common + └── .modulerc + +The :file:`.modulerc` file may define several virtual versions: + +.. code-block:: tcl + + #%Module + module-virtual 1.0 .common + module-virtual 1.2 .common + module-virtual 1.5 .common + module-virtual 2.0 .common + +.. parsed-literal:: + + :ps:`$` module avail + ------------------- :sgrmp:`/usr/share/modulefiles` ------------------ + app/1.0 app/1.2 app/1.5 app/2.0 + +All these virtual modules are evaluated using the same :file:`.common` +modulefile. +Its behavior can be adapted according to the virtual module +name being evaluated. + +.. code-block:: tcl + + #%Module + + set version [lindex [split [module-info name] /] end] + + setenv APP_VERSION $version + +Module logger +^^^^^^^^^^^^^ + +Modules can log module activity through the :mconfig:`logger` and +:mconfig:`logged_events` configuration options. + +The :mconfig:`logger` option defines the command used to record log messages. + +For example: + +.. parsed-literal:: + + :ps:`$` module config logger "/usr/bin/logger -t modules" + +The :mconfig:`logged_events` option defines which module events are recorded. + +.. list-table:: + :header-rows: 1 + :widths: 30 70 + + * - Event + - Description + + * - ``requested_cmd`` + - Record module commands requested by users. + + * - ``requested_eval`` + - Record modulefile evaluations requested by users. + + * - ``auto_eval`` + - Record modulefile evaluations automatically triggered by Modules. + +Multiple events may be specified using the ``:`` separator. + +For example: + +.. parsed-literal:: + + :ps:`$` module config logged_events requested_cmd:requested_eval + +By default, no events are logged. + +The logger command can be customized to integrate Modules activity with an +existing logging or monitoring infrastructure.