Extra match search

Traditional module lookup only performs modulefile search, module version resolution, module alias and symbolic version resolution. This is based on file lookup and evaluation of modulerc files.

Searching modules with a query exceeding traditional lookup is called extra match search. It mainly looks at modulefile content to retain those matching specified query. This content lookup requires a specific modulefile evaluation (see Modulefile evaluation mode for extra match search).

Requirements

An extra match search query requires Advanced module version specifiers configuration to be enabled. Otherwise query specifiers will be understood as module name and version.

When extra match search applies

On Module version specification to return all matching modules context. On such context, variant specification in search query was previously ignored. Extra match search adds here a feature to filter returned results.

On Module version specification to select one module context, extra match search is not enabled at the moment. As it changes obtained result. For instance when loading a module with a given variant value, extra match search will remove from available modules those not declaring this variant and its specified value. It is considered to add an option to apply extra match search to the select one module context. This option will be disabled by default on Modules v5 and enabled by default on v6.

Extra match search process

Extra match search is performed from getModules procedure. All subsequent procedures relying on getModules will then benefit from this extra process without a change.

Extra match search is done right after phase 3: elaborate directory content with default element selection. At this stage:

  • symbolic versions, aliases and virtual modules are known
  • dynamically hidden or expired elements have been filtered
  • automatically defined symbols are set
  • initial directory content and their default version are set

This way the subsequent phases that filters result based on name and version search query, adjusts directory content and no-indepth mode does not need to be updated and will apply on the extra match search result.

As extra match search is performed after phase 3, search operation will only applies on result obtained from traditional lookup.

In case no-indepth mode is asked and extra match search should be performed, traditional file lookup (by findModules) is made to return all existing files. Not only those matching depth level. As extra match filtering process may eliminate some entries, all of them should be tested to obtain accurate result.

Extra match search will only be performed if search query requires it. It will be determined by isExtraMatchSearchRequired procedure. See What triggers an extra match search? for applying conditions. Current search module specification is passed as argument. This string helps to find if:

  • variant has been specified in ModuleVersSpec structure
  • extra specifier has been specified in ModuleVersSpec structure

If search query is a traditional one, no extra match search is performed. It saves this way substantial processing time as no evaluation of modulefile is performed.

getModules will call a dedicated procedure named filterExtraMatchSearch to handle the extra match search process. It will obtain the name of result array as argument and will bind to this array variable (to change it without copy). Search module specification is also set as argument to help to know the extra match query to filter modules on.

filterExtraMatchSearch evaluates all entries in obtained result array that are of modulefile or virtual types. See Modulefile evaluation mode for extra match search section. With the consolidated information gathered by these evaluations, procedure filters entries in result array that do not match the extra match query.

Symbolic versions

From filterExtraMatchSearch, symbolic version elements are retained unless if they target an element that is withdrawn by the filter process.

They need to be filtered if their target is filtered as it may confuse some sub-commands like paths if they are part of getModules result.

During wild search (no module name specified) with variant specified, auto symbolic versions (latest and default) are disabled. This is done especially for sub-commands like paths that take getModules result and try to resolve each entry. In this situation it is important not to have any auto symbol that indirectly targets an element withdrawn from extra match filter.

Module aliases

From filterExtraMatchSearch, module alias elements are purely withdrawn by the filter process as they are not resolved on return all matching modules context. They are also withdrawn even if searched module name matches alias name.

They need to be filtered when search query mentions a specific variant and value as alias does not define variant in itself.

When variants have to be reported but are not part of the search query, then no filtering process occurs, aliases are not withdrawn.

Directories overridden by aliases take precedence over these aliases when extra match search is performed.

FUTURE: it may be revised to implement extra match search on select one module context.

Module tags

Modulefiles tagged forbidden are excluded from evaluation mechanism. If forbidden tag only applies to some specific variant values, modulefile is evaluated.

Note that in a select one module context, if forbidden tag applies specifically to searched variant, this module is excluded from result.

