如何在有限的内存中使用并行的蛇形作业?



Snakemake的调度器忽略了我的mem_mb声明,并在合计需求超过可用内存的并行作业中执行(例如,在128 GB的系统中使用mem_mb=53000的三个作业)。此外,即使串行运行,它也可以运行系统中无法满足声明需求的作业(当我运行snakemake -T10时超过1TB)。Snakemake似乎也使作业保持运行,即使它分配的内存比声明的要多得多。

我的想法是告诉Snakemake期望一个分配到一定数量内存的作业,相应地计划工作流并对内存消耗实施声明的约束。有没有办法做到这一点与Snakemake不诉诸串行执行?

我有一个工作流,有很多调用一个规则,可能是相当内存轻或内存重。由于我希望从并行执行中获益,因此我声明该作业在第一次尝试运行时需要1000 MiB,在后续尝试中需要更多MiB。规则是这样的:

def get_mem_mb(wildcards, attempt):
return 1_000 if attempt == 1 else (51_000 + 1_000 * 2 ** (attempt - 1))
rule Rulename:
input:
"{CONFIG}.ini"
output:
"{CONFIG}.h5"
resources:
mem_mb=get_mem_mb
shell:
"python script.py -o {output} -i {input}"

这不是Snakemake内存限制的副本,因为唯一的答案是不完整的(它没有涵盖"内存限制");部分)。目前,这是我的问题,有完整(但分裂)的答案:

  • 调度作业时的资源管理,
  • 强制作业声明的内存限制。

我是基于我之前的回答,但我不确定我是否正确理解了这个问题。也许你可以用--restart-times 10和动态内存约束来运行snake makake:

rule all:
input:
"a"
def get_mem_mb(wildcards, attempt):
"""
First attempt uses 10 MB, second attempt uses 100MB, third 1GB,
etc etc
"""
return 10**attempt
rule:
output:
"a"
threads: 1
resources:
mem_mb = get_mem_mb
shell:
"""
ulimit -v $(({resources.mem_mb} * 1024))
python3 -c 'import numpy; x=numpy.ones(1_000_000_000)'
touch a
"""

注意,这只适用于linux机器。这种方法的作用是为规则分配一定数量的内存,第一次尝试时为10MB。如果规则试图分配更多的内存,则规则崩溃,并使用100MB内存重新启动。如果失败了1GB,等等。您可能希望将get_mem_mb规则的缩放方式更改为例如2**attempt

我在评论中找到了一个相关问题的提示:如何在snakemake中设置绑定内存限制

"ressources"在蛇的制造是[…]你所赋的任意值要整条蛇跑,而蛇不会同时跑该资源中的作业总数超过分配的数量运行

因此,为了防止Snakemake同时运行内存繁重的作业,我需要告诉它限制是什么(例如--res mem_mb=100000)。

最新更新