1. 什么是module

Environment Modules包通过模块文件动态修改用户的环境。

命令 作用
module avail 或 module av 查看系统中可用的软件
module add 或 module load 加载模块
module rm 或 unload 卸载模块
module list 或 module li 显示已加载模块
module purge 卸载所有模块
module show 显示模块配置文件
module swap 或 module switch 将模块1 替换为 模块2
module help 查看具体软件的信息

2. module使用初级

2.1 查看所有模块

$ module av
------------- /usr/share/Modules/3.2.10/Applications -------------
bedtools2/2.25.0-gcc4.8         
bedtools2/2.26.0-gcc4.8(default)

上面的代码中,行首为$符的行是用户输入的命令,其他行为显示的结果,同下。

说明:

  1. 有2个module模块
  2. 模块名称为bedtools2/2.25.0-gcc4.8bedtools2/2.26.0-gcc4.8
  3. 模块名通常的命令方式为:软件名/版本-[编译器名]-[MPI编译器名]
  4. bedtools2/2.26.0-gcc4.8模块后面有一个default,表示它是bedtools2软件的默认版本,即只写bedtools2 即表示 bedtools2/2.26.0-gcc4.8

在平台上有数百个可用module模块,此处只列2个教学用。

加载

$ bedtools2/2.25.0-gcc4.8
$ 

没有任何报错表明加载成功。

2.2 查看已加载模块

$ module li
Currently Loaded Modulefiles:
  1) bedtools2/2.25.0-gcc4.8

2.3 使用已加载模块

我们看到bedtools2/2.25.0-gcc4.8已经成功加载了,用户可以直接调用bedtools2软件的相关命令了,例如:

$ bedtools
bedtools: flexible tools for genome arithmetic and DNA sequence analysis.
usage:    bedtools <subcommand> [options]

The bedtools sub-commands include:

[ Genome arithmetic ]
    intersect     Find overlapping intervals in various ways.
    window        Find overlapping intervals within a window around an interval.
...

友情提示:在超算中心使用,登陆节点与计算节点是分开的,因此请使用作业调度系统提交任务。

2.4 卸载模块

$ module rm bedtools2/2.25.0-gcc4.8
$ module li
No Modulefiles Currently Loaded.

到此处,我们学到了:

  1. 如何查看所有的module模块 module av
  2. 如何加载一个模块 module add 模块名
  3. 如何查看已加载的模块 module li
  4. 如何卸载一个模块 module rm 模块名

3. module使用中级

3.1 显示模块详细信息

$ module show bedtools2/2.26.0-gcc4.8
-------------------------------------------------------------------
/usr/share/Modules/Applications/bedtools2/2.26.0-gcc4.8:

module-whatis    bedtools2/2.26.0-gcc4.8
conflict         bedtools2
prepend-path     PATH /THL6/software/bedtools2/2.26.0-gcc4.8/bin
-------------------------------------------------------------------

3.2 替换模块

当我们加载了bedtools2/2.25.0-gcc4.8模块后,希望更改为bedtools2/2.26.0-gcc4.8模块,应该怎么做呢?

让我们先这样试一试:

$ module li
Currently Loaded Modulefiles:
  1) bedtools2/2.25.0-gcc4.8
$ module rm  bedtools2/2.26.0-gcc4.8
$ module add bedtools2/2.26.0-gcc4.8
bedtools2/2.26.0-gcc4.8(25):ERROR:150: Module 'bedtools2/2.26.0-gcc4.8' 
    conflicts with the currently loaded module(s) 'bedtools2/2.25.0-gcc4.8'
bedtools2/2.26.0-gcc4.8(25):ERROR:102: Tcl command execution failed: 
    conflict   bedtools2

报错了!我们仔细观察这个错误ERROR conflict bedtools2,想一想这是为什么?

bedtools2软件有2个版本的,我们已经加载了一个了,要不把之前的先卸载了试试?