If module hidden tag only applies to some specific variant values, modulefile is evaluated in scan mode.

Error entries

Files in error (e.g., without a module header string, not readable) are ignored by filterExtraMatchSearch and kept in result array. These error entries are useful to report the message they contain if erroneous file was specifically selected.

Extra specifier

Extra specifier enables to query whose modules defines a given element. With them it is possible to get all the modules defining a given environment variable or requiring a given module.

Most of the modulefile Tcl commands are associated to an extra specifier. Some aliases are also provided, to gather several command elements into the general same concept they are about. Following table list the available extra specifiers and their associated modulefile command.

Modulefile command Extra specifier(s)
variant variant
setenv setenv, envvar
unsetenv unsetenv, envvar
pushenv pushenv, envvar
append-path append-path, envvar
prepend-path prepend-path, envvar
remove-path remove-path, envvar
complete complete
uncomplete uncomplete
set-alias set-alias
unset-alias unset-alias
set-function set-function
unset-function unset-function
chdir chdir
family family
prereq prereq, prereq-any, require
prereq-any prereq-any, prereq, require
prereq-all prereq-all, depends-on, require
depends-on depends-on, prereq-all, require
always-load always-load, require
conflict conflict, incompat
module load load, require
module load-any load-any, require
module try-load try-load, require
module unload unload, incompat
module switch switch, switch-on, require, switch-off, incompat

Extra specifier are only valid on return all matching modules context. An error is returned when used in query on other contexts.

Using an unknown extra specifier (not part of the above table) produces an error. Helps to distinguish between a bad specification and no modulefile declaring the associated modulefile command.

Extra specifier are not made to resolve module alias or symbolic version, as such resolution is part of the regular match search.

The module switch command produces content in different extra specifiers. Switched-on module can be queried via switch, switch-on and require specifiers. Switched-off module can be queried via switch, switch-off and incompat specifiers. On its one-arg form, no switched-off module is added to relative specifiers.

Recording extra specifier specification

Extra specifiers defined in a search query are processed and saved in ModuleVersSpec structure along other query elements. As the search query string is passed along the procedures, it is possible to retrieved the extra specifier properties from this query string (with getExtraListFromVersSpec procedure).

Extra specifiers are saved as a list of list. Every extra specifier defined in query is set as a list whose first element is extra specifier name, then the other element corresponds to the list of values provided to this argument.

For example, search query mod/1.0 setenv:FOO variant:bar setenv:BAR produces internal representation {setenv FOO} {variant bar} {setenv BAR}.

When OR operation will be supported, search query mod/1.0 setenv:FOO,BAR will produce internal representation {setenv FOO BAR}.

Value specified may contain a space character if it is escaped on command line either by quotes ("prereq:mod@1.0 foo=bar") or backslash (prereq:mod@1.0\ foo=bar). This is especially useful for complex module specification.

Filtering extra specifier results

Every -sc variant of modulefile Tcl command, record their properties in the g_scanModuleElt global dictionary. It is a nested structure that contains at the top level the list of defined extra specifier names. Each of these names is in turn a structure that contains all defined extra specifier values associated to the module name and version defining this extra specifier name and value pair.

For example, when module mod/1.0 defines setenv FOO value in its file, then the global dictionary is updated to add mod/1.0 to the setenv > FOO nested key.

