计算化学公社

 找回密码 Forget password
 注册 Register
Views: 76|回复 Reply: 0
打印 Print 上一主题 Last thread 下一主题 Next thread

[辅助/分析程序] 利用btrun管理任务运行队列

[复制链接 Copy URL]

889

帖子

15

威望

4084

eV
积分
5273

Level 6 (一方通行)

鸩羽

本帖最后由 wal 于 2026-8-24 23:56 编辑

1 前言

多数量子化学程序的运行需要极长的时间,如果研究者想要运行一批任务,就免不了涉及到队列运行问题。就我所知,想要达成队列运行,有如下解决方案:

1)采用成熟的作业调度系统如slurm,sge,pbs等
作业调度系统在资源分配上做的很出色,是多数集群的队列管理首选。但在个人单机场景中,这些调度系统涉及到一些初见时比较难以理解的概念,且安装比较复杂,不太方便推广。
使用作业调度系统还有另一个问题,就是任务模板该如何管理。如果每次运行时都手写任务脚本,将会非常繁琐,像笔者这样懒惰而记性不好的人一看就该放弃了。

2)使用自建调度脚本
自建调度脚本的优点是运行命令可以设计得极简,启动调度脚本就能开始运行。
但缺点是此类调度脚本常常只针对某种程序、某类工作流等。若想实现并行,会极大提高调度脚本本身的复杂度。如果还想兼顾不同程序的兼容性,甚至可能需要像作业调度系统一样需要任务脚本来启动。

2 思路

为了解决上述问题,构造一种既适用于单机又适用于集群的队列管理程序,笔者做过一些尝试。首先,若要队列运行一些量子化学任务,我们的有效输入信息大致有以下三类:
1)每个任务的资源控制
2)每个任务的环境加载
3)每个任务的主运行命令
其余信息,如slurm模板八股文之类每个任务都一致的此处不算做有效信息。
对于信息(1),笔者自己做计算的时候,一般都是挑一个核数,然后所有程序都用这个设置,只有在特殊需求时才会更改。此出可暂时认为资源控制可以有一个默认值,特殊需求使用命令行临时覆盖
对于信息(2、3),若想做到通用队列,则必须以某种方式区分不同任务。此处笔者的选择是使用配置文件,按程序划分,每个程序有一个配置文件,保存其环境和运行命令。
有了这些信息,我们就可以像搭积木一样把所有东西全都搭起来,最终按照需求组合成作业调度系统或自建队列的任务脚本。

早期笔者尝试过bash脚本,但是发现bash脚本想做本地队列比较费劲,所以给队列单独做了个python脚本。后来觉得这样不是很优雅,于是把整个队列管理做成了一整个程序,也就是btrun。
注:btrun是某更大项目的一个组件,所以并不仅仅为了上述目的而设计,其中可能存在一些其他与本文无关的功能,可以忽视。

3 btrun

btrun是一个队列管理工具,支持主流的slurm、pbs、sge作业调度系统的任务脚本统一生成,也有自带的本地队列供没有安装调度系统的服务器单机串行、并行。对于大部分量子化学程序,在用户配置好后,只需要执行如'btrun task -t g16'这样的短命令,就可以完成对当前目录下所有相应程序输入文件的排队运行。

3.1 配置文件

btrun采用配置文件管理每种量子化学程序的构造信息,配置文件统一存放在~/.bane/task/envs里。在使用btrun前,你需要为你常用的量化程序做好配置文件。例如,Gaussian的~/.bane/task/envs/g16.conf:
  1. [main]
  2. # 资源配置
  3. CONF_CORES=32
  4. CONF_MEMORY=96000
  5. SUFFIX=gjf
  6. CONF_SPAN_NODES=false

  7. [ENV_SETUP]
  8. # g16 environment
  9. # module load g16
  10. source "$HOME/apprepo/gaussian/16-hy/scripts/env.sh"
  11. export PGI_FASTMATH_CPU=sandybridge
  12. export PATH=~/scripts/bin:$PATH

  13. [RUN_CMD_TEMPLATE]
  14. g16loop "${ACTUAL_INPUT_FILE}" --crash-handle all > "${ACTUAL_OUTPUT_FILE}"