$ module li
Currently Loaded Modulefiles:
  1) bedtools2/2.25.0-gcc4.8

$ module rm bedtools2/2.25.0-gcc4.8
$ module rm bedtools2/2.26.0-gcc4.8

$ module li
Currently Loaded Modulefiles:
  1) bedtools2/2.26.0-gcc4.8

成功了!因此,同类型的软件只能加载一个,加载新的之前要卸载旧的,否则就conflict 冲突了。

可是,更换版本是一个很常见的操作,有没有更简便的方法呢?有的,请往下看。

更简单的方法为:

$ module li
Currently Loaded Modulefiles:
  1) bedtools2/2.25.0-gcc4.8

$ module swap bedtools2/2.25.0-gcc4.8 bedtools2/2.26.0-gcc4.8

$ module li
Currently Loaded Modulefiles:
  1) bedtools2/2.26.0-gcc4.8

使用module swap 旧模块名 新模块名 即可实现模块替换。

3.3 卸载所有模块

当加载的模块非常多的时候,我们希望一次性都卸载了,命令为:

$ module purge
$ module li
No Modulefiles Currently Loaded.

到此处,我们学到了:

  1. 显示一个module模块的详细信息:module show 模块名
  2. 替换一个module模块为新的module模块:module swap 旧模块名 新模块名
  3. 一次性卸载所有已加载module模块:module purge

注意:我们遇到过一个报错ERROR conflict bedtools2 ,关键词为 conflict 即为版本冲突,它表明 bedtools2 模块已经加载,如果想加载新的,需要先卸载旧的。 我们可以用 module li 看看已加载的模块,把对应的冲突模块用module rm卸载后,在加载新的模块。 我们也可以用module swap 来直接将旧模块替换为新的模块。


4. module使用高级

4.1 模块依赖问题 prereq

我们再次使用module av命令,查看所有可用的module模块,这次我们以espresso软件为例,因为它复杂一点点。

$ module av 
------------- /usr/share/Modules/3.2.10/Applications -------------
espresso/5.4.0-icc16-IMPI5.1

我们再来尝试加载一下espresso/5.4.0-icc16-IMPI5.1,输入命令:

$ module add espresso/5.4.0-icc16-IMPI5.1
espresso/5.4.0-icc16-IMPI5.1(27):ERROR:151: Module 'espresso/5.4.0-icc16-IMPI5.1' 
    depends on one of the module(s) 'Intel_compiler/16.0.3'
espresso/5.4.0-icc16-IMPI5.1(27):ERROR:102: Tcl command execution failed: 
    prereq                Intel_compiler/16.0.3

很遗憾,这回有信息提示,竟然是ERROR prereq Intel_compiler/16.0.3,这次又是为什么呢?

我们观察这个模块的名称espresso/5.4.0-icc16-IMPI5.1,在第二节中我们提到过module模块的常见命名规则:软件名/版本-[编译器名]-[MPI编译器名],因此我们分析如下:

  • esresso 表示软件的名字
  • 5.4.0 是软件的版本
  • icc16 是intel compiler的版本
  • IMPI5.1 是MPI编译器的版本

详解:

一款并行程序通常需要串行编译器加并行编译器来编译,然后它通过类似mpirun的并行执行命令来运行。如果运行过程中缺少动态库就会报错。因此,我们设置了依赖关系,让加载软件模块的时候,必须预先加载依赖的其它模块(如编译器模块等),然后再加载模块本身,以免报错。

我们仔细观察报错中的内容:prereq Intel_compiler/16.0.3,它表明espresso这个模块依赖于Intel_compiler这个模块。

我们决定先加载Intel_compiler,再加载espresso模块:

$ module add Intel_compiler/16.0.3
$ module add espresso/5.4.0-icc16-IMPI5.1

然后我们发现,有报错了,不过报错和之前的很类似。

我们决定把MPI/Intel/IMPI/5.1.3.210模块也加载上,最终输入:

$ module add Intel_compiler/16.0.3
$ module add MPI/Intel/IMPI/5.1.3.210
$ module add espresso/5.4.0-icc16-IMPI5.1

如下图,没有任何报错,就成功了。

4.2 自定义路径配置

用户可以通过设置 MODULEPATH 或者通过 module 命令来增加减少搜索路径。

方法1:

$ export MODULEPATH=/path/to/new/directory:$MODULEPATH
## 增加路径
$ module use --append /path/to/new/directory
## 减少路径
$ module unuse --append /path/to/old/directory

提别提醒:MODULEPATH等于号后面的值,以及--append后面的参数,都是实际希望增加或减少的搜索路径,不要照抄。

4.3 配置文件编写

我们先来看一个标准的module配置文件模板

#%Module1.0#####################################################################
##
## modules modulefile
##
## modulefiles/modules.  Generated from modules.in by configure.
##
proc ModulesHelp { } {
                global version prefix

                puts stderr "\tespresso/5.4.0-icc16-IMPI5.1, link with Intel_compiler/16.0.3," 
                puts stderr "MPI/Intel/IMPI/5.1.3.210"
                puts stderr "\n\tAfter loading the module, you can try to use espresso"
                puts stderr "\tAdds Intel compilers to your environment variables."
                puts stderr "\n\tThis adds $prefix/* to several of the"
                puts stderr "\tenvironment variables."
                puts stderr "\n\tVersion $version\n"
}

module-whatis   "espresso/5.4.0-icc16-IMPI5.1"

# for Tcl script use only
set     version         espresso/5.4.0-icc16-IMPI5.1
set     prefix          /home/software/espresso/5.4.0-icc16-IMPI5.1
set     exec_prefix     ${prefix}
set     datarootdir     ${prefix}/share
set     INSTALL_DIR     ${prefix}

conflict        espresso

prereq          Intel_compiler/16.0.3
prereq          MPI/Intel/IMPI/5.1.3.210

prepend-path    PATH                ${prefix}/bin
prepend-path    LD_LIBRARY_PATH     ${prefix}/lib

prepend-path    LIBRARY_PATH        ${prefix}/lib
prepend-path    PKG_CONFIG_PATH     ${prefix}/lib/pkgconfig
prepend-path    C_INCLUDE_PATH      ${prefix}/include
prepend-path    CXX_INCLUDE_PATH    ${prefix}/include
prepend-path    MANPATH             ${datarootdir}/man

用户自己写module模块的时候,可以依照此模板进行修改。

参数说明:

参数 说明 备注
proc ModulesHelp 执行module show 模块名时候的反馈信息
set version 设置版本
set prefix 设置安装目录 非常关键
conflict 设置conflict报错的 这就是之前遇到error的原因,同下
prereq 用来设置依赖哪些模块的
prepend-path 添加一个路径到某个环境变量
PATH 将目录添加到PATH环境变量中 最常用的环境变量就是PATHLD_LIBRARY_PATH
LD_LIBRARY_PATH 将目录添加到LD_LIBRARY_PATH环境变量中
LIBRARY_PATH 等 与上面类似,通常运行软件命令时不需要,编译其他软件时候可能会用到

附录

A 安装

命令安装

apt-get命令安装:

$ sudo apt-get install environment-modules

yum命令安装

$ sudo yum install environment-modules

源码安装

下载:

https://sourceforge.net/projects/modules/files/下载module源码,如果系统缺少tcl环境,需要额外下载安装tcl环境。

#Modules-Tcl
https://jaist.dl.sourceforge.net/project/modules/Modules-Tcl/modules-tcl-1.923.tar.gz
# Modules
https://nchc.dl.sourceforge.net/project/modules/Modules/modules-3.2.10/modules-3.2.10.tar.gz

编译:

$ tar zxvf modules-3.2.10.tar.gz
$ cd modules-3.2.10
$ ./configure
$ make
$ make install

