Environment modules

From CUC3
Revision as of 15:36, 9 July 2008 by import>Cen1001 (→‎Private modules)
Jump to navigation Jump to search

The sector notes and the man pages are incredibly useful.

Initialising modules

A shell script inherits the environment its parent, so whatever modules you have loaded are available to any scripts you run. However, the module system is not initialised for non-interactive shells, so a script does not (by default) have access to the module system (i.e. can't change the environment). If you want to be able to change modules in a script, you must initialise the module system: how to do so depends on the language.

Scripts run via cron are started using a non-interactive environment, but have nothing to inherit from. This means if you want to use anything contained in a module in such scripts, you must first initialise the module system and then load the required modules. Initialising the module system does *not* purge the existing modules (see below).

Any modules loaded by a child process do not persist beyond the end of the child process: if a script loads a module, it won't remain in scope once the script ends.

bash

. /usr/share/modules/init/bash initialises modules in bash.

jss43@keiko:~> module list
Currently Loaded Modulefiles:
  1) pgi/64/7.0/7        2) g95/64/64i/0.91     3) mathematica/6.0.3
jss43@keiko:~> more module_examples 
. /usr/share/modules/init/bash                                 # This initialises the module system in bash.
module load ifort
module list
jss43@keiko:~> bash module_examples
Currently Loaded Modulefiles:                                  # module_examples loads the ifort module and inherits modules already loaded.
  1) pgi/64/7.0/7        3) mathematica/6.0.3
  2) g95/64/64i/0.91     4) ifort/32/9.1/040
jss43@keiko:~> module list
Currently Loaded Modulefiles:                                  # The ifort module does not remain loaded beyond the end of module_examples.
  1) pgi/64/7.0/7        2) g95/64/64i/0.91     3) mathematica/6.0.3

python

Similarly to bash, in /usr/share/modules/init there is a python script to initialise the module system. It doesn't work due to a bug in modules' auto-configuration causes an incorrect path to be set. A correct version can be downloaded here---save it as python_modules.py. (This annoying bug is going to be fixed in the SuSE 10.3 image --Catherine 16:30, 9 July 2008 (BST)) You can initialise modules using either execfile (specifying the full path) or import (where it must be in the current directory or in your PYTHONPATH, and the .py is left out of the module name). module('command') then works, where command is one of the usual module commands we use in the terminal.

jss43@keiko:~> python
>>> execfile('python_modules.py')
>>> modules('list')
Currently Loaded Modulefiles:
  1) pgi/64/7.0/7        2) g95/64/64i/0.91     3) mathematica/6.0.3
jss43@keiko:~> python
>>> from python_modules import *
>>> modules('list')
Currently Loaded Modulefiles:
  1) pgi/64/7.0/7        2) g95/64/64i/0.91     3) mathematica/6.0.3

If you use ipython (if you don't, you should), then you can implement the module commands as a "magic" command (type magic at the ipython prompt). The script needed is here---save it to ~/.ipython/modules_magic.py. You can add it to the standard profile (ipythonrc):

execfile ~/.ipython/modules_magic.py

If you are using a later version of ipython, then there will be a ipy_user_conf.py file in your .ipython directory. To implement the module magic command in this case, add

import_all("modules_magic")

in the main() subroutine.

You now have the module command defined in ipython which can be used exactly as in bash:

jss43@keiko:~> ipython
Python 2.5 (r25:51908, Jan 10 2008, 18:01:52) 
Type "copyright", "credits" or "license" for more information.

IPython 0.8.3.svn.r3001 -- An enhanced Interactive Python.
?         -> Introduction and overview of IPython's features.
%quickref -> Quick reference.
help      -> Python's own help system.
object?   -> Details about 'object'. ?object also works, ?? prints more.

In [1]: module list
Currently Loaded Modulefiles:
  1) pgi/64/7.0/7        2) g95/64/64i/0.91     3) mathematica/6.0.3

Private modules

It is possible to extend the module system by creating your own modules. First of all do module load use.own. The directory ~/privatemodules is created the first time you do this. ~/privatemodules also contains a template (null) from which you can create module configuration files. If you do module avail after loading the use.own module, you'll see there's a new section: /home/${USER}/privatemodules. This contains any modules you create.

jss43@keiko:~> module avail
[...]
-------------------------- /home/jss43/privatemodules --------------------------
gcc-4.2   lapack-64

My private modules can be used exactly as the standard modules.

Module configuration files are in Tcl, but we can avoid knowing anything about Tcl by shamelessly copying the existing module files (in /usr/local/shared/Modules/modulefiles). As an example, here are two module files I have:

gcc-4.2

Following on from the installation process described here. I based this on the g95 module file.

#%Module1.0#####################################################################
##
## 
##

set base "/home/jss43/src/gcc-4.2"
set version "4.2"
set compilerhome $base

proc ModulesHelp { } {
	global compilerhome
	global version
	puts stderr "\tgcc - loads version $version of the gcc compiler suite."
	puts stderr "\tTHIS VERSION USES A 64-BIT INTEGER"
	puts stderr "\tThis adds $compilerhome/bin to the PATH"
	puts stderr "\n\tgcc contains free c and F95 compilers."
	puts stderr "\tThere are extensive man and info pages."
}

module-whatis "Loads version $version of the gcc compiler"

prepend-path PATH $compilerhome/bin
prepend-path LD_LIBRARY_PATH $compilerhome/lib64
prepend-path MANPATH $compilerhome/man
prepend-path INFOPATH $compilerhome/info

It is important to prepend the paths: earlier versions of gcc and gfortran exist on the system PATH already, so we must make the shell find the user-installed gcc-4.2 suite first.

If you want to make private modulefiles for libraries it may be useful to know that the local compilers have been wrapped to honour the variables LIBRARY_PATH and CPATH . LIBRARY_PATH is treated as a list of directories to search for libraries when linking, and CPATH is a list of directories to search for header files. The contents of LIBRARY_PATH are also passed to the linker as the runpath setting for the resulting binary. This means you can do away with -L and -I options when compiling, and the runpath thing means you can often (but not always) get away without resorting to setting LD_LIBRARY_PATH .

lapack

Following on from the installation process described here. I based this on the atlas/32/P4SSE2 module file.

#%Module1.0#####################################################################
##
## 
##

conflict atlas acml

set root /home/jss43/src/lib/lapack-3.1.1
set version 3.1.1

proc ModulesHelp { } {
        global root
	puts stderr "\t[module-info name] - loads ATLAS maths library"
	puts stderr "\tThis is a well-known linear algebra library."
	puts stderr "\tThis version was compiled locally using the"
	puts stderr "\tdefault options."
	puts stderr "\tFor documentation see the homepage:"
	puts stderr "\thttp://math-atlas.sourceforge.net/"
}

module-whatis "Loads version $version of the lapack library"

prepend-path LIBRARY_PATH $root
prepend-path LD_LIBRARY_PATH $root
prepend-path MANPATH $root/manpages/man

Development work

Private modules make it very easy to switch between development branches and/or production version code:

jss43@keiko:~> module load use.own code-clean
jss43@keiko:~> which neci.x
/home/jss43/CPMD/v3.11.1/CLEAN/NECI/neci.x
jss43@keiko:~> module  swap code-clean code-dev
jss43@keiko:~> which neci.x
/home/jss43/CPMD/v3.11.1/QMC_branch/NECI/neci.x