复制代码
配置文件格式为类toml。[main]区配置默认本程序的提交资源,以及该程序对应的输入后缀、其他杂项设置。[ENV_SETUP]区直接写环境加载命令。[RUN_CMD_TEMPLATE]直接写程序运行命令。由于早期是bash设计,[RUN_CMD_TEMPLATE]处残留了bash风格的变量占位符痕迹,即如果用户需要使用输入文件名,则用"${ACTUAL_INPUT_FILE}"占位;输出文件则用"${ACTUAL_OUTPUT_FILE}" 占位。像GAMESS之类的需要在命令行指出核数的程序,则可以用"${CORES}"占位。

3.2 资源和作业调度系统管理

由于需要了解本机情况,且所需信息很碎,btrun提供了init命令来初始化。btrun init命令将自动探查资源情况并作为建议值提供,而用户可以交互式一项一项自定义资源要求。具体的看示例吧

  1. [gaus@login06 ~]$ btrun init
  2. Profile/cluster name [default]:
  3. Scheduler backend (slurm/sge/pbs/local) [slurm]:
  4. Detected local machine:
  5.   cores: 64
  6.   memory_mb: 257529
  7.   gpus: 0
  8.   scheduler commands: slurm,sge/pbs
  9.   inferred role: login_node
  10. Enable local execution target? [y/N]: y
  11.   Local role [login_node]:
  12.   Local max CPU cores [64]:
  13.   Local max memory, MB [257529]:
  14.   Local max GPUs [0]:
  15.   Local GPU ids, comma-separated:
  16.   Reserve CPU cores for OS/interactive use [4]:
  17.   Reserve memory for OS/interactive use, MB [16384]:
  18.   Reserve GPUs [0]:
  19. Discovered scheduler queues: whhcnormal
  20. Use discovered queues? [Y/n]:
  21. Configure queue 'whhcnormal'? [Y/n]:

  22. Queue 'whhcnormal' resources and submit header
  23.   Logical btrun queue key: whhcnormal
  24.   Scheduler queue/partition name: whhcnormal
  25.   Description [Discovered scheduler queue whhcnormal]:
  26.   Aliases, comma-separated:
  27.   Priority used by fallback, lower is preferred [10]:
  28.   Physical CPU cores per node [32]:
  29.   Max nodes [377]:
  30.   Max CPU cores per node [32]:
  31.   Max memory per node, MB [255500]:
  32.   Max GPUs per node [0]:
  33.   Default cores per job [16]: 32
  34.   Default memory per job, MB [64000]: 96000
  35.   High-memory threshold, MB/core [7984]:
  36.   Slurm header style (ntasks_per_node/ntasks/cpus_per_task) [ntasks_per_node]:
  37. Add another queue manually? [y/N]:
复制代码
在配置好后,btrun就可以开始管理本地队列和作业调度系统队列了。

3.3 作业调度系统管理

