From Fedora Project Wiki
m (removed draft warning as this has been approved both by FPC and FESCo)
(Update with Lmod additions)
Line 3: Line 3:
 
When one has multiple programs serving the same purpose (for instance SMTP servers such as sendmail, exim and postfix; or print servers such as lprng and cups), it is usual to wrap these using alternatives. Alternatives provides a clean way to have many types of software serving the same purpose installed at the same time and have the commands such as <code>mail</code> and <code>lpr</code> point to the wanted versions.
 
When one has multiple programs serving the same purpose (for instance SMTP servers such as sendmail, exim and postfix; or print servers such as lprng and cups), it is usual to wrap these using alternatives. Alternatives provides a clean way to have many types of software serving the same purpose installed at the same time and have the commands such as <code>mail</code> and <code>lpr</code> point to the wanted versions.
  
 +
However, when there are multiple variants that each serve the needs of some user and thus must be available simultaneously by users, the alternatives system simply isn't enough since it is system-wide. This has been reality on supercomputers and clusters for eons, and multiple implementations of a solution has been developed: [http://modules.sourceforge.net/ environment modules] and [https://www.tacc.utexas.edu/tacc-projects/lmod Lmod].  Fedora currently makes use of this primarily for handling switching between differen MPI implementations.
  
However, when there are multiple variants that each serve the needs of some user and thus must be available simultaneously by users, the alternatives system simply isn't enough since it is system-wide. This has been reality on supercomputers and clusters for eons, and a solution has been developed: [http://modules.sourceforge.net/ environment modules].
+
Environment modules are also useful in situations where a package wants to install binaries that use common names and might conflict file in or otherwise pollute /usr/bin. Use must then load an environment module before being able to make use of those programs.
  
 
== Using environment modules ==
 
== Using environment modules ==
  
 
To see what modules are available, run <code>$ module avail</code>.
 
To see what modules are available, run <code>$ module avail</code>.
To load a module run e.g. <code>$ module load openmpi-i386</code>.
+
To load a module run e.g. <code>$ module load mpi/openmpi-x86_64</code>.
To unload a module, run e.g. <code>$module unload openmpi-i386</code>.
+
To unload a module, run e.g. <code>$module unload mpi/openmpi-x86_64</code>.
  
