向Slurm集群提交Gaussian任务的两个注意事项
先说注意事项,后面解释原因:(假设并行核数64)
不能只在Slurm提交脚本中指定并行CPU核数,必须在Gaussian输入文件中同时通过 “nprocshared=64” 指定,且两个地方指定的并行核数应当相同。
Slurm提交Gaussian单机多核任务的脚本里对并行核数的指定应当用 “#SBATCH -c 64” 而非 “#SBATCH –ntasks-per-node=64” 。
以下是简要的原因解释:
1. 为什么不能只在Slurm提交脚本中指定并行CPU核数,必须在Gaussian输入文件中同时通过 “nprocshared=64” 指定?
这是因为像Gaussian这样能在输入文件中指定并行核数的程序,其读取输入文件中并行核数指定的优先级总是大于从提交脚本读取并行核数,此时如果未在输入文件中明确指定“nprocshared=64”,Gaussian默认会将并行核数识别为1(除非在安装目录下添加有指定默认设置的文件,对于Gaussian为“Default.Route”。这种情况下Gaussian会从默认设置中读取并行核数,但如果输入文件显式指定了并行核数,Gaussian依然会只按输入文件的来)。也就是说,即使你在提交脚本中明确指定了请求并行的核数,只要输入文件没有同时指定,那么Gaussian任务实际上始终只有一个核在跑,而集群系统依据脚本将一个节点的64个核全部分配下去,导致你的单核运行任务白白占着那么多资源不用,不仅自己会因为算得慢而急得团团转,也会因为资源的无端占据影响别的用户排队跑任务。
2. 为什么Slurm提交Gaussian任务的脚本里对并行核数的指定应当用 “#SBATCH -c 64” 而非 “#SBATCH –ntasks-per-node=64” ?
这两个选项,应该选择哪个,取决于脚本要调用程序的多核并行模式。必须知道,一般计算化学程序的多核并行模式分为两种:MPI并行和OpenMP并行。VASP和ORCA一般属于前者,Gaussian严格属于后者,CP2K则两种模式均支持(VASP其实也可以用OpenMP,但截至目前没见有人用过;ORCA有少量代码也支持OpenMP,但跟没有一个样)。两个并行方式在资源配置方面最大的不同就是运行内存的分配问题:MPI不同进程的资源分配是相互独立的,每个MPI进程各占一份独有的内存;而OpenMP并行是所有进程共同享有同一份运行内存(即“shared memory”)。对于MPI并行,应当使用“#SBATCH –ntasks-per-node=64”;对于OpenMP并行,则为“#SBATCH -c 64”。
Gaussian的输入文件可以通过“%mem=”指定内存请求量(需带单位),且该请求量为所有OpenMP线程共享。如果你的任务对内存要求非常低(比如中小体系的结构优化),那么两者混用姑且可以接受,仅就多核并行效率来看没有明显区别;但如果对内存有明显要求(比如算激发能),则必然遭殃,哪怕本来没有什么要求,只是在输入文件里面添加了这一选项,也有很大概率会报错。比如你算激发能,用了64个核,按照每个核至少分配1GB、一般分配2GB左右的惯例在输入文件添加了“%mem=128GB”,本来应该是64个核共享这128GB内存,你一用“#SBATCH –ntasks-per-node=64”,把这64个线程分割了开来,导致实际上被识别成每个核分配128GB内存,一般一个这样的服务器节点会装有500GB内存左右的配置,你这样一搞,很容易使得软件错误地判定剩余内存不够用,导致还没开始计算就报错停止。(与此不同,ORCA输入文件指定内存和CP2K杂和泛函计算输入文件中指定内存就是每个MPI进程各自使用的内存量)