When extra specifier has alias name(s), each of these aliases have their own entry in the global directory. Reusing the previous example, envvar is an alias on setenv extra specifier. When module mod/1.0 defines setenv FOO value, the global dictionary is also updated to add mod/1.0 to the envvar > FOO nested key (in addition to the setenv > FOO nested key.

Such data structure optimizes filtering work: it is done once for all modulefiles after finishing the scan evaluation of all of them. For each extra specifier criteria, goal is to match the corresponding nested key in g_scanModuleElt global directory. Modulefiles to keep in result of those listed as value in every matched nested keys.

When there are several extra specifiers in search query, result are the modules present in the value list of every matched keys (intersection of value list obtained for every extra specifier criterion).

Specific filtering work is achieved for extra specifiers accepting a module specification. See next section.

Filtering module specification

Some extra specifiers accept a module specification as value. It corresponds to all extra specifiers relative to requirements and incompatibilities expressed by modulefiles (prereq, conflict, etc).

Module specification passed as extra specifier value has to be compared to the module specification set in the modulefile definition for corresponding command.

When parsing such extra specifier value, when evaluating command line arguments, module specification is parsed with a specific available module resolution: all matching available modules are recorded into module specification (g_moduleVersSpec). It enables to fetch:

  • every module name and version matching a version list or range specification
  • every generic or fully qualified names

Match against modulefile definitions of such extra specifiers is performed in the same location than for other extra specifiers. It relies on a modEq comparison that has been adapted to also compare alternative names fetched and stored into module specification structure. Relying on modEq procedure, comparison leverages icase and extended_default features.

LIMITATIONS: Current module specification match does not support:

  • Comparison of module alias or symbolic names when used in either extra specifier value or in modulefile definition
  • Version range or list specified in extra specifier value is converted into a list of existing modulefiles, thus a version in such specification that does not correspond to an existing module will not be matched

Variant value comparison is enabled on modEq test. modVariantCmp internal test has been adapted to let a missing variant definition be considered as a match.

Query grammar

In extra match search query, variants are expressed like in select one module context:

  • multiple variants mentioned act as an AND operation
    • module avail mod/1.0 foo=val1 bar=val2
    • means foo equals val1 and bar equals val2
  • same variant mentioned multiple times: only the last mention is retained
    • module avail mod/1.0 foo=val1 foo=val2
    • means foo equals val2

In extra match search query, extra specifiers are expressed with name:value syntax. Using : as separator helps to distinguish from variant specification. As a consequence, such character is not recommended to be part of a module name or version (which was already the case, as : character is also a separator used in environment variables like LOADEDMODULES). As extra specifiers only applies to return all matching modules context, the use of name:value specific syntax may help user to distinguish from the select one module context.

NOTE: use of a --where or --with options was also considered to be able to use a name=value syntax like variant specification. It was preferred to use a different syntax (name:value) to avoid having to type an extra option.

NOTE: if name=value syntax where used for extra specifier, all extra specifier names would have been forbidden to use as variant names.

  • multiple extra specifiers mentioned act as an AND operation
    • module avail mod/1.0 setenv:FOO pushenv:BAR
    • means module defines setenv command to set FOO environment variable and defines pushenv command to set BAR*
  • same extra specifier mentioned multiple times: all mentions retained and act as an AND operation
    • module avail mod/1.0 variant:foo variant:bar
    • means defines variant foo and variant bar

Value of either variant or extra specifier are full name. No wildcard characters are taken into account (they are treated literally).

An error is raised when an empty extra specifier name or value is specified.

FUTURE: expressing an OR operation

  • for instance by mentioning multiple values separated by , character
  • module avail mod/1.0 foo=val1,val2 bar=val2
  • means foo equals val1 or val2 and bar equals val2
  • such syntax is equivalent to version list specification
  • does not seem useful to allow ranges like for version
  • FIXME: allow such syntax on any context or only for return all matching modules context?

FUTURE: expressing a NOT operation

  • adding a character like ~ or ! prior value
  • module avail mod/1.0 foo=!val1 bar=val2
  • means foo equals any value expect val1 and bar equals val2
  • FIXME: allow such syntax on any context or only for return all matching modules context?
  • NOTE: NOT operator is not specified currently on Spack's side. Some discussions mention use of !, which does not work for Tcsh shell

What triggers scan evaluation?

  • everything that triggers an extra match search
  • except tag extra specifier, as tags are defined outside of modulefiles

Specific impact

  • With a contains search match every modulefiles in modulepath are evaluated in scan mode.
    • FUTURE: there may have room for optimisation here