【问题标题】:Snakemake: use checksums instead of timestamps?Snakemake:使用校验和而不是时间戳?
【发布时间】:2021-01-26 18:36:55
【问题描述】:

我的项目可能存在输入数据集被覆盖但内容未更改的情况。 Snakemake 中有没有一种方法可以使用校验和而不是时间戳来检查构建更改?

例如,Scons 使用 md5 哈希检查代码和数据中的构建更改(哈希仅在时间戳发生更改时计算)。但我更喜欢使用 Snakemake,因为它还有其他杀手级功能。

所需的行为类似于文档中描述的between workflow caching 功能。在文档中它说:

无需使用此功能来避免工作流中的冗余计算。 Snakemake 开箱即用。

但所有对这个问题的引用都指向 Snakemake 仅在正常工作流程中使用时间戳。

使用ancient 标记或使用touch 来调整时间戳对我来说不起作用,因为这需要太多的人工干预。

我最终发现 an old SO post 表明我可以通过编写自己的脚本来比较校验和然后将其输入到 Snakemake 中来做到这一点,但我不确定这是否仍然是唯一的选择。

【问题讨论】:

    标签: snakemake


    【解决方案1】:

    我不知道snakemake 中有内置解决方案。也许这就是我的做法。

    假设您的输入数据是data.txt。这是可能在不更改的情况下被覆盖的文件。不是直接在snakemake rules 中使用这个文件,而是使用一个缓存副本,仅当md5 在原始和缓存之间发生变化时才被覆盖。检查可以在rule all之前使用标准python代码完成。

    这是一个伪代码示例:

    input_md5 = get_md5('data.txt')
    cache_md5 = get_md5('cache/data.txt')
    
    if input_md5 != cache_md5:
        # This will trigger the pipeline because cache/data.txt is newer than output
        copy('data.txt', 'cache/data.txt') 
    
    rule all:
        input:
            'stuff.txt'
    
    rule one:
        input:
            'cache/data.txt',
        output:
            'stuff.txt',
    

    编辑:此伪代码保存缓存输入文件的 md5,因此无需每次都重新计算。它还将输入数据的时间戳保存到文件中,以便仅当此类时间戳比缓存的时间戳更新时才重新计算输入的 md5:

    for each input datafile do:
    
    current_input_timestamp = get_timestamp('data.txt')
    cache_input_timestamp = read('data.timestamp.txt')
    
    if current_input_timestamp > cache_input_timestamp:
        input_md5 = get_md5('data.txt')
        cache_md5 = read('cache/data.md5')
    
        if input_md5 != cache_md5:
            copy('data.txt', 'cache/data.txt') 
            write(input_md5, 'cache/data.md5')
            write(current_input_timestamp, 'data.timestamp.txt')
    
    # If any input datafile is newer than the cache, the pipeline will be triggered
    

    但是,这增加了管道的复杂性,所以我会检查它是否值得。

    【讨论】:

    • 感谢您的回复,这是个好主意。不过,我更喜欢不同的解决方案,因为我有很多数据文件,其中一些非常大 - 这可能会增加相当多的时间和磁盘使用量。
    • @tlddl 如果对节省时间有用,请参阅对我的回答的编辑。您可以创建符号链接,而不是复制文件,但我不确定在这种情况下,snakemake 将如何处理它们。或者您可以只 touch 输入来更新其时间戳而不复制它。
    • 谢谢,接受你的回答,因为这似乎在 Snakemake 中不可用。在比较校验和后,我将尝试创建一个使用touch 更新时间戳的方法。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-07-21
    • 1970-01-01
    • 2015-11-29
    • 1970-01-01
    • 1970-01-01
    • 2021-07-22
    • 2013-06-18
    相关资源
    最近更新 更多