yhli0906的个人博客分享 http://blog.sciencenet.cn/u/yhli0906

博文

Pmod使用说明

已有 7771 次阅读 2018-12-17 16:11 |个人分类:计算机软件|系统分类:科研笔记

基本介绍

刚上手第一性原理计算的人,应该都遇到过类似“-bash: xxx: command not found” 或者 “xxx: error while loading shared libraries: libxxx.so: cannot open shared object file: No such file or directory”的错误。如果自己编译过abinitQEsiesta等软件,一般也遇到过已经安装了某个库,configure时却无法识别的情形。这些问题都由环境变量设置不当导致。软件安装后,需设置PATH LD_LIBRARY_PATHLIBRARY_PATH等环境变量,才能正常运行。随着软件越装越多,~/.bashrc也越来越复杂,充斥着这样的设置:

图片.png

这种方式有几个缺点,最严重的就是要输很多环境变量名。有几个环境变量名很长,一旦输错一个字母,轻则软件不能正常运行,重则连lsvi等命令都不能用了。我就曾经见过有人手滑,把LD_LIBRARY_PATH中的某个R打成了T。相比于直接操作环境变量,更为安全的方式是定义一个函数,通过这个函数修改环境变量:

图片.png


这样每个环境变量名只需输入一次,极大地降低了出错的概率。但这种方法并非十分完美。每次添加新软件的配置信息,或者移除旧软件,都要修改~/.bashrc并重新登录,非常麻烦。如果一台服务器由几个人共用,管理员需要为每个人准备一份~/.bashrc。况且不同软件间一般存在依赖或冲突关系,例如QE依赖MKLMPI,如果这两个组件未正确设置就会报错;ADFORCA等软件所需要的特定版本的MPI,一般又和系统中已安装的MPI冲突。通过修改~/.bashrc来设置软件运行环境,每次都要改动很多地方,既费时费力,又容易出错。如果有程序能根据需要自动设置环境变量,使用软件时就会轻松很多。

 

环境模块系统(Environment module)就是为解决这类问题而设计的软件。目前环境模块系统有Environment Modules (又名Tmod)Lmod,以及一个比较古老的Cmod和用shell script写的dotkit等几种。配置Tmod需要学习TCLLmod需要学习Lua。两门语言都相对小众,有一定的学习成本。另外,一些软件如Intel编译器、GaussianADF等都提供了初始化脚本来设置运行环境。但无论Tmod还是Lmod都不建议用户使用这种脚本,也没有运行脚本的功能,而是提供了工具将之转换成各自的配置文件,这就不是很方便。于是就用Python自己写了一个简单的环境模块系统Pmod。软件原理不复杂,核心部分是这样一个函数:

图片.png

shell把命令行参数传给python脚本,由脚本确定需要修改哪些环境变量并输出相应指令,再由shell执行该指令。TmodLmod也是基于这种设计思路。目前Pmod已具有模块加载与卸载、自动解决冲突和依赖关系、查看模块内部配置信息和加载状态、根据名称搜索模块等功能,项目放在GitHub上:https://github.com/yhli1016/Pmod

 

安装配置

Pmod只依赖Python标准库,因此只要系统中安装了Python即可运行,对Python版本也无限制,2.x3.x均可。具体安装过程如下:

    下载源码并解压到安装目录,若供多人使用可解压到/opt,仅单人使用可解压到$HOME

    假设解压后源码目录为/opt/pmod,修改init/bash.sh,将PM_ROOT设置为解压后的源码目录;

    若供多人使用,将init/bash.sh链接至/etc/profile.d,仅单人使用则在~/.bashrc中添加一行“source /opt/pmod/init/bash.sh”

至此安装完成。重新登录系统后,输入module av即可得到如下输出:

图片.png

这些都是例子中预设的模块,仅作示范用。用户需要根据需求,添加自己的模块。在讲解如何添加模块之前,先简单介绍Pmod的内部架构。

 

       Pmod由一个初始化脚本init/bash.sh,一个命令行程序bin/modcmd.py和两个Python包组成。pmod包中定义了三个类:ModuleSandBoxModManangerModule对应负责存储环境变量、命令别名等配置信息。ModManager负责解析依赖关系,以及加载和卸载模块。SandBox负责收集各模块的中存储的配置信息,并输出相应的shell命令。在modulefiles包的setup模块中从ModManager类创建了一个对象mod_manager,并通过create_mod()方法向其添加了各个模块。最后bin/modcmd.py导入mod_manager,通过load_mods()unload_mods()等方法完成用户指定的操作。

 

添加模块主要通过ModManager类的create_mod()方法完成,调用方式如下:

图片.png

第一个无名参数为模块名称,如果模块不存在则创建之,已存在则向该模块添加配置信息。除mod_class关键字外,剩下的关键字参数最终都传递到Module类的add settings()方法。该方法接受的关键字参数如下:

图片.png


