Skip to content

Modules 使用入门

Modules 模块概述

在高性能计算平台上由于用户数量多,因此也安装了各种各样的计算程序,这些程序依赖的动态/静态链接库等又各不相同,并且不同用户对同一个程序可能又有不同版本的需求。因此如何分类管理这些程序以及这些程序依赖的动态/静态链接库和第三方依赖变得十分重要。而 Modules 提供了组织程序以及各个程序依赖的解决方案,modules 模块可以将这些操作整合进单个 modulefile 文件中,用户在需要使用相关程序时只需要执行一条简单的加载命令。

该教程主要介绍了 SonmiHPC 集群中 modules 模块的使用,以及 modulefile 的简单编写技巧。

Modules 模块安装

一些超算平台中往往已经集成了 modules 模块,如果没有的话集群管理员可能需要手动安装。安装的方法一般有两种,YUM 仓库中有的话直接使用 yum 或者 dnf 命令进行安装即可。

bash
# 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 模块。

bash
# 安装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 : 一般集群管理员新增软件模块时推荐放在该路径下
bash
[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 <模块名>指令可卸载已加载模块,例如:

bash
[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为例:

tcl
#%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
  1. modulefile 以#%Module1.0开头,1.0 为 modules 模块的版本。
  2. 后续以##开头的行数的为该模块的相关注释,可以在此编写相关的注释信息。
  3. proc 开头为模块的帮助函数,当执行module help <模块名>命令时,会打印出该函数中的相关帮助信息。该函数内部puts语句将字符串打印至标准错误输出中:puts stderr "... ..."
proc ModulesHelp { } {
	... ....
	puts stderr "输出的帮助信息"
}
proc ModulesHelp { } {
	... ....
	puts stderr "输出的帮助信息"
}
  1. module-whatis 指令用于描述该模块的相关功能。
  2. set 变量名 变量值指令则用于设置变量。
  3. setenv 环境变量名 变量值指令用于设置环境变量。
  4. 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 如下所示:

tcl
#%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 如下所示:

tcl
#%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

添加后可以通过指令查看添加的模块:

bash
[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
... ...

可以使用以下指令使用模块:

bash
# 使用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

本站内容未经授权禁止转载
联系邮箱: [email protected]