引言服务器端批量提交任务
引言
许多科研活动涉及大量繁重的计算任务,如分子模拟,量化计算,数据分析等等。往往这些计算都由服务器来完成。大致的流程如下:
通常科学计算用服务器安装的都是linux等系统,且受限于网络速度,与用户的交互界面也是命令行式的(还记得dos吧)。在linux下,任何东西都是文件,任何事情都可以通过操作文件来实现。这是非常灵活的设计,方便我们定制一些特殊功能,利用好这些特性可以大大提高我们的工作效率。
在科研活动中,一个常用的研究方法是控制变量,通过改变一些变量的值来观察结果对变量的响应。具体到服务器的任务提交上,可能就会涉及到大量的大同小异的输入文件上。如果手工操作,一个文件一个文件的修改,然后一个任务一个任务的上传,这就浪费大家宝贵的生命了。
这里列举一个简单的例子来介绍处理这类任务一劳永逸的方法,归纳一下,就是批处理的思想。希望抛砖引玉对大家有所帮助。
总之,只要涉及到枯燥的步骤化的任务,立马就要想到用计算机去处理。
例子
假设我们需要研究氢分子的电子密度随原子之间距离的变化,利用开源软件GAMESS就能办到。这里重点不在介绍GAMESS的使用,重点是批量地生成输入文件与批量地提交一大帮任务的思想,所以大家对GAMESS的输入文件不熟悉也无关紧要。
服务器提交单个任务的细节
下面是提交任务的脚本,这里读者需要关心的是红字部分
#!/bin/sh
#PBS -N Gamess-Energy
#PBS -q Einstein
#PBS -j oe
#PBS -o H2e.out
#PBS -l nodes=1:ppn=4
#PBS -v step
#################################################################
#......you only need to modify the filename of these line.......#
#............or add lines similar as these......................#
cd /home/cluster/…/gamess
time ./rungms H2e.inp 00 4 >& H2e.log
#################################################################
exit 0
红字部分第一行告诉服务器,把工作路径切换到GAMESS的安装目录,第二行告诉服务器运行GAMESS的执行文件rungms,这个文件需要输入文件H2e.inp,并把结果输出到H2e.log文件中。
所以,大部分情况下,我们要让GAMESS干不同的活,只需要更改输入文件H2e.inp的内容,GAMESS就会根据输入文件的内容完成指定任务。这就够了,大部分软件都遵循这个逻辑:
批量生成多个输入文件
这里的目的是计算氢分子的电子密度随原子之间距离的变化,在输入文件中,原子距离在这里(红色标出),其它细节不用关心。
$contrl runtyp=energy cityp=aldet ISPHER=1 AIMPAC=.t. $end
$CIDET NCORE=0 NACT=124 NELS=2 $end
$basis gbasis=ACC6 $end
$system mwords=185 MEMDDI=200 $end
$eldens ieden=1 where=points $end
$data
H2 density in rhf
Dnh 2
H 1.0 0.0 0.0-0.3707511063
$end
$points
bohr 8000
0.00000031 0.00000000 0.00014314
。。。。。。
可以想象,如果我们手工在记事本中操作的话,如下
1,更改红字部分的数值,保持而其它内容不变;
2,点击另存为,选一个能代表内容的名称,找个硬盘地址保存之;
3,重复1,2步,如此反复知道生成所有需要的文件。
如果我们需要从平衡位置开始等间距地取30个计算点,那么我们就需要改动30个文件。如果需要计算10000个点那么就是不可能的任务了。
其实要实现这个功能,利用linux的bash脚本文本处理功能就能够办到,这是在下的一个解决方案
#!/bin/bash
# Content:
# This program aims to creat GAMESS input file.
# Example:
# ./creat H2e 0.1 30
# from equilibrium add 0.1 each time ,total 30 times
#-----------------------------------------------
numb=$3
step=$2
filename=$1
from='-0.3707511063'
rnew='-0.3707511063'
to="we"
cp $1.inp ${1}0.inp
for ((COUNTER=1; COUNTER< ${numb}; ++counter))
do
rnew=`echo "${rnew}-${step}"|bc`
to=${rnew}
cat ${filename}.inp|sed "s/${from}/${to}/" >& ${filename}${COUNTER}.inp
done
要看懂这个脚本,需要大家熟悉一下bash的命令,本文意不在此,不再介绍,读者可以用任意具有文本处理功能的程序语言解决。不过用bash有好处,在服务器端默认都支持bash,因此可以直接使用。总体思路是:
1, 将原始文件拷贝并重新命名;
2, 打开新命名的文件;
3, 更改需要改动的部分。
将上面的代码保存到一个文件名为creat的文件中,敲击./creat运行得到下图
至此所有输入文件已经准备好。
批量提交任务
还记得提交单个任务怎么提交么?我们将单个任务的脚本稍微改动一下,使得它可以使用输入变量,并命名为pbsrun
#!/bin/sh
#PBS -N Gamess-Energy
#PBS -q Einstein
#PBS -j oe
#PBS -o N2e.out
#PBS -l nodes=1:ppn=4
#PBS -v step
#################################################################
#......you only need to modify the filename of these line.......#
#............or add lines similar as these......................#
cd /home/cluster/… /gamess
time ./rungms H2e${step}.inp 00 4 >& /home/cluster/… /results/H2/H2e${step}.log
#################################################################
exit 0
注意文中的红色部分,这里针对我们的输入文件(以H2e1,2,3等数字区别),使得pbsrun脚本可以接受不同的数字(这里用step储存)来选择不同的输入文件,这样我们在调用提交任务的脚本时就可以方便的更改输入文件了。
接下来,我们在使用一个脚本,反复调用pbsrun,从而批量提交任务的目的,这个脚本文件以suball命名
#!/bin/bash
# Content:
# This program aims to sub all.
# Example:
# ./suball
# from equilibrium add 0.1 each time ,total 30 times
#-----------------------------------------------
for ((COUNTER=0; COUNTER<30 ; ++counter))
do
qsub ./pbsrun -v step=${COUNTER}
done
运行./suball,你就可以在服务器上看到你的任务了。
结语
本文的例子很简单,希望对大家有所启发,大家在科研工作中如果遇到繁复无意思的工作,尽量想到用计算机来完成,磨刀不误砍柴工,这样会大大提高效率。