由于笔者的主力是slurm调度系统,btrun对slurm生成的默认模板会比较稳定,而PBS和SGE则可能需要用户手动检查一下。此外,由于每个集群对作业脚本有不同的要求,比如拒绝某种选项,支持某种选项,只能用某种选项,这类村规难以统一,因此btrun允许用户自定义任务脚本的模板。例如,上述init自动生成的slurm模板配置保存在~/.bane/task/btrun/queues/default.yaml,内容为
  1. kind: queue_catalog
  2. schema_version: 1
  3. profile: default
  4. scheduler: slurm

  5. defaults:
  6.   queue: whhcnormal
  7.   priority_policy: lower_priority_first

  8. queues:
  9.   whhcnormal:
  10.     scheduler_queue_name: "whhcnormal"
  11.     description: "Discovered scheduler queue whhcnormal"
  12.     aliases: []
  13.     enabled: true
  14.     priority: 10
  15.     resources:
  16.       physical_cpu_num: 32
  17.       max_nodes: 455
  18.       max_cores_per_node: 32
  19.       max_memory_mb_per_node: 255500
  20.       max_gpus_per_node: 0
  21.       default_cores: 32
  22.       default_memory_mb: 96000
  23.       high_memory_threshold_mb_per_core: 6000
  24.     header_lines:
  25.       - "#!/bin/bash"
  26.       - "#SBATCH -J {{job_name}}"
  27.       - "#SBATCH -p {{scheduler_queue_name}}"
  28.       - "#SBATCH -N {{nodes}}"
  29.       - "#SBATCH --ntasks-per-node={{cores_per_node}}"
  30.       - "#SBATCH --mem={{memory_mb_per_node}}M"
  31.       - "{{array_directive}}"
  32.       - "export CORES={{cores}}"
  33.       - "export BTRUN_QUEUE={{queue_name}}"
  34.       - "cd {{workdir_quoted}} || exit 97"
复制代码
其中,header_lines:后面的内容均为slurm脚本头。有的集群只能使用ntasks-per-node,有的集群建议使用ncpus,有的集群禁止指定mem,用户可以根据需要修改这里的模板,使得渲染出的任务脚本符合自己的需求。

3.4 提交作业

完成上述配置之后,btrun就正式可用了。假如你配置好了g16的conf文件,而当前目录下存在1.gjf,2.gjf,3.gjf,1.log,则运行
  1. btrun task -t g16
复制代码
btrun会先查找~/.bane/task/envs/g16.conf,然后读取SUFFIX值,确定要找的任务目标。此处为gjf,于是1.gjf,2.gjf,3.gjf均进入候选。随后检查是否存在同stem的log(这个输出后缀可以用OUTPUT_SUFFIX指定),发现1.log,认为这个已经运行过了,避免重复提交,排除该任务。随后,若配置了作业调度系统,则btrun组合header、环境加载、运行命令为任务脚本,并直接提交2.gjf、3.gjf到作业调度系统;
若没有作业调度系统,btrun会使用自己实现的本地队列来进行串行/并行任务。不过由于笔者平常的环境都有slurm,local队列较少使用,因此btrun的local队列可能存在一些bug,需要一些验证,欢迎反馈bug。进入local queue模式时,btrun生成btq文件(也就是btrun自带队列的任务脚本),然后开始运行。btrun会简单计算资源如何组合,如总共64核,提交上来一批32核的任务,且内存相加不超过内存上限,则btrun会两个两个地并行。但是btrun不会像真正的作业调度系统一样绑核,也不会实际限制内存分配,本质上资源分配只在btrun内部验证一下,后面跟bash去执行那个任务脚本没啥区别,这一点需要注意。以及自然,btrun的队列是阻塞运行的,如果想后台的话需要使用nohup等方式实现。可以使用btrun queue list来简单查询队列信息,btrun queue cancel来终止某个任务,btrun queue history看历史记录等,其他详细信息可以看btrun queue的帮助。
  1. $ btrun queue list
  2. JOBID                  STATE     BACKEND PROFILE           PID EXIT JOB_NAME                 WORKDIR
  3. 260823-170000_aaaaaaaa running   local   -               16995    - live-job                 /tmp/live

  4. $ btrun queue history
  5. JOBID                  STATE     BACKEND PROFILE           PID EXIT JOB_NAME                 WORKDIR
  6. 260823-160000_bbbbbbbb done      local   -                   -    0 done-job                 /tmp/done
  7. 260823-150000_cccccccc failed    local   -                   -  127 failed-job               /tmp/failed
复制代码

