计算化学公社

标题: 量化计算中的技巧(二):活用shell script [打印本页]

作者
Author:
sky    时间: 2017-7-12 11:58
标题: 量化计算中的技巧(二):活用shell script
不管是什么作业系统,提交的通通都是脚本。学会活用这些脚本将对减少工作量有很大帮助,有时甚至还有意想不到的功能。
举个简单例子,天河2号一个节点有24核,对于gaussian用户,用24核跑一个任务是非常不划算的。对于vasp用户,如果你有一堆小体系的计算任务你会怎么办?24核跑一个很小的任务反而会减慢计算速度。当然你也可以只申请一个节点,然后只用其中一部分核心来跑。但是无论用什么办法,都是不划算的。
如果你会写脚本,那这事就非常好办了。自己写一个简易的任务管理脚本,比如这个:
  • #!/bin/bash
  • for i in `ls *gjf`
  • do
  •   while ((1));do
  •     my_jobs=`jobs |wc -l`
  •     if [ $my_jobs -lt "4" ];then
  •       g09 $i &
  •       break
  •     else
  •       sleep 10s
  •     fi
  •   done
  • done
  • while [ $my_jobs -gt "0" ];do
  •   my_jobs=`jobs |wc -l`
  •   sleep 10s
  • done

所有的gaussian文件固定使用6核心,一个节点上跑的任务不能超过4个。每隔10秒检查一下后台运行的任务数量,少于4个的话就继续提交。等到所有任务运行完成后自动退出。稍微改改就能用于其它软件。如果不满意还能加一些更复杂的功能,比如每个任务用的核数可以不一样,只要所有任务核数加起来<24的话就继续提交。



因为我主要用VASP,后面就只拿VASP说事了。但是其中的技巧放到其它软件上也同样适用。
下面用天河2号上的若干个简单的任务来说明对shell script的运用。需要注意的是不同超算中心的作业管理系统不一样,但提交的全都是shell script脚本,因此以下内容除了提交方法不一样之外,其它部分都是通用的。

1. 输入文件检查
因为输入文件繁杂,可能辛辛苦苦排个队,排到之后输入参数错误又得重新排。可以把自己经常出错的东西写成脚本,每次提交之前检查:
  • #!/bin/bash
  • echo ""
  • echo "KPOINTS:"
  • tail -3 KPOINTS
  • echo ""
  • echo "POTCAR:"
  • grep "TITEL" POTCAR
  • echo ""
  • if [ -e POSCAR ];then
  •     echo "POSCAR:"
  •     sed -n '6,8p' POSCAR
  •     flagck.py
  • elif [ -e 00/POSCAR ];then
  •     echo "00/POSCAR:"
  •     sed -n '6,8p' 00/POSCAR
  •     cd 00/
  •     flagck.py
  •     cd ..
  • else
  •     echo "POSCAR do not exit!"
  • fi
  • dir=`pwd`
  • if [[ ! $dir =~ freq && $dir =~ dimer ]];then
  •   if [ ! -f MODECAR ];then
  •     echo ""
  •     echo "    !!!!!warning: MODECAR undetected!!!!!"
  •     echo ""
  •   fi
  • fi

这个脚本可以显示k点,赝势里的元素信息,POSCAR的基本信息,以及跑dimer时会检查有没有MODECAR.任务运行前检查一次,减少出错概率




2. 算某分子的吸附能,现在有两个问题:
  • 一开始输入的构型可能不合理,导致某几个原子之间的力非常大。如果一开始就用CG算法跑的话收敛速度会变慢,甚至有时程序会崩溃。因此需要先用最速下降法算到力小于某个值,再用CG法继续算
  • 我需要在(4*4*1)k点下的结果,但是在(4*4*1)k点下运算量太大,速度慢。因此我想要先在(3*3*1)k点下跑,最后再换到(4*4*1)k点下,能节省不少时间
如果用手工来完成这些工作,将会耗费大量的时间用于调参数、编辑新任务,还得不停地查看任务完成了没,可能最终还不如直接用一个参数跑到底来得快。


