Snakemake(v7.32.4)动态资源配置问题:外部设置及干运行/规则图生成
Snakemake动态资源设置相关问题解答
我正在使用Slurm任务管理器运行Snakemake(v.7.32.4)流程,已基于文件大小和尝试次数为每个规则动态设置资源(时间和内存),示例代码如下:
rule index: resources: mem_mb = lambda wildcards, input, attempt: ( 200 * attempt ), runtime = lambda wildcards, input, attempt: ( "{minutes}min".format( minutes=max( int((input.size_mb / 5000) * attempt), 1) ) )
以下是两个问题的解决方案:
1. 能否在Snakefile外部动态设置资源?
可以实现,分两种场景处理:
场景1:仅存放静态参数到外部配置
如果只是想把资源计算的基准值(如内存基数、文件大小系数)放到外部,使用YAML配置文件即可:
- 新建
config.yaml:
index_resources: base_mem: 200 size_factor: 5000
- 在Snakefile中加载配置并引用:
configfile: "config.yaml" rule index: resources: mem_mb = lambda wildcards, input, attempt: config["index_resources"]["base_mem"] * attempt, runtime = lambda wildcards, input, attempt: ( "{minutes}min".format( minutes=max( int((input.size_mb / config["index_resources"]["size_factor"]) * attempt), 1) ) )
场景2:把资源计算逻辑完全放到外部
如果要将整个资源计算逻辑移出Snakefile,使用Python格式的配置文件更合适:
- 新建
config.py:
def calculate_index_mem(attempt): return 200 * attempt def calculate_index_runtime(input_size, attempt): minutes = max(int((input_size / 5000) * attempt), 1) return f"{minutes}min"
- 在Snakefile中导入并调用这些函数:
from config import calculate_index_mem, calculate_index_runtime rule index: resources: mem_mb = lambda wildcards, input, attempt: calculate_index_mem(attempt), runtime = lambda wildcards, input, attempt: calculate_index_runtime(input.size_mb, attempt)
注意:YAML配置文件无法存储函数逻辑,仅适合存放静态参数;Python配置文件支持完整的代码逻辑,灵活性更高。
2. 动态设置资源后如何执行干运行或生成规则图?
干运行时出现Cannot parse runtime value into minutes for setting runtime resource: <TBD>错误,是因为输入文件尚未生成,input.size_mb无法获取有效值。可以通过以下两种方法解决:
方法1:为缺失的输入文件设置默认值
在资源计算的lambda中,使用getattr为不存在的size_mb属性设置默认预估大小,确保干运行时能生成合法的runtime值:
rule index: resources: mem_mb = lambda wildcards, input, attempt: 200 * attempt, runtime = lambda wildcards, input, attempt: ( "{minutes}min".format( minutes=max( int((getattr(input, "size_mb", 1000) / 5000) * attempt), 1) ) )
这里的1000是预估的输入文件大小(MB),可根据实际场景调整。
方法2:判断干运行状态并返回占位资源值
利用Snakemake内置的workflow.dryrun变量,在干运行时直接返回一个占位的资源值,避免计算文件大小:
rule index: resources: mem_mb = lambda wildcards, input, attempt: 200 * attempt if not workflow.dryrun else 200, runtime = lambda wildcards, input, attempt: ( "{minutes}min".format( minutes=max( int((input.size_mb / 5000) * attempt) if not workflow.dryrun else 1, 1) ) )
修改后,执行干运行命令:
snakemake --profile Config/Profiles/slurm -np
生成规则图命令:
snakemake --profile Config/Profiles/slurm -np --rulegraph | dot -Tsvg > rulegraph.svg
就能正常执行,不会再出现
内容的提问来源于stack exchange,提问作者Agustin Carbajal
相关产品推荐
相关产品推荐