btrun还有更多调整提交细节的功能,可以在运行btrun task -h和btrun queue -h在帮助里查看。例如btrun task -h输出:
  1. $ btrun task -h
  2. Standalone task submission

  3. USAGE:
  4.   btrun task [<file-or-directory>...] [OPTIONS]

  5. INPUT:
  6.   <file-or-directory>...          Input files or directories

  7. OPTIONS:
  8.   -h, --help                      Show help for this command

  9. Common submission options:
  10.   -b, --backend <auto|local|slurm|sge|pbs>
  11.                                   Filter targets by backend; auto selects from discovered local, scheduler,
  12.                                   and remote targets
  13.   -L, --local                     Restrict selection to the local file-queue runner
  14.   -S, --slurm                     Restrict selection to Slurm targets, local or remote
  15.   -E, --sge                       Restrict selection to SGE targets, local or remote
  16.   -B, --pbs                       Restrict selection to PBS targets, local or remote
  17.   -P, --profile <profile>         Restrict selection to one execution profile
  18.   --profiles <profile,...>        Restrict selection to a comma/semicolon/space-separated profile target pool
  19.   -D, --profile-dir <directory>   Directory containing execution profiles
  20.   -q, --queue <queue>             Require a queue name, alias, or native partition
  21.   --auto-target                   Allow unconstrained automatic selection of remote profiles
  22.   --no-auto-target                Disable automatic remote-profile selection for this invocation
  23.   --no-local                      Exclude the local file-queue runner
  24.   --health-check                  Probe candidate remote scheduler commands over SSH
  25.   --no-health-check               Disable remote scheduler health probes for this invocation
  26.   --explain                       Print discovered, rejected, and selected execution targets
  27.   --selection-mode <local_first|remote_first|best_fit|first_runnable_by_priority>
  28.                                   Target ordering: local_first, remote_first, best_fit, or
  29.                                   first_runnable_by_priority
  30.   -d, --dry-run                   Render/prepare work but skip submission
  31.   -k, --keep-script               Keep generated submit scripts
  32.   -p, --path <directory>          Directory to scan for kick/submit/render/task

  33. Local queue options:
  34.   -w, --poll <seconds>            Runner polling interval in seconds; default: 5
  35.   -F, --follow                    Follow local job .out/.err logs in this terminal
  36.   --verbose                       Print full local job IDs, paths, and finish source
  37.   --detach                        Start or join a short-lived background local runner
  38.   --no-detach                     Disable detached local-runner mode for this invocation
  39.   -c, --cores <count>             Total CPU cores available to the local runner
  40.   --gpus <count>                  Total GPUs available to the local runner
  41.   --gpu-ids <id,...>              GPU IDs visible to local jobs, for example 0 or 0,1

  42. Batch submission options:
  43.   --max-submit <count>            Process at most N discovered jobs in this invocation; default: unlimited

  44. Task options:
  45.   --config-dir <directory>        Directory containing <type>.conf files
  46.   -r, --raw-mode                  Submit each input directory as a raw task
  47.   --file-mode                     Force normal input-file mode when RAW_MODE=true
  48.   -f, --force                     Submit even when expected output already exists
  49.   -a, --recursive                 Recursively scan input directories
  50.   -l, --list-types                List available task types in the config search path
  51.   -H, --help-type <type>          Show the HELP_START/HELP_END block from TYPE.conf
  52.   -t, --type <type>               Task type resolved from TYPE.conf; defaults from manifest, then gaussian
  53.   -n, --task-cores <count>        Per-job CPU cores; --cores is also used when this option is omitted
  54.   -m, --memory <megabytes>        Per-job memory in MB
  55.   -x, --extra-args <arguments>    Value for EXTRA_ARGS in RUN_CMD_TEMPLATE
  56.   --post-var <variable>           Append a named config variable after the main command

  57. Behavior:
  58.   task builds jobs from <type>.conf plus explicit input files, scanned
  59.   input directories, or task.manifest.json.

  60. Type/config resolution:
  61.   Type priority: -t/--type, then task.manifest.json program_params.prog,
  62.   then task.manifest.json program_type, then gaussian. TYPE.conf is found
  63.   from --config-dir, BTRUN_TASK_CONFIG_DIR, BANETASK_ENVCONF_PATH,
  64.   ./envs, ./conf/envs, installed envs, and ~/.bane/task/envs.

  65.   POSIX path-list values use ':'; Windows path-list values use ';'.

  66. Manifest fields used when present:
  67.   input_files, output_file_name, program_type, program_params.prog,
  68.   program_params.args/extra_args, nprocs/nproc/cores, memory/mem,
  69.   maxcore, cores_pre_node/cores_per_node, gpus, gpu_mem, gpu_type.

  70. When no task.manifest.json is present, g16 inputs are probed
  71.   for %nprocshared/%nproc and %mem, and orca inputs for %pal/!PALN
  72.   and %maxcore, unless CLI options override them.

  73. Examples:
  74.   btrun task -L -t gaussian --path ./cases -a -c 64 -n 16
  75.   btrun task -S -t orca mol1.inp mol2.inp
  76.   btrun task --path ./case-with-manifest
  77.   btrun task -l --config-dir ~/.bane/task/envs
  78.   btrun task -H gaussian
  79.   btrun help conf

  80. Use 'btrun help conf' for the task environment .conf format.