而通过shell脚本,可以把上面所有工作整合到一个任务里:
  • #!/bin/bash
  • cat >INCAR<<!
  • ...
  •   EDIFFG = -1.0
  •   NSW = 500
  •   IBRION = 3
  •   POTIM = 0.2
  • ...
  • !
  • yhrun -n 24 ~/vasp/bin/vasp-gamma >output
  • if [ -s CONTCAR ];then
  •     mv POSCAR POSCAR0 && mv CONTCAR POSCAR
  • else
  •     exit
  • fi
  • cat >INCAR<<!
  •   ISTART = 1
  •   ICHARG = 1
  • ...
  •   EDIFFG = -0.01
  •   NSW = 500
  •   IBRION = 2
  •   POTIM = 0.2
  • ...
  • !
  • yhrun -n 24 ~/vasp/bin/vasp-gamma >output
  • if [ -s CONTCAR ];then
  •     mv POSCAR POSCAR1 && mv CONTCAR POSCAR
  • else
  •     exit
  • fi
  • cat >KPOINTS<<!
  • K-Points
  • 0
  • Monhkorst-Pack
  • 4  4  1
  • 0  0  0
  • !
  • cat >INCAR<<!
  •   ISTART = 1
  •   ICHARG = 1
  • ...
  •   EDIFFG = -0.01
  •   NSW = 500
  •   IBRION = 2
  •   POTIM = 0.2
  • ...
  • !
  • yhrun -n 24 ~/vasp/bin/vasp-gamma >output

简要说明一下:
  • cat >INCAR<<!
  • ...
  •   EDIFFG = -1.0
  •   NSW = 500
  •   IBRION = 3
  •   POTIM = 0.2
  • ...
  • !

这个用于覆盖写入计算参数


  • if [ -s CONTCAR ];then
  •     mv POSCAR POSCAR1 && mv CONTCAR POSCAR
  • else
  •     exit
  • fi

这几行代码先把POSCAR文件备份,再把CONTCAR重命名为POSCAR,准备下一次计算。
对于有节点限制的同学那就是神器,提交一次任务之后就等结果就行了,不用再反复排队。或者前一天晚上提交任务,第二天早上直接拿结果,节省了大量时间。




3. 提交任务
我真正用来提交给天河的脚本dimer.sh是这个样子的:
  • #!/bin/bash
  • exe=gamma
  • node=96
  • cat >INCAR<<!
  • ...
  • balabala
  • ...
  • !
  • echo -n "start time  " >time
  • date >> time
  • if [[ $exe =~ gamma ]];then
  •     yhrun -n $node ~/vasp.5.3/bin/vasp-gamma >output
  • else
  •     yhrun -n $node ~/vasp.5.3/bin/vasp >output
  • fi
  • echo -n "end   time  " >> time ; date >> time
  • cat time >> output
  • job_log.sh
  • start_freq_job.sh ../dimer-freq/

这是一个用来跑dimer的脚本,跑完之后自动开始频率计算。

3、4两行定义了vasp的版本(是否为gamma版本)以及需要用的核心数,之后写入INCAR文件,执行程序。
第21行是任务日志,任务完成之后会把本次任务信息写到一个专门的文件里。这样下次登录的时候我就知道哪几个任务完成了。
第22行是自己写的另外一个脚本,用来把CONTCAR文件移动到../dimer-freq/文件夹下,然后自动开始频率计算。
最后通过命令:
> sub dimer.sh
来提交这个脚本,sub是我另外一个脚本,放到了系统路径下,可以直接调用,它用来提取出我自己的脚本里的vasp版本信息以及需要的核心数量,通过15行的命令提交给作业系统:
  • #!/bin/bash
  • node=`grep "node=" $1 |sed 's/\s*//g' |cut -c 6-`
  • res=$((${node}%24))
  • if [ -z $node ];then
  •     echo ""
  •     echo "node has not been defined! Check your script $1."
  •     echo ""
  •     exit
  • elif [ "$res" -ne "0" ];then
  •     echo ""
  •     echo "you defined node=$node, which is wrong. Please check again!"
  •     echo ""
  •     exit
  • fi
  • yhbatch -n $node $1

这样我通过一次任务提交就跑完了dimer,还自动完成了对它的频率分析。



4. NEB计算信息的提取
用NEB来计算过渡态,最后的信息提取是个问题。如果只有4个image可能还好,可以手动一个一个来,如果不小心跑了个16个image呢?所以还是交给shell script来处理。
  • > nebinfo
  • ############ All CONTACRs and POSCARs in packege will be converted to cartesian file ############
  • The number of images:8
  • #############################  Processing  #############################
  •                            vaspfile/ processing
  •                              gvfile/ processing
  •                               movie/ processing
  •                  ---------------  Done  ---------------

脚本nebinfo,把所有的POSCAR和CONTCAR文件保存并且自动转换为gjf文件,还提供从image1~image8的动画文件.xyz,最后全部压缩成一个文件包。脚本略复杂,就不贴出来了。


