Snakemake 在开始下一个并行作业之前等待完成所有并行作业
Snakemake waiting to finish all parallel jobs before starting next parallel job
我编写了运行 Muscle(MSA 工具)的 Snakemake 规则来计算目录中所有文件的多序列比对 (MSA)。该任务非常并行,因为不同的文件不相互依赖。问题是,Snakemake 在 n 个“批次”中运行此规则,其中 n 是作为参数提供给 Snakemake 的核心:
snakemake -j 4 msa
.
Snakemake 以 运行 4 个并行作业开始,它会等到每个作业都完成,然后再开始新的 4 个作业“批次”。这会浪费 CPU 时间,因为输入文件的大小差异很大,并且它们的 MSA 计算时间可能从几秒到几分钟不等。导致以下执行流程:
job1|----- |job5|----- |...|->
job2|--- |job6|-------- |...|->
job3|----------------|job7|-- |...|->
job4|- |job8|----------|...|->
我如何告诉 Snakemake 真正并行化作业?
CLUSTER_IDS, = glob_wildcards(os.path.join(WORK_DIR, "fasta", "{id}.fasta"))
rule msa:
input:
expand(os.path.join(WORK_DIR, "msa", "{id}.afa"), id=CLUSTER_IDS)
rule:
input:
os.path.join(WORK_DIR, "fasta", "{id}.fasta")
output:
os.path.join(WORK_DIR, "msa", "{id}.afa")
shell:
"{MUSCLE_PATH}/muscle3.8.31_i86darwin64 -in {input} -out {output}"
你用的是哪个版本的snakemake。我很确定这是因为最近 -j
和 --cores
标志的工作方式发生了变化。
是否每个“作业”运行 在 1 个线程上?
我建议在你的规则中使用 threads:
指令,你可以像这样给规则 1 线程:
rule:
input:
os.path.join(WORK_DIR, "fasta", "{id}.fasta")
output:
os.path.join(WORK_DIR, "msa", "{id}.afa")
threads:
1
shell:
"{MUSCLE_PATH}/muscle3.8.31_i86darwin64 -in {input} -out {output}"
然后你可以运行 snakemake 使用下面的命令:
snakemake --cores 4
现在最多应该 运行 四个 rules/jobs,但是一旦完成就会开始一个新的。
它也可能与 -j
一起使用,但我认为最好将工作和 cores/processes 分开考虑,因为最近这些选项发生变化的动机也是如此。
Snakemake从5.30.1升级到6.5.2版本后问题解决
我编写了运行 Muscle(MSA 工具)的 Snakemake 规则来计算目录中所有文件的多序列比对 (MSA)。该任务非常并行,因为不同的文件不相互依赖。问题是,Snakemake 在 n 个“批次”中运行此规则,其中 n 是作为参数提供给 Snakemake 的核心:
snakemake -j 4 msa
.
Snakemake 以 运行 4 个并行作业开始,它会等到每个作业都完成,然后再开始新的 4 个作业“批次”。这会浪费 CPU 时间,因为输入文件的大小差异很大,并且它们的 MSA 计算时间可能从几秒到几分钟不等。导致以下执行流程:
job1|----- |job5|----- |...|->
job2|--- |job6|-------- |...|->
job3|----------------|job7|-- |...|->
job4|- |job8|----------|...|->
我如何告诉 Snakemake 真正并行化作业?
CLUSTER_IDS, = glob_wildcards(os.path.join(WORK_DIR, "fasta", "{id}.fasta"))
rule msa:
input:
expand(os.path.join(WORK_DIR, "msa", "{id}.afa"), id=CLUSTER_IDS)
rule:
input:
os.path.join(WORK_DIR, "fasta", "{id}.fasta")
output:
os.path.join(WORK_DIR, "msa", "{id}.afa")
shell:
"{MUSCLE_PATH}/muscle3.8.31_i86darwin64 -in {input} -out {output}"
你用的是哪个版本的snakemake。我很确定这是因为最近 -j
和 --cores
标志的工作方式发生了变化。
是否每个“作业”运行 在 1 个线程上?
我建议在你的规则中使用 threads:
指令,你可以像这样给规则 1 线程:
rule:
input:
os.path.join(WORK_DIR, "fasta", "{id}.fasta")
output:
os.path.join(WORK_DIR, "msa", "{id}.afa")
threads:
1
shell:
"{MUSCLE_PATH}/muscle3.8.31_i86darwin64 -in {input} -out {output}"
然后你可以运行 snakemake 使用下面的命令:
snakemake --cores 4
现在最多应该 运行 四个 rules/jobs,但是一旦完成就会开始一个新的。
它也可能与 -j
一起使用,但我认为最好将工作和 cores/processes 分开考虑,因为最近这些选项发生变化的动机也是如此。
Snakemake从5.30.1升级到6.5.2版本后问题解决