复制代码

3.5 其他

btrun存在一些其他的需要提及的默认行为,在这里提示。可能有一些其他没想到的,随时补充。
1)对于Gaussian任务(必须是g16.conf)和ORCA任务(必须是orca.conf),若没有在命令行用-m,-n等指定核数,btrun会尝试解析输入文件头的资源设置作为提交作业的资源设定。
2)btrun会根据队列的memory-per-core(init时的High-memory threshold参数)限制来动态调整申请的资源。例如,对于postHF任务,通常需要小核数+大内存。然而,一些集群要求内存与核之比不能高于xxxx,因此量化实际使用资源不等于提交所用资源。遇到超出队列memory-per-core的高内存需求任务时,btrun会用总内存除以memory-per-core阈值,向上取整得到最终请求核数。例如,队列限制memory-per-core最高3000,我有个任务是需要使用16核+96000M的,btrun会利用96000/3000=32,尝试提交一个32核(当然队列必须有这么多核)、memory-per-core=3000的任务。
3)High-memory threshold还有另一个行为,就是在任务内存需求超出High-memory threshold时,如果你配置了其他队列,btrun会优先尝试把任务转交到一个内存够高的队列去,而不是扩大核数在本队列提交。
4)当前btrun task对GPU的管理方案不完整,未来可能会进一步支持

4 下载
btrun暂未开源,未来可能会随另一个项目一块放出。二进制文件下载:
linux: btrun.zip (2 MB, 下载次数 Times of downloads: 0)
配置文件示例: envs.zip (3.75 KB, 下载次数 Times of downloads: 0) (不要照抄,按照你当前环境的实际情况修改)

欢迎反馈bug,直接在本贴回复即可



评分 Rate

参与人数
Participants 1
eV +5 收起 理由
Reason
chenjinfeng850 + 5 GJ!

查看全部评分 View all ratings

某不知名实验组从苞米地里长出来的计算选手

本版积分规则 Credits rule

手机版 Mobile version|北京科音自然科学研究中心 Beijing Kein Research Center for Natural Sciences|京公网安备 11010502035419号|计算化学公社 — 北京科音旗下高水平计算化学交流论坛 ( 京ICP备14038949号-1 )|网站地图

GMT+8, 2026-8-25 09:49 , Processed in 0.613042 second(s), 24 queries , Gzip On.

快速回复 返回顶部 返回列表 Return to list