使用SBatch脚本托管Snakemake SLURM任务时内存参数冲突问题求助
我有一套能在HPC上通过SLURM正常运行的Snakemake数据处理流水线,直接在本地终端启动时,任务可以并行提交且运行无异常。但流水线耗时极长,我需要通过VPN访问受保护环境处理数据,而VPN存在超时机制,无法一直保持终端在线,因此打算用.sbatch脚本托管任务执行,脚本内容如下:
#!/bin/bash #SBATCH --account=<acct> #SBATCH --partition=<part> #SBATCH --time=48:00:00 #SBATCH --nodes=1 #SBATCH --ntasks=1 #SBATCH --output=./logs/log.out #SBATCH --error=./logs/log.out # 切换到Snakemake工作目录 cd path/to/workdir # 创建日志目录 mkdir -p logs # 加载环境 ml miniconda3/latest module use ~/MyModules source /path/to/miniconda/etc/profile.d/conda.sh conda activate snakemake # 启动预处理流水线 snakemake --slurm --profile profile/cluster/
但运行该SBatch脚本后任务失败,报错信息为:srun: fatal: SLURM_MEM_PER_CPU, SLURM_MEM_PER_GPU, and SLURM_MEM_PER_NODE are mutually exclusive.
直接在终端启动Snakemake时不会出现此错误,说明问题并非出自Snakemake配置文件本身。请问如何通过SBatch脚本正确托管后续的SLURM任务提交?
这个错误的核心原因是:SBatch提交的主任务自带的SLURM内存环境变量,与Snakemake提交子任务时传递的内存参数发生了互斥冲突。当用SBatch启动Snakemake主进程时,主任务的SLURM环境变量会被子任务继承,导致srun同时收到两种互斥的内存参数。
解决方法如下:
1. 修改SBatch脚本,避免主任务传递互斥内存参数
当前SBatch脚本未显式设置内存参数,但部分HPC集群会默认分配SLURM_MEM_PER_CPU或SLURM_MEM_PER_NODE。为防止继承冲突,建议在SBatch脚本中仅显式设置一种内存参数,或者让主任务使用最小资源(因为Snakemake主进程只需要协调任务,消耗极低)。
同时,给Snakemake添加--no-srun参数,强制它用sbatch而非srun提交子任务,彻底切断主任务环境变量的继承影响:
修改后的SBatch脚本示例:
#!/bin/bash #SBATCH --account=<acct> #SBATCH --partition=<part> #SBATCH --time=48:00:00 #SBATCH --nodes=1 #SBATCH --ntasks=1 #SBATCH --cpus-per-task=1 #SBATCH --mem=1G # 仅设置一种内存参数,避免互斥 #SBATCH --output=./logs/log.out #SBATCH --error=./logs/log.err cd path/to/workdir mkdir -p logs ml miniconda3/latest module use ~/MyModules source /path/to/miniconda/etc/profile.d/conda.sh conda activate snakemake # 添加--no-srun,让Snakemake直接调用sbatch提交子任务 snakemake --slurm --profile profile/cluster/ --no-srun
2. 检查Snakemake集群配置,确保内存参数唯一
打开你的Snakemake集群配置文件(通常是profile/cluster/config.yaml),确保里面只定义一种内存参数,比如仅用mem_per_cpu或mem_per_node,不要同时出现两种互斥配置。
示例配置(仅使用mem_per_cpu):
cluster: sbatch: --account: <acct> --partition: <part> --mem-per-cpu: 4G --time: "24:00:00" jobs: 20
为何直接终端运行无问题?
直接在终端启动Snakemake时,主进程不在SLURM作业环境中,不会传递任何SLURM内存环境变量给子任务,Snakemake仅用自身配置的参数提交任务,因此不会出现参数冲突。
内容的提问来源于stack exchange,提问作者Joshua Mincer