The upstream documentation for the module command is available [http://modules.sourceforge.net/man/module1.html here].
+
The upstream documentation for the module command is available [http://modules.sourceforge.net/man/module1.html here] or with <code>man module</code>.
  
 
== Creating environment modules ==
 
== Creating environment modules ==
  
{{admon/important|Packaging note|When creating RPMs containing module files, be sure to <code>Requires: environment-modules</code> for directory ownership and usability.}}
+
{{admon/important|Packaging note|When creating RPMs containing module files, be sure to specify <code>Requires: environment(modules)</code> for directory ownership and usability, and <code>BuildRequires: environment(modules)</code> for the %{_modulesdir} macro.}}
  
To create an environment module, place a module file into <code>/etc/modulefiles/</code>. The directory <code>/usr/share/Modules/modulefiles</code> is to be used only for internal modules of environment-modules. Besides this, installing a module file into an arbitrary directory currently makes module unloading not working (see [https://bugzilla.redhat.com/show_bug.cgi?id=513583 BZ#513583])
+
To install an environment module, place a module file into <code>%{_modulesdir}</code>, which should evaluate to <code>/usr/share/modulefiles</code>.  This macro is available in Fedora 21+ and EPEL 7+. The directory <code>/usr/share/Modules/modulefiles</code> is to be used only for internal modules of environment-modules. <code>/etc/modulefiles</code> is available to local system administrator use.
  
 
{{admon/warning|Multilib packages|Suffix the module file name with the architecture to prevent clashes from multilib/multiarch packages.}}
 
{{admon/warning|Multilib packages|Suffix the module file name with the architecture to prevent clashes from multilib/multiarch packages.}}
  
The module files are plain text with a tcl syntax, for instance an environment module for 32-bit OpenMPI <code>openmpi-i386</code>:
+
The module files are plain text with optional tcl syntax, for instance an environment module for 64-bit OpenMPI <code>mpi/openmpi-x86_64</code>:
  
 
<pre>
 
<pre>
 
#%Module 1.0
 
#%Module 1.0
#  
+
#
# OpenMPI module for use with 'environment-modules' package:
+
# OpenMPI module for use with 'environment-modules' package:
#  
+
#
prepend-path            PATH            /usr/lib/openmpi/bin
+
conflict                mpi
prepend-path            LD_LIBRARY_PATH /usr/lib/openmpi/lib
+
prepend-path            PATH            /usr/lib64/openmpi/bin
setenv                  MPI_BIN        /usr/lib/openmpi/bin
+
prepend-path            LD_LIBRARY_PATH /usr/lib64/openmpi/lib
setenv                  MPI_LIB        /usr/lib/openmpi/lib
+
prepend-path            PYTHONPATH      /usr/lib64/python2.7/site-packages/openmpi
 +
prepend-path            MANPATH        /usr/share/man/openmpi-x86_64
 +
setenv                  MPI_BIN        /usr/lib64/openmpi/bin
 +
setenv                  MPI_SYSCONFIG  /etc/openmpi-x86_64
 +
setenv                  MPI_FORTRAN_MOD_DIR    /usr/lib64/gfortran/modules/openmpi-x86_64
 +
setenv                  MPI_INCLUDE    /usr/include/openmpi-x86_64
 +
setenv                  MPI_LIB        /usr/lib64/openmpi/lib
 +
setenv                  MPI_MAN        /usr/share/man/openmpi-x86_64
 +
setenv                  MPI_PYTHON_SITEARCH    /usr/lib64/python2.7/site-packages/openmpi
 +
setenv                  MPI_COMPILER    openmpi-x86_64
 +
setenv                  MPI_SUFFIX      _openmpi
 +
setenv                  MPI_HOME        /usr/lib64/openmpi
 
</pre>
 
</pre>
  
 
The module file begins with the magic cookie <code>#%Module <version></code>, where <code><version></code> is the version of the module file used. The current version is 1.0.
 
The module file begins with the magic cookie <code>#%Module <version></code>, where <code><version></code> is the version of the module file used. The current version is 1.0.
  
The above commands prepends the path with the bindir of the 32-bit OpenMPI (compiled with GCC) and adds the relevant library path. Then it sets five environment variables.
+
The above commands prepends the path with the bindir of the 64-bit OpenMPI (compiled with GCC) and adds the relevant library path. Then it sets various environment variables.
  
It is also possible to set <code>CFLAGS</code> and <code>LDFLAGS</code> with the above manner, but in the case of MPI compilers it is not necessary since the compilers are invoked with the <code>mpicc</code>, <code>mpicxx</code>, <code>mpif77</code> and <code>mpif90</code> wrappers that already contain the necessary include and library paths. Also, in the case of development packages an override of <code>CFLAGS</code> and/or <code>LDFLAGS</code> is not sane,  
+
It is also possible to set <code>CFLAGS</code> and <code>LDFLAGS</code> with the above manner, but in the case of MPI compilers it is not necessary since the compilers are invoked with the <code>mpicc</code>, <code>mpicxx</code>, <code>mpif77</code> and <code>mpif90</code> wrappers that already contain the necessary include and library paths. Also, in the case of development packages an override of <code>CFLAGS</code> and/or <code>LDFLAGS</code> is not sane, as it may cause trouble in building RPMs as it overrides <code>%{optflags}</code>.
as it may cause trouble in building RPMs as it overrides <code>%{optflags}</code>.
 
  
The upstream documentation for module files is available [http://modules.sourceforge.net/man/modulefile4.html here].
+
The upstream documentation for module files is available [http://modules.sourceforge.net/man/modulefile4.html here] or with <code>man modulefile</code>.
  
 +
== Switching between module implementations ==
 +
 +
Switching between the environment-modules and Lmod implementations is done via alternatives.  The shell init scripts /etc/profile.d/modules.{csh,sh} are links to /etc/alternatives/modules.{csh.sh} and can be manipulated with the alternatives command.
 +
 +
== Lmod ==
 +
 +
[https://www.tacc.utexas.edu/tacc-projects/lmod Lmod] is an environment modules implementation written in Lua, and can make use of module files written in Lua as well as Tcl.  Such files have a ".lua" extensions.  However, such files '''must not''' be installed /usr/share/modulefiles so as to not cause issues when the environment-modules package is in use.
 
[[Category:Packaging guidelines drafts]]
 
[[Category:Packaging guidelines drafts]]

Revision as of 22:12, 14 April 2014

Introduction

When one has multiple programs serving the same purpose (for instance SMTP servers such as sendmail, exim and postfix; or print servers such as lprng and cups), it is usual to wrap these using alternatives. Alternatives provides a clean way to have many types of software serving the same purpose installed at the same time and have the commands such as mail and lpr point to the wanted versions.

However, when there are multiple variants that each serve the needs of some user and thus must be available simultaneously by users, the alternatives system simply isn't enough since it is system-wide. This has been reality on supercomputers and clusters for eons, and multiple implementations of a solution has been developed: environment modules and Lmod. Fedora currently makes use of this primarily for handling switching between differen MPI implementations.

Environment modules are also useful in situations where a package wants to install binaries that use common names and might conflict file in or otherwise pollute /usr/bin. Use must then load an environment module before being able to make use of those programs.

Using environment modules

To see what modules are available, run $ module avail. To load a module run e.g. $ module load mpi/openmpi-x86_64. To unload a module, run e.g. $module unload mpi/openmpi-x86_64.

The upstream documentation for the module command is available here or with man module.

Creating environment modules

Important.png
Packaging note
When creating RPMs containing module files, be sure to specify Requires: environment(modules) for directory ownership and usability, and BuildRequires: environment(modules) for the %{_modulesdir} macro.

To install an environment module, place a module file into %{_modulesdir}, which should evaluate to /usr/share/modulefiles. This macro is available in Fedora 21+ and EPEL 7+. The directory /usr/share/Modules/modulefiles is to be used only for internal modules of environment-modules. /etc/modulefiles is available to local system administrator use.

Warning.png
Multilib packages
Suffix the module file name with the architecture to prevent clashes from multilib/multiarch packages.

The module files are plain text with optional tcl syntax, for instance an environment module for 64-bit OpenMPI mpi/openmpi-x86_64:

#%Module 1.0
#
#  OpenMPI module for use with 'environment-modules' package:
#
conflict                mpi
prepend-path            PATH            /usr/lib64/openmpi/bin
prepend-path            LD_LIBRARY_PATH /usr/lib64/openmpi/lib
prepend-path            PYTHONPATH      /usr/lib64/python2.7/site-packages/openmpi
prepend-path            MANPATH         /usr/share/man/openmpi-x86_64
setenv                  MPI_BIN         /usr/lib64/openmpi/bin
setenv                  MPI_SYSCONFIG   /etc/openmpi-x86_64
setenv                  MPI_FORTRAN_MOD_DIR     /usr/lib64/gfortran/modules/openmpi-x86_64
setenv                  MPI_INCLUDE     /usr/include/openmpi-x86_64
setenv                  MPI_LIB         /usr/lib64/openmpi/lib
setenv                  MPI_MAN         /usr/share/man/openmpi-x86_64
setenv                  MPI_PYTHON_SITEARCH     /usr/lib64/python2.7/site-packages/openmpi
setenv                  MPI_COMPILER    openmpi-x86_64
setenv                  MPI_SUFFIX      _openmpi
setenv                  MPI_HOME        /usr/lib64/openmpi

The module file begins with the magic cookie #%Module <version>, where <version> is the version of the module file used. The current version is 1.0.

The above commands prepends the path with the bindir of the 64-bit OpenMPI (compiled with GCC) and adds the relevant library path. Then it sets various environment variables.

It is also possible to set CFLAGS and LDFLAGS with the above manner, but in the case of MPI compilers it is not necessary since the compilers are invoked with the mpicc, mpicxx, mpif77 and mpif90 wrappers that already contain the necessary include and library paths. Also, in the case of development packages an override of CFLAGS and/or LDFLAGS is not sane, as it may cause trouble in building RPMs as it overrides %{optflags}.

The upstream documentation for module files is available here or with man modulefile.

Switching between module implementations

Switching between the environment-modules and Lmod implementations is done via alternatives. The shell init scripts /etc/profile.d/modules.{csh,sh} are links to /etc/alternatives/modules.{csh.sh} and can be manipulated with the alternatives command.

Lmod

Lmod is an environment modules implementation written in Lua, and can make use of module files written in Lua as well as Tcl. Such files have a ".lua" extensions. However, such files must not be installed /usr/share/modulefiles so as to not cause issues when the environment-modules package is in use.