Modules and bcmodule
The Baseline Configuration Team provides bcmodule
, a command which executes like the standard
module
command but has numerous improvements and new features. Users can think of bcmodule
as a total replacement for module, though technically it is a "wrapper" which calls module
. The two
commands can be used interchangeably in the same shell, except when one of the new features of bcmodule
is needed.
First we give an explanation of modules in general and then we discuss bcmodule
in particular.
What are modules and what do they do?
The purpose of the module command is to establish the proper environment in the user's shell for running an application. The shell itself contains information in two types of variables that are called "shell variables" and "environment variables." The information in these variables is used to locate executables, data files and shared libraries. Having the shell environment variables set correctly can make the difference between being able to run an application and not.
A module
command for an application typically augments the user's PATH
variable so that the
executable for that application can be located. It may also set an environment variable, such as LD_LIBRARY_PATH
,
which tells the operating system where to look for libraries the executable requires to run. It may set other environment
variables that contain the location of required data files. Without modules, users would need to know where an
application resides, how to add that path to the PATH
variable, which libraries are needed, where
they are, how to tell the operating system how it can find them, etc. So using modules makes computing much
easier, even for experts.
How does one use modules?
The basics one needs to know about modules include the module command, the module sub-commands, module directories, and modulefiles.
Let's start with the modulefiles. Each version of an application, compiler, MPI, etc. will have its own modulefile,
which is a file containing the information required to initialize the shell environment to run that version of the
application, compiler, or MPI. To configure a shell, a user executes a module load
on the modulefile.
This means that the module
command reads the modulefile, and modifies the shell accordingly.
Strictly speaking, module
is the command, but instead of speaking of "loading a modulefile", one usually
speaks of "loading a module".
Before a user can load a module, the module command has to know where the modulefile is. To find a modulefile, a user's
shell must be aware of the directory that the modulefile resides in. The module command finds a modulefile using the same
method the shell uses to find a command: it searches along a path,
which is an ordered list of directories,
until it finds the file it is looking for. This path is stored in the shell as the environment variable MODULEPATH. You
can see its value by executing echo $MODULEPATH.
To set this path to include directory_1,
one
executes module use directory_1.
In executing this, the module command reads the current value of
$MODULEPATH
and adds directory_1
to it, thus modifying your shell, which is now aware of one
more directory where modulefiles can be found.
Now that the module command can find the modulefile, we are ready to have the modulefile modify a shell (i.e. to have
it "work"). This is done by executing a module load,
such as module load compiler/gcc/4.9.3.
The load
in this command is called the sub-command, and the modulefile is compiler/gcc/4.9.3.
The portion of the full path to the modulefile that precedes the modulefile name is the directory that was added to
MODULEPATH earlier by module use.
To remove a directory from your MODULEPATH, execute module unuse
directory_2.
This will make the modulefiles in directory_2
disappear from your shell's point of
view.
Module commands always have the form module switches sub-command args
. To say a module is loaded means
that it is in effect (i.e. your shell is configured according to that modulefile). If a user wishes to run a different
version of the same application, then he/she must unload
the current module, and then execute a module
load on the desired version. A module unload
removes the additions to the shell environment that the
corresponding module load had made. Executing module swap
can be used to unload one module and load
another in one command. A module can load one or more other modules.
Users typically have multiple modules loaded at any one time (just not multiple versions of a particular application).
To see which modules are currently loaded, execute module list.
To see which modules one can load, execute
module avail.
Executing module use directory
as described above will make more modules
available to your shell. To see what a module does to your shell, execute module show
To see
a list of all module
sub-commands execute module with no arguments, or module --help
(notice
there are two dashes).
A summary of the more important module
subcommands is given below:
Command | Details |
---|---|
module use mod_directory | add a directory to $MODULEPATH |
module unuse mod_directory | remove a directory from $MODULEPATH |
module load modulefile | modifies the shell to run an application |
module unload modulefile | undoes what the module load did |
module swap mod_a mod_b | unload module mod_a and load mod_b |
Command | Details |
---|---|
module show module_name | show what the module does to your shell |
module list | list which modules are currently loaded |
module avail | list which modules could be loaded |
The staff at the DSRCs maintains modulefiles, some of which come from vendors, and some are generated locally. Users who run their own codes can even write their own modulefile if they wish. To do so, you may copy and then amend an existing modulefile, or ask for help from the HPC Help Desk.
The BCT command "bcmodule"
The command bcmodule
works in all six shells supported by the HPCMP: sh, bash, ksh, zsh, csh,
and tcsh. Both module and bcmodule should be initialized by default upon login. Execute bcmodule
to see the help menu of sub-commands.
Since bcmodule can be thought of as a replacement for module, it can be used to list the modules that are
currently loaded. Below illustrates an example, using the C-shell (csh or tcsh). Notice that sub-command
list has been abbreviated to li
; such abbreviations are optional.
$ bcmodule li Currently Loaded Modulefiles: 1) compiler/intel/2017.1.132 2) mpi/sgimpt/2.15 3) Master>
So three modules are loaded. To see what a particular module does to your shell, execute the show
sub-command as shown below.
$ bcmodule show Master ------------------------------------------------------------------- /p/app/modulefiles/unsupported/Master: setenv BC_HOST systemname setenv BC_CORES_PER_NODE 40 setenv BC_STANDARD_NODE_CORES 40 setenv BC_ACCELERATOR_NODE_CORES 40 setenv BC_BIGMEM_NODE_CORES 40 setenv BC_PHI_NODE_CORES 0 setenv BC_NODE_TYPE LOGIN setenv MODULE_VERSION 3.2.10 setenv CSI_HOME /usr/cta setenv DAAC_HOME /usr/cta/DAAC setenv PET_HOME /usr/cta/pet setenv WORKDIR /p/work1/username setenv SAMPLES_HOME /usr/cta/SCR setenv CENTER /p/cwfs/username setenv MPSCP_CONFIG_FILENAME /etc/mpscp_config setenv MPSCP_BLOCKED_FILE /etc/mpscp_blocked_ports setenv PROJECTS_HOME /usr/cta/unsupported setenv KRB5HOME /usr/krb5/bin setenv KRB5_HOME /usr/krb5/bin setenv COST_HOME /p/app/unsupported/COST setenv JAVA_HOME /opt/rh/rh-eclipse46/root/usr/lib/jvm/java setenv ARCHIVE_HOME /admin/username setenv ARCHIVE_HOST archive.domain prepend-path MANPATH /usr/share/man:/usr/local/man prepend-path PATH /usr/local/bin:/usr/krb5/bin prepend-path PATH //usr/cta/unsupported/BC prepend-path PATH /usr/people/PBS/SLB module load compiler/intel/2017.1.132 mpi/sgimpt/2.15 -------------------------------------------------------------------
The first line (starting with /usr/cta) shows where the Master
modulefile is located. This
is followed by 23 setenv
lines, each of which sets the value of an environment variable. When
you run a Linux command or execute an application, it can extract the value of an environment variable
defined in the shell. For example, when I execute the command archive
to archive a file, the
archive command knows where to copy the file based on my shell's value of the variable ARCHIVE_HOME,
which is my personal directory /admin/username
. In this case, the Master module sets a unique
value for ARCHIVE_HOME
for each user, so that one user's files are not archived into another
user's directory.
The last four lines of the module modify an existing shell variable. The first prepend-path
module statement prepends two directories (/usr/share/man and /usr/local/man) to the variable MANPATH, which
is used in finding man
pages (Linux online documentation). The last three lines each insert
one or two directories at the beginning of the variable PATH,
which is used to find Linux commands
as well as application scripts and executables.
Here is a list of improvements provided by bcmodule
that are not available in module
:
- It translates native modulefile names into BCT-specified modulefile names for greater uniformity of modulefile
names across different systems in the HPCMP. Users can use either the BCT modulefile name or the native modulefile
name interchangeably. Two new sub-commands (tran and show_all_trans) show the translation of modulefile names from
native to BCT and vice-versa, as illustrated below.
$ bcmodule tran compiler/gcc/6.2.0 real module name is gcc/6.2.0 BCT module name is compiler/gcc/6.2.0
- It returns non-zero return codes when errors occur.
- Output from bcmodule goes to stdout, which allows users to pipe the output into subsequent Linux commands
such as
grep
ormore
, as illustrated below.$ bcmodule avail | grep perftools cray-petsc-complex-64/3.6.3.0 perftools-base/6.3.0 cray-petsc-complex-64/3.7.4.0 perftools-base/6.3.2 cray-petsc/3.6.3.0 perftools/6.4.4
This does not work withmodule
since it writes its output to standard error. Each line of output from the bcmodule command above has perftools in it, but it also contains modules that have nothing to do with perftools. This is becausegrep
is grabbing entire lines. Next we will show a better bcmodule feature for seeing only the perftools related modules. - A new sub-command
find
searches through all known modulefile directories (not just those in use) and lists all modulefile names it finds that contain the given string searched for, thus helping users find modulefiles when the exact name is uncertain and/or the location is unknown. An illustration of the sub-commandfind
is included below.$ bcmodule find perftools /opt/cray/modulefiles/perftools-lite total 36 -rwxr-xr-x 1 root root 7794 Jan 15 2015 6.2.2 -rwxr-xr-x 1 root root 7201 Aug 25 2015 6.2.5 -rw-r--r-- 1 root root 7616 Oct 19 2015 6.3.0 -rw-r--r-- 1 root root 7817 Apr 13 2016 6.3.2 -rw-r--r-- 1 root root 1506 Jan 25 2017 6.4.4 /opt/cray/modulefiles/perftools-base total 28 -rw-r--r-- 1 root root 7707 Oct 19 2015 6.3.0 -rw-r--r-- 1 root root 8015 Apr 13 2016 6.3.2 -rw-r--r-- 1 root root 9707 Jan 25 2017 6.4.4 /opt/cray/modulefiles/perftools total 36 -rwxr-xr-x 1 root root 7794 Jan 15 2015 6.2.2 -rwxr-xr-x 1 root root 7201 Aug 25 2015 6.2.5 -rw-r--r-- 1 root root 7560 Oct 19 2015 6.3.0 -rw-r--r-- 1 root root 7761 Apr 13 2016 6.3.2 -rw-r--r-- 1 root root 1506 Jan 25 2017 6.4.4
Here the output format is a bit different, but all the information you need to locate the perftools modules is given. And the timestamps of the files is also given, which is not the case formodule
commands. - A new sub-command
find_in_module
searches for a modulefile which contains the given string, thus locating the modulefile not by a string in its name (the sub-commandfind
described above does that), but by finding a modulefile that performs any action involving the string. For example,bcmodule find_in_module XYZ
finds any modulefile that sets the environment variable XYZ, or that sets any environment variable with XYZ as part of the name, or augments any PATH with a directory having the pattern XYZ, etc.An illustration of the subcommand
find_in_module
is included below. Each modulefile listed has the stringARCH
somewhere in its contents.$ bcmodule find_in_module ARCH /p/app/modulefiles/unsupported/master /p/app/modulefiles/unsupported/.Master.old /p/app/modulefiles/unsupported/Master /p/app/modulefiles/apps/fluent/172~ /p/app/modulefiles/apps/fluent/180 /p/app/modulefiles/apps/fluent/182
- A new sub-command
inuse
lists all module directories currently in use. - A new sub-command
show_all_dirs
lists all known module directories so that users can easily add module directories for greater access to modulefiles. - Even easier, the new sub-command
use_all_dirs
adds all known module directories so that users automatically use all configured module directories when loading and listing available modules.
Below demonstrates how the number of modules available increases (from 41 lines of output to 100 lines) when all (system configured) modulefile directories are added using the
use_all_dirs
option.
$ bcmodule avail | wc -l 41 $ bcmodule use_all_dirs $ bcmodule avail | wc -l 100These three commands show that by executing
bcmodule use_all_dirs,
the list of module directories
known to the shell increases such that an additional 59 lines worth of modules are now locatable, and can thus
be loaded. The inuse
and show_all_dirs
sub-commands mentioned above can be used to
see those directories.
The term "system configured" used above refers to the commonly used module directories configured for bcmodule by the system admin, but not directories containing only modules for certain projects. Users who wish to always have their project specific module directory used can do so by including a
module use
command in their personal shell initialization script.
count
counts modulefiles and modulefile directories currently used.Tired of getting too much output from module avail
? The new bcmodule features find
,
-compress
, -sf
, -xf
, -sd
, and -xd
all make
finding modulefiles much easier.
-compress
removes the module version and lists each "family"
of modules once instead of once per version. On one system, this reduced the number of lines of output
from 202 to 51.
Below includes an example where module avail,
for the directory /opt/modulefiles, gives 21
lines of output whereas the -compress
option in bcmodule shortens the output to just two lines:
$ module avail --------------------------------------- /opt/modulefiles ---------------------------------------- cce/8.3.14(default) intel/14.0.2.144 cce/8.3.5 intel/15.0.1.133 cce/8.3.6 intel/16.0.0.109 cce/8.3.9 intel/17.0.1.132 cce/8.4.0 java/jdk1.7.0_45 cce/8.4.1 java/jdk1.8.0_51(default) cce/8.4.5 modules/3.2.10.3(default) cce/8.5.6 modules/3.2.10.5 chapel/1.9.0.1(default) modules/3.2.6.7 ddt/4.2.2.6_39982(default) pbs ddt/5.0.1.3_42607 pgi/14.10.0 ddt-memdebug/4.2.2.6_39982(default) pgi/14.10.0-acc ddt-memdebug/5.0.1.3_42607 pgi/15.3.0(default) eswrap/1.3.3-1.020200.1278.0(default) pgi/15.3.0-acc gcc/4.8.1 pgi/15.7.0 gcc/4.9.2 pgi/15.7.0-acc gcc/4.9.3(default) pgi/16.10.0 gcc/5.1.0 pgi/16.10.0-acc gcc/5.3.0 xc-sysroot/5.2.40 gcc/6.1.0 xc-sysroot/5.2.82(default) gcc/6.2.0 $ bcmodule avail -compress --------------------------------------- /opt/modulefiles --------------------------------------- cce compiler/gcc compiler/java ddt ddt-memdebug eswrap modules pbs xc-sysroot chapel compiler/intel compiler/pgi
a.
-sf pattern
lists only modulefiles having pattern
in the name.b.
-xf pattern
lists only modulefiles not having pattern
in the modulefile name.An illustration of the sub-command
av
with option -sf
is below.$ bcmodule av -sf perftool ------------------------------------ /opt/cray/modulefiles ------------------------------------- perftools-base/6.3.0 perftools-lite/6.2.5(default) perftools-lite/6.4.4 perftools/6.3.0 perftools-base/6.3.2 perftools-lite/6.3.0 perftools/6.2.2 perftools/6.3.2 perftools-base/6.4.4 perftools-lite/6.3.2 perftools/6.2.5(default) perftools/6.4.4 perftools-lite/6.2.2
a.
-sd dir
lists only modulefiles in directories having dir
as part of the directory name.b.
-xd dir
lists only modulefiles in directories not having dir
as part of the directory name.The two commands
bcmodule find pattern
and module avail –sf pattern
are very similar, but not identical.
Their output formats are different, but more importantly, find
searches through all configured modulefile directories,
whereas the second command only searches through directories you have in use.
The new bcmodule does a slightly better job than module of "cramming" as many columns of output as it can to your screen to reduce the number of lines of output. In the process of reformatting the output, it sometimes alphabetizes the modulefiles slightly differently.
Happy moduling!