类似的例子不计其数,我写了50多个脚本用于辅助工作。有些是通用的,有些是针对某个任务写的。重复的工作基本全都被我脚本化,只需要少量时间我就能提交或者管理一大堆任务,所以工作效率很高,也能有更多时间干其它事。

我工作的脚本全都放在了这里:
github.com/Mabinogiysk/VASP-script
不定期更新,有兴趣的自行取用,另外关于怎么写脚本推荐两本书:
入门用《鸟哥私房菜》:cn.linux.vbird.org
高级玩家可用《Advanced Bash-Scripting Guide》:www.tldp.org/LDP/abs/html




作者
Author:
xiaowandouer    时间: 2017-7-12 15:36
简直就是及时雨!太有用了!还推荐了写脚本的书,10086个赞!
请教楼主:如果运行高斯任务,每个作业不超过8核,是不是将第六行的“4”改成3就可以了?在天河二号上,这个脚本怎么用,提交高斯作业的时候是不是还需要其他脚本?


作者
Author:
小书童    时间: 2017-7-12 20:33
vasp初始优化的选择最速下降法,对于的是IBRION=3吗?
作者
Author:
sky    时间: 2017-7-12 21:39
xiaowandouer 发表于 2017-7-12 15:36
简直就是及时雨!太有用了!还推荐了写脚本的书,10086个赞!
请教楼主:如果运行高斯任务,每个作业不超 ...

1. 每个作业固定8核,4改成3就行了。
2. 在天河2上跟gjf文件放在同一目录下,直接提交脚本就行了。今早临时写的,测试过了没问题。
3. 还有个问题是提交脚本之后,再往该目录下添加gjf文件就没用了。其实这个功能也能实现,懒得做了。
作者
Author:
sky    时间: 2017-7-12 21:39
小书童 发表于 2017-7-12 20:33
vasp初始优化的选择最速下降法,对于的是IBRION=3吗?

对,好像是叫最速下降吧,凭印象写的
作者
Author:
小书童    时间: 2017-7-12 22:02
sky 发表于 2017-7-12 21:39
对,好像是叫最速下降吧,凭印象写的

官网介绍,也是这么说的,Damped molecular dynamics (IBRION=3) are often useful when starting from very bad initial guesses
作者
Author:
xiaowandouer    时间: 2017-7-13 08:58
sky 发表于 2017-7-12 21:39
1. 每个作业固定8核,4改成3就行了。
2. 在天河2上跟gjf文件放在同一目录下,直接提交脚本就行了。今早 ...

谢谢回复!第三条提到的功能,对天河二号这样的服务器很有用,不然作业不能同步结束的话,还是会造成资源浪费。脚本盲太希望楼主能把这部分功能补全了!
作者
Author:
sky    时间: 2017-7-13 10:23
xiaowandouer 发表于 2017-7-13 08:58
谢谢回复!第三条提到的功能,对天河二号这样的服务器很有用,不然作业不能同步结束的话,还是会造成资源 ...

自己学着写吧,没什么难度。先把我的脚本研究清楚,不懂的命令百度,然后在上面改一改就行了。
给你提供个思路,建A、B两个文件夹,A文件夹放gjf文件。写个wile循环ls出里面的gjf文件,当节点空闲时把A文件夹里的gjf文件mv到B文件夹里然后运行。
作者
Author:
xiaowandouer    时间: 2017-7-13 11:50
sky 发表于 2017-7-13 10:23
自己学着写吧,没什么难度。先把我的脚本研究清楚,不懂的命令百度,然后在上面改一改就行了。
给你提供 ...

谢谢!
作者
Author:
biancheng159    时间: 2021-12-30 18:27
关于第一个g09这个脚本*.sh,几个问题请教下,
1. 是用类似yhrun -N 1 -n 1 -c 24 -p test *.sh这样提交上去么,此行的末尾要加“&”么?
2. 这个*.sh脚本经yhrun后是全程在被指派的计算节点(而不是当前登录节点)运行吧,那my_jobs=`jobs |wc -l`获取的是该计算节点上正运行的jobs数?
3. “while ((1));do”后的“g09 $i &”处的"&"与后续break 、sleep等的配合不是很明白,我试了下如果不加break、sleep等,yhq会发现程序长期在计算节点上运行(实际g09 *.gjf任务早已结束),只能yhcancel取消。




欢迎光临 计算化学公社 (http://bbs.keinsci.com/) Powered by Discuz! X3.3