presetdestination两个参数指定向该模块添加哪些环境变量配置信息。以openmpi为例,preset=“mod”destination=“/opt/openmpi/3.1.3”会把/opt/openmpi/3.1.3/bin添加至PATH/opt/openmpi/3.1.3/lib添加至LIBRARY_PATHLD_LIBRARY_PATH/opt/openmpi/3.1.3/include添加至C_INCLUDE_PATHCPLUS_INCLUDE_PATH。当preset值为mod时,会自动补全binlibinclude等子目录,但取其它值时不会自动补全。例如,若要将/opt/gpaw/1.4.0/bin添加至PATH,就必需指定preset=“path”destination=“/opt/gpaw/1.4.0/bin”


       environ参数指定无法通过presetdestination设置的环境变量配置信息。这个参数是一个列表,每个元素是一个由三个元素组成的元组。元组中第一个元素指定对环境变量进行何种操作,取值为resetappendprepend三种,分别代表重设、在尾部追加字符串和在头部插入字符串;第二个元素为环境变量名称;第三个元素为修改环境变量所用的字符串。在上面所给出的GPAW例子中,environ参数表示将环境变量GPAW_SETUP_PATH重设为/opt/gpaw/1.4.0/data/gpaw-setups-0.9.20000。此外,environ参数多用于加载编译器时设置相关环境变量:

图片.png

这些设置最终转化为如下shell指令:

图片.png

 

       dependconflict参数指定与当前模块所依赖的模块,以及与之冲突的模块。每个参数都是一个列表,列表内元素为模块的名称,具体参见上面GPAW的例子。需注意,在加载和卸载模块时,依赖和冲突关系会被递归展开。例如,IntelMPI依赖IntelCC,又与各OpenMPI冲突;作为依赖IntelMPIVASP,其depend参数只需包含IntelMPI,而conflict参数无需设置:

图片.png

在加载VASP模块时,Pmod会自动检测并卸载各OpenMPI模块,并加载IntelCCIntelMPI模块。当有大量模块依赖同一模块时,可以从Module类派生新的类,重载__init__()方法,在其中将所依赖模块加入depend列表,然后将派生类作为mod_class参数传给create_mod()方法,如下图所示:

图片.png

这样便可进一步降低出错的概率。详细的例子参见examples/hierarchy

 

       command参数指定额外的初始化命令,是一个由字符串组成的列表。每个字符串即一条命令,一般用来运行初始化脚本。alias参数指定创建哪些命令别名,是一个由元组组成的列表。每个元组包含两个字符串:别名和命令。这两个参数的例子如下:

图片.png

图片.png


常用操作

罗列所有可用模块: module avail/av

图片.png

 

查看各模块状态:module status/stat

图片.png

如果加载了某模块后不慎修改了相关环境变量,该模块就会被标记为broken。例如,IntelCC模块将CC设置为icc,若将CC修改为gcc,则该模块“损坏”。

 

查看已加载模块:module list/ls

图片.png

该命令是module stat的简化版,在Pmod内部也由同一个函数完成。


 

查看模块内部配置信息:module info/show/display xxx

图片.png

 

检查模块是否正常加载:module diagnose/probe xxx

图片.png

 

搜索模块(支持正则表达式):module search regex

图片.png


 

加载模块:module load/add xxxx

自动模式下自动加载依赖模块并卸载冲突模块

图片.png

 

卸载模块:module unload/remove/rm/delete/del xxxx

自动模式下卸载指定模块时,会同时卸载其依赖模块。但若依赖模块仍被其它模块使用,则不会被卸载

图片.png

 

卸载所有已加载模块:module clean/purge

图片.png


 

重新加载已加载模块: module reload/update

图片.png

 

自动模式

各软件间往往存在依赖或冲突关系,因此仅仅加载某个模块,软件一般无法运行。Pmod提供了自动模式解决这个问题。在自动模式下,除了加载指定模块外,还执行如下操作:

    加载依赖模块

    卸载冲突模块

    卸载因第①②步操作而无法运行的模块

    重新加载因第①②步操作而需重新加载的模块

在卸载模块时,还执行如下操作:

    分析当前模块的依赖关系,并卸载其中不再被其它已加载模块依赖的模块;

    卸载因第①步操作而无法运行的模块

    重新加载因第①②步操作而需重新加载的模块

 

自动模式保证了已加载的模块都可用,不足之处就是module loadmodule unload命令的效果和用户预期有差别。例如,VASP依赖IntelMPI,在不卸载VASP的情况下无法卸载IntelMPI;而卸载VASP的同时,也会连IntelMPI一起卸载。因此,Pmod提供了-f/--force_no_auto选项以禁用自动模式。




https://blog.sciencenet.cn/blog-2909108-1152044.html

上一篇:QE使用经验总结:画Fatband
下一篇:Wannier90输入文件中num_wann, num_bands, 和energy window等参数设置规则
收藏 IP: 121.249.15.*| 热度|

3 唐刚 刘鹏飞 赵鸿远

该博文允许注册用户评论 请点击登录 评论 (0 个评论)

数据加载中...
扫一扫,分享此博文

Archiver|手机版|科学网 ( 京ICP备07017567号-12 )

GMT+8, 2024-5-1 02:46

Powered by ScienceNet.cn

Copyright © 2007- 中国科学报社

返回顶部