Modules 使用入门
Modules 模块概述
在高性能计算平台上由于用户数量多,因此也安装了各种各样的计算程序,这些程序依赖的动态/静态链接库等又各不相同,并且不同用户对同一个程序可能又有不同版本的需求。因此如何分类管理这些程序以及这些程序依赖的动态/静态链接库和第三方依赖变得十分重要。而 Modules 提供了组织程序以及各个程序依赖的解决方案,modules 模块可以将这些操作整合进单个 modulefile 文件中,用户在需要使用相关程序时只需要执行一条简单的加载命令。
该教程主要介绍了 SonmiHPC 集群中 modules 模块的使用,以及 modulefile 的简单编写技巧。
Modules 模块安装
一些超算平台中往往已经集成了 modules 模块,如果没有的话集群管理员可能需要手动安装。安装的方法一般有两种,YUM 仓库中有的话直接使用 yum 或者 dnf 命令进行安装即可。
# SonmiHPC集群中已默认集成modules模块,故不需要安装
# redhat体系的发行版可以通过yum或者dnf命令进行安装
yum install environment-modules -y
dnf install environment-modules -y
# SonmiHPC集群中已默认集成modules模块,故不需要安装
# redhat体系的发行版可以通过yum或者dnf命令进行安装
yum install environment-modules -y
dnf install environment-modules -y
有特殊需求的话,也可以通过手动编译源码安装 modules 模块。
# 安装tcl语言工具
yum -y install tcl-devel
# 获取tarball源码包
curl -LJO https://github.com/cea-hpc/modules/releases/download/v5.0.1/modules-5.0.1.tar.gz
# 解压缩源码包
tar xfz modules-5.0.1.tar.gz
# 简单编译安装,有特别需求可以手动设置配置参数
./configure
make
make install
# configure常用的配置参数
--prefix=PREFIX #执行文件安装路径
--modulefilesdir=DIR #modulefile文件目录
# 安装tcl语言工具
yum -y install tcl-devel
# 获取tarball源码包
curl -LJO https://github.com/cea-hpc/modules/releases/download/v5.0.1/modules-5.0.1.tar.gz
# 解压缩源码包
tar xfz modules-5.0.1.tar.gz
# 简单编译安装,有特别需求可以手动设置配置参数
./configure
make
make install
# configure常用的配置参数
--prefix=PREFIX #执行文件安装路径
--modulefilesdir=DIR #modulefile文件目录
Modules 模块简单使用
modules 模块的指令格式如下:
module [switches] [subcommand] [subcommand-args]
module [switches] [subcommand] [subcommand-args]
switches 部分用于控制输出的信息格式和输出行为,switches 的可选命令如下:
-H|--help 打印帮助信息
-V|--version 查看模块的版本信息和编译配置参数(即configure所带参数)
-f|--force force active dependency resolution
-t|--terse terse format avail and list format
-l|--long long format avail and list format
-h|--human readable format avail and list format
-v|--verbose 启用输出详细信息
-s|--silent 静默模式,与-v相反
-c|--create create caches for avail and apropos
-i|--icase 大小写不敏感的
-u|--userlvl <lvl> 设置用户等级,可选参数:nov/exp/adv (nov[ice],exp[ert],adv[anced])
-H|--help 打印帮助信息
-V|--version 查看模块的版本信息和编译配置参数(即configure所带参数)
-f|--force force active dependency resolution
-t|--terse terse format avail and list format
-l|--long long format avail and list format
-h|--human readable format avail and list format
-v|--verbose 启用输出详细信息
-s|--silent 静默模式,与-v相反
-c|--create create caches for avail and apropos
-i|--icase 大小写不敏感的
-u|--userlvl <lvl> 设置用户等级,可选参数:nov/exp/adv (nov[ice],exp[ert],adv[anced])
subcommand 所有子命令如下:
只需要记住常见的使用命令,load/unload/switch/avail/list/use/clear 即可。
add|load modulefile [modulefile ...] # 加载模块
rm|unload modulefile [modulefile ...] # 卸载模块
switch|swap [modulefile1] modulefile2 # 切换模块
display|show modulefile [modulefile ...] # 查看模块的相关信息
avail [modulefile [modulefile ...]] # 查看系统中可用的模块
use [-a|--append] dir [dir ...] #将用户modulefile目录加入到MODULEPATH中
unuse dir [dir ...] # 将用户modulefile目录从MODULEPATH中移除
update
refresh
purge
list # 列出已经加载的模块
clear
help [modulefile [modulefile ...]]
whatis [modulefile [modulefile ...]]
apropos|keyword string
initadd modulefile [modulefile ...]
initprepend modulefile [modulefile ...]
initrm modulefile [modulefile ...]
initswitch modulefile1 modulefile2
initlist
initclear
add|load modulefile [modulefile ...] # 加载模块
rm|unload modulefile [modulefile ...] # 卸载模块
switch|swap [modulefile1] modulefile2 # 切换模块
display|show modulefile [modulefile ...] # 查看模块的相关信息
avail [modulefile [modulefile ...]] # 查看系统中可用的模块
use [-a|--append] dir [dir ...] #将用户modulefile目录加入到MODULEPATH中
unuse dir [dir ...] # 将用户modulefile目录从MODULEPATH中移除
update
refresh
purge
list # 列出已经加载的模块
clear
help [modulefile [modulefile ...]]
whatis [modulefile [modulefile ...]]
apropos|keyword string
initadd modulefile [modulefile ...]
initprepend modulefile [modulefile ...]
initrm modulefile [modulefile ...]
initswitch modulefile1 modulefile2
initlist
initclear
查看所有可用的 modules 模块
module avail
可以列出系统中可用的所有模块。SonmiHPC 集群中默认的 modulefiles 文件夹路径为:
- /usr/share/Modules/modulefiles
- /usr/share/modulefiles
- /opt/intel/oneapi/modulefiles : Intel oneAPI 组件的模块路径
- /opt/sonmi/modulefiles : 集群测试套件的模块文件存放在该路径下
- /share/apps/modulefiles : 一般集群管理员新增软件模块时推荐放在该路径下
[root@sonmi sonmi]# module avail
-------------------------------------- /usr/share/Modules/modulefiles --------------------------------------
dot module-git module-info modules null use.own
------------------------------------------ /usr/share/modulefiles ------------------------------------------
mpi/openmpi-x86_64
-------------------------------------- /opt/intel/oneapi/modulefiles ---------------------------------------
advisor/2024.0 dal/2024.0.0 ifort/2024.0.2 mkl/2024.0
advisor/latest dal/latest ifort/latest mkl/latest
ccl/2021.11.2 debugger/2024.0.0 ifort32/2024.0.2 mkl32/2024.0
ccl/latest debugger/latest ifort32/latest mkl32/latest
compiler-rt/2024.0.2 dev-utilities/2024.0.0 inspector/2024.0 mpi/2021.11
compiler-rt/latest dev-utilities/latest inspector/latest mpi/latest
compiler-rt32/2024.0.2 dnnl/3.3.0 intel_ipp_intel64/2021.10 oclfpga/2024.0.0
compiler-rt32/latest dnnl/latest intel_ipp_intel64/latest oclfpga/latest
compiler/2024.0.2 dpct/2024.0.0 intel_ippcp_intel64/2021.9 tbb/2021.11
compiler/latest dpct/latest intel_ippcp_intel64/latest tbb/latest
compiler32/2024.0.2 dpl/2022.3 itac/2022.0 vtune/2024.0
compiler32/latest dpl/latest itac/latest vtune/latest
------------------------------------------ /opt/sonmi/modulefiles ------------------------------------------
sonmi-test-suite
Key:
modulepath
[root@sonmi sonmi]# module avail
-------------------------------------- /usr/share/Modules/modulefiles --------------------------------------
dot module-git module-info modules null use.own
------------------------------------------ /usr/share/modulefiles ------------------------------------------
mpi/openmpi-x86_64
-------------------------------------- /opt/intel/oneapi/modulefiles ---------------------------------------
advisor/2024.0 dal/2024.0.0 ifort/2024.0.2 mkl/2024.0
advisor/latest dal/latest ifort/latest mkl/latest
ccl/2021.11.2 debugger/2024.0.0 ifort32/2024.0.2 mkl32/2024.0
ccl/latest debugger/latest ifort32/latest mkl32/latest
compiler-rt/2024.0.2 dev-utilities/2024.0.0 inspector/2024.0 mpi/2021.11
compiler-rt/latest dev-utilities/latest inspector/latest mpi/latest
compiler-rt32/2024.0.2 dnnl/3.3.0 intel_ipp_intel64/2021.10 oclfpga/2024.0.0
compiler-rt32/latest dnnl/latest intel_ipp_intel64/latest oclfpga/latest
compiler/2024.0.2 dpct/2024.0.0 intel_ippcp_intel64/2021.9 tbb/2021.11
compiler/latest dpct/latest intel_ippcp_intel64/latest tbb/latest
compiler32/2024.0.2 dpl/2022.3 itac/2022.0 vtune/2024.0
compiler32/latest dpl/latest itac/latest vtune/latest
------------------------------------------ /opt/sonmi/modulefiles ------------------------------------------
sonmi-test-suite
Key:
modulepath
所有已加载的 modules 模块
module list
指令可以列出系统中已经加载的模块,例如:
[root@sonmi sonmi]# module list
Currently Loaded Modulefiles:
1) sonmi-test-suite
[root@sonmi sonmi]# module list
Currently Loaded Modulefiles:
1) sonmi-test-suite
以上例子可以看到集群中已经加载了自带的 sonmi-test-suite 模块。
卸载已加载的 modules 模块
module unload <模块名>
指令可卸载已加载模块,例如:
[root@sonmi sonmi]# module list
Currently Loaded Modulefiles:
1) sonmi-test-suite 2) mpi/openmpi-x86_64
[root@sonmi sonmi]# module unload sonmi-test-suite
Removing sonmi test suite version 0.7.0
Use to view any remaining dependent modules.
[root@sonmi sonmi]# module list
Currently Loaded Modulefiles:
1) mpi/openmpi-x86_64
[root@sonmi sonmi]# module list
Currently Loaded Modulefiles:
1) sonmi-test-suite 2) mpi/openmpi-x86_64
[root@sonmi sonmi]# module unload sonmi-test-suite
Removing sonmi test suite version 0.7.0
Use to view any remaining dependent modules.
[root@sonmi sonmi]# module list
Currently Loaded Modulefiles:
1) mpi/openmpi-x86_64
2.4 查看相关模块的详细信息
module show <模块名>
指令可查看相关模块的具体详细信息,包括描述、环境变量、链接库等。例如:
[root@sonmi sonmi]# module show mpi/openmpi-x86_64
-------------------------------------------------------------------
/usr/share/modulefiles/mpi/openmpi-x86_64:
conflict mpi
prepend-path PATH /usr/lib64/openmpi/bin
prepend-path LD_LIBRARY_PATH /usr/lib64/openmpi/lib
prepend-path PKG_CONFIG_PATH /usr/lib64/openmpi/lib/pkgconfig
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
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_PYTHON3_SITEARCH /usr/lib64/python3.9/site-packages/openmpi
setenv MPI_COMPILER openmpi-x86_64
setenv MPI_SUFFIX _openmpi
setenv MPI_HOME /usr/lib64/openmpi
-------------------------------------------------------------------
[root@sonmi sonmi]# module show mpi/openmpi-x86_64
-------------------------------------------------------------------
/usr/share/modulefiles/mpi/openmpi-x86_64:
conflict mpi
prepend-path PATH /usr/lib64/openmpi/bin
prepend-path LD_LIBRARY_PATH /usr/lib64/openmpi/lib
prepend-path PKG_CONFIG_PATH /usr/lib64/openmpi/lib/pkgconfig
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
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_PYTHON3_SITEARCH /usr/lib64/python3.9/site-packages/openmpi
setenv MPI_COMPILER openmpi-x86_64
setenv MPI_SUFFIX _openmpi
setenv MPI_HOME /usr/lib64/openmpi
-------------------------------------------------------------------
modulefile 的编写指南
该部分主要简明介绍 modulefile 的项目组织,文件的一般结构,以及常用的相关指令。
3.1 modulefile 文件如何进行系统性组织
例举一个常见的常见,当超算平台中存在多个不同的计算软件,每个计算软件都要求不同版本的MPI进行并行计算支持。这是可以针对这一些不同版本不同厂商的MPI软件的 modulefile 进行组织,使用 SonmiHPC 时建议集群管理员在 /share/apps/modulefiles 文件夹中组织相关的 modulefile。当然管理员及用户也可以通过在 MODULEPATH 环境变量中添加自定义的路径来组织 modulefile。
例如:
modulefiles/
├── cmake
│ ├── 3.8.0
│ └── 3.9.0
├── gcc
└── mpi
├── intel
├── mpich2
└── openmpi
├── 3.1.1
├── 3.1.2
└── 3.1.3
modulefiles/
├── cmake
│ ├── 3.8.0
│ └── 3.9.0
├── gcc
└── mpi
├── intel
├── mpich2
└── openmpi
├── 3.1.1
├── 3.1.2
└── 3.1.3
需要激活相关版本的时候只需要执行加载命令即可:module load mpi/openmpi/3.1.1
3.2 modulefile 文件结构详解
下面用两个 modulefile 的实际例子来刨析 modulefile 的一个大致的文件结构。
modulefile 以工具命令语言(Tool Command Language)编写,由 modulecmd.tcl作为解释器。
以自带的openmpi为例:
#%Module1.0
##
## openmpi modulefile
##
## modulefiles/
##
proc ModulesHelp { } {
global rocks-openmpiversion
puts stderr "\t Use /opt/rocks/openmpi as your MPI"
puts stderr "\n\tVersion $rocks-openmpiversion\n"
}
module-whatis "Use Rocks-compiled OpenMPI with tcp,self transport"
# for Tcl script use only
set rocks-openmpiversion 2.1.1
set mpiHome /opt/openmpi
setenv MPIHOME $mpiHome
setenv OMPI_MCA_btl self,sm,tcp
prepend-path PATH $mpiHome/bin
prepend-path LD_LIBRARY_PATH $mpiHome/lib
#%Module1.0
##
## openmpi modulefile
##
## modulefiles/
##
proc ModulesHelp { } {
global rocks-openmpiversion
puts stderr "\t Use /opt/rocks/openmpi as your MPI"
puts stderr "\n\tVersion $rocks-openmpiversion\n"
}
module-whatis "Use Rocks-compiled OpenMPI with tcp,self transport"
# for Tcl script use only
set rocks-openmpiversion 2.1.1
set mpiHome /opt/openmpi
setenv MPIHOME $mpiHome
setenv OMPI_MCA_btl self,sm,tcp
prepend-path PATH $mpiHome/bin
prepend-path LD_LIBRARY_PATH $mpiHome/lib
- modulefile 以
#%Module1.0
开头,1.0 为 modules 模块的版本。 - 后续以##开头的行数的为该模块的相关注释,可以在此编写相关的注释信息。
- proc 开头为模块的帮助函数,当执行
module help <模块名>
命令时,会打印出该函数中的相关帮助信息。该函数内部puts语句将字符串打印至标准错误输出中:puts stderr "... ..."
proc ModulesHelp { } {
... ....
puts stderr "输出的帮助信息"
}
proc ModulesHelp { } {
... ....
puts stderr "输出的帮助信息"
}
module-whatis
指令用于描述该模块的相关功能。set 变量名 变量值
指令则用于设置变量。setenv 环境变量名 变量值
指令用于设置环境变量。prepend-path 环境变量名 变量值
指令用于将新变量值增加到现有的变量值之前,例如prepend-path PATH $mpiHome/bin
等同于export PATH=$mpiHome/bin:$PATH
。
了解以上的相关指令便可以初步写一些简单的 modulefile 文件。
后面将以两个不同版本的cmake和两个不同版本的 openmpi 为例来编写 modulefile 文件,进行实战练习。
modulefile 实战练习
4.1 cmake 的 modulefile 编写实战
在集群中已经编译3.8与3.20两个版本的 cmake,路径分别为
/share/apps/cmake/
├── 3.20.0
│ ├── bin
│ ├── doc
│ ├── man
│ └── share
└── 3.8.0
├── bin
├── doc
├── man
└── share
/share/apps/cmake/
├── 3.20.0
│ ├── bin
│ ├── doc
│ ├── man
│ └── share
└── 3.8.0
├── bin
├── doc
├── man
└── share
分别在 /share/apps/modulefiles/cmake 下编写两个不同版本 cmake 的 modulefile:
文件树形图如下:
/share/apps/modulefiles/
├── cmake
├── 3.20.0
└── 3.8.0
/share/apps/modulefiles/
├── cmake
├── 3.20.0
└── 3.8.0
3.8.0版本 cmake 的 modulefile 如下所示:
#%Module1.0
## cmake-3.8.0
proc ModulesHelp { } {
puts stderr "\t Use cmake/3.8.0 as your cmake"
}
module-whatis "cmake-3.8.0"
set cmakeHome /share/apps/cmake/3.8.0
prepend-path PATH $cmakeHome/bin
#%Module1.0
## cmake-3.8.0
proc ModulesHelp { } {
puts stderr "\t Use cmake/3.8.0 as your cmake"
}
module-whatis "cmake-3.8.0"
set cmakeHome /share/apps/cmake/3.8.0
prepend-path PATH $cmakeHome/bin
3.20.0 版本 cmake 的 modulefile 如下所示:
#%Module1.0
## cmake-3.20.0
proc ModulesHelp { } {
puts stderr "\t Use cmake/3.20.0 as your cmake"
}
module-whatis "cmake-3.20.0"
set cmakeHome /share/apps/cmake/3.20.0
prepend-path PATH $cmakeHome/bin
#%Module1.0
## cmake-3.20.0
proc ModulesHelp { } {
puts stderr "\t Use cmake/3.20.0 as your cmake"
}
module-whatis "cmake-3.20.0"
set cmakeHome /share/apps/cmake/3.20.0
prepend-path PATH $cmakeHome/bin
添加后可以通过指令查看添加的模块:
[root@sonmi cmake]$ module avail
... ...
------------------------ /share/apps/modulefiles/ ------------------------
cmake/3.20.0 cmake/3.8.0
... ...
[root@sonmi cmake]$ module avail
... ...
------------------------ /share/apps/modulefiles/ ------------------------
cmake/3.20.0 cmake/3.8.0
... ...
可以使用以下指令使用模块:
# 使用cmake-3.8.0
module load cmake/3.8.0
# 切换到cmake-3.20.0
module switch cmake/3.20.0
# 卸载cmake-3.20.0模块
module unload cmake/3.20.0
# 使用cmake-3.8.0
module load cmake/3.8.0
# 切换到cmake-3.20.0
module switch cmake/3.20.0
# 卸载cmake-3.20.0模块
module unload cmake/3.20.0