You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何避免Snakemake因基准文件缺失重复执行规则?

Snakemake:忽略缺失基准文件以避免规则重复执行

我使用Snakemake 8.23.2版本时遇到问题:仅因基准文件缺失,即使主输出文件已存在,规则仍会被重新执行。以下是具体场景、异常表现及解决方案:

场景与Snakefile代码

我的Snakefile定义了一个带动态基准文件的规则:

from datetime import datetime
NOW = datetime.now().strftime("%Y%m%d-%H%M%S")


rule all:
    input:
        "test"

rule test:
    output:
        "test"
    benchmark:
        "benchmark/" + NOW + ".tsv"
    shell:
        """
sleep 3
touch {output}
        """

异常表现

首次运行snakemake test时规则正常执行,但后续运行时,Snakemake会因为基准文件缺失触发规则重新执行:

❯ snakemake test
[...]
[Fri Oct 25 15:22:20 2024]
localrule test:
    output: test
    jobid: 0
    benchmark: benchmark/20241025-152220.tsv
    reason: Missing output files: benchmark/20241025-152220.tsv
    resources: tmpdir=/tmp
[...]

预期行为

只要主输出文件存在,无论基准文件是否存在,Snakemake都应判定规则已完成:

❯ snakemake all
Assuming unrestricted shared filesystem usage.
Building DAG of jobs...
Nothing to be done (all requested files are present and up to date).

已尝试方案

曾使用--rerun-triggers选项,但未解决问题。

解决方案

要让Snakemake忽略缺失的基准文件,推荐以下两种方法:

方法1:标记基准文件为可选(推荐)

在规则的benchmark定义中使用benchmark()函数并添加optional=True参数,标记该基准文件为可选。这样Snakemake会跳过对基准文件的缺失检查,仅在主输出文件需要更新时才执行规则:

rule test:
    output:
        "test"
    benchmark:
        benchmark("benchmark/" + NOW + ".tsv", optional=True)
    shell:
        """
sleep 3
touch {output}
        """

该参数从Snakemake 5.10版本开始支持,8.23.2版本完全兼容。添加后,基准文件存在时会正常生成,缺失时不会触发规则重跑。

方法2:自定义执行逻辑(复杂场景适用)

如果需要更灵活的控制,可以将规则逻辑迁移到run函数中,手动检查主输出文件状态,仅在必要时执行任务并生成基准文件:

import os
import subprocess
from datetime import datetime

NOW = datetime.now().strftime("%Y%m%d-%H%M%S")

rule all:
    input:
        "test"

rule test:
    output:
        "test"
    run:
        if not os.path.exists(output[0]):
            # 执行原任务逻辑
            subprocess.run(f"sleep 3; touch {output[0]}", shell=True)
            # 生成基准文件
            benchmark_path = f"benchmark/{NOW}.tsv"
            with open(benchmark_path, "w") as f:
                # 可写入自定义基准数据,例如运行时间
                f.write("runtime\t3\n")

这种方式需要将shell命令转换为Python代码,适合需要额外逻辑判断的场景。


内容的提问来源于stack exchange,提问作者ManJi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 20:23:16