可以使用--prefix指定安装目录。

加载:

如果使用的不是命令安装方式,而是源码方式编译到非系统默认路径,需要在使用module命令的时候,加载环境变量。

假如安装路径为 $HOME/software ,那么需要加载环境:

$ source $HOME/software/Modules/init/bash

针对其他shell环境,如csh,可以加载:

$ source $HOME/software/Modules/init/csh

以下命令均针对bash环境。

修改系统默认搜索路径

在上面我们介绍了用户设置路径的方法,此处我们介绍如何修改系统默认的module模块搜索路径。

在安装后的Modules/3.2.10/init目录,打开隐藏文件,增加/删除路径实现配置。

$ vim .modulespath

直接输入路径来增加搜索路径;通过#注释行,或直接删除行来减少搜索路径。

#
#  @(#)$Id: 38aa24cc33a5f54a93781d63005a084f74418022 $
#  Module version 3.2.10
#  init/.modulespath.  Generated from .modulespath.in by configure.
#
#  Modulepath initial setup
#  ========================
#
#  This file defines the initial setup for the module files search path.
#  Comments may be added anywhere, which begin on # and continue until the
#     end of the line
#  Each line containing a single path will be added to the MODULEPATH
#     environment variable. You may add as many as you want - just
#     limited by the maximum variable size of your shell.
#
/usr/share/Modules/versions                                # location of version files
/usr/share/Modules/$MODULE_VERSION/modulefiles     # Module pkg modulefiles (if versioning)
#/usr/share/Modules/modulefiles    # Module pkg modulefiles (if no versioning)
/usr/share/Modules/modulefiles                             # General module files
#/usr/share/Modules/3.2.10/your_contribs                   # Edit for your requirements

B 常用命令列表

表 Modules 常用命令

命令 作用
module avail 或 module av 查看系统中可用的软件
module add 或 module load 加载模块
module rm 或 unload 卸载模块
module list 或 module li 显示已加载模块
module purge 卸载所有模块
module show 显示模块配置文件
module swap 或 module switch 将模块1 替换为 模块2
module help 查看具体软件的信息

C 遇到报错

常见报错有2类:

1. conflict

对于conflict而言,通常是由于同款软件不能同时加载多个版本,因此建议卸载之前的,再加载新的。提示哪个模块冲突了就卸载哪一个。

举例:

$ module add bedtools2/2.26.0-gcc4.8
bedtools2/2.26.0-gcc4.8(25):ERROR:150: Module 'bedtools2/2.26.0-gcc4.8' 
    conflicts with the currently loaded module(s) 'bedtools2/2.25.0-gcc4.8'
bedtools2/2.26.0-gcc4.8(25):ERROR:102: Tcl command execution failed: 
    conflict   bedtools2

我们要加载的是bedtools2/2.26.0-gcc4.8,但与bedtools2/2.25.0-gcc4.8冲突了,那么:

$ module rm  bedtools2/2.25.0-gcc4.8
$ module add bedtools2/2.26.0-gcc4.8
$ 

2. prereq

对于prereq而言,通常是加载的模块依赖其他默认,因此必须先加载依赖的模块,在加载该模块。

举例:

$ module add espresso/5.4.0-icc16-IMPI5.1
espresso/5.4.0-icc16-IMPI5.1(27):ERROR:151: Module 'espresso/5.4.0-icc16-IMPI5.1' 
    depends on one of the module(s) 'Intel_compiler/16.0.3'
espresso/5.4.0-icc16-IMPI5.1(27):ERROR:102: Tcl command execution failed: 
    prereq                Intel_compiler/16.0.3

我们需要先加载Intel_compiler/16.0.3,再加载espresso/5.4.0-icc16-IMPI5.1

$ module add Intel_compiler/16.0.3
$ module add espresso/5.4.0-icc16-IMPI5.1

留一个问题,以上两行命令能够加载成功吗?