Cromwell release-49 新特性解析

Task 级别 Callcaching 开关

我们知道,Callcaching是否启用可以通过如下方式来控制:

  • 配置文件:控制全局的Callcaching 是否开启
# Optional call-caching configuration.
call-caching {
  # Allows re-use of existing results for jobs you've already run
  # (default: false)
  enabled = true

  # Whether to invalidate a cache result forever if we cannot reuse them. Disable this if you expect some cache copies
  # to fail for external reasons which should not invalidate the cache (e.g. auth differences between users):
  # (default: true)
  invalidate-bad-cache-results = true
}

enabled 设置为 true 时,表示 Callcaching 开启,反正 Callcaching 关闭。

  • 提交工作流时的option选项
{
  "read_from_cache": true,
  "write_to_cache": true
}

其中 read_from_cache 表示本次工作流的执行是否从 cache 读取数据,即是否复用之前的运行结果。write_to_cache 表示本次工作流的执行结果是否写入 cache,即本次运行的结果是否给后面的执行复用。

但在有些场景下,我们需要工作流中的某个指定 task 每次都重新运行,即不使用 Callcaching。使用上面的方式是无法支持的。从 Release-49 版本开始,Cromwell 支持对单个 task 设置是否启用 Callcaching(官方文档),下面对这个特性做个介绍。

使用方法

具体来讲,我们可以在 task 定义的 meta 部分使用 volatile 来指定当前 task 是否使用 Callcaching,例如:

version 1.0

task make_random_int {

  meta {
    volatile: true
  }

  command <<<
    echo $RANDOM
  >>>

  output {
    Int random = read_string(stdout())
  }
}

volatile 设置为 true 时,表示当前 task 需要重新执行,不启用 Callcaching。不设置时,默认为false。

其实volatile在计算机编程语言中是个常见的关键字,比如在 C/C++/Java 等语言中都有,只不过各自代表的含义不同。例如在C语言中,volatile 关键字可以用来提醒编译器它后面所定义的变量随时有可能改变,因此编译后的程序每次需要存储或读取这个变量的时候,都会直接从变量地址中读取数据。如果没有 volatile 关键字,则编译器可能优化读取和存储,可能暂时使用寄存器中的值,如果这个变量由别的程序更新了的话,将出现不一致的现象。

在 WDL 中,volatile的含义和C语言有点类似,表示当前的 task,需要每次都重新执行不要使用 Cache 中的记录。

中间文件删除

我们在使用 Cromwell 运行 WDL 的时候可能有这样的经历:一个工作流有若干个 task,每个 task 都会产生一定的输出文件。但是整个 Workflow 的输出是最后一个 Task 的输出,也就是说如果工作流运行结束后,只有最后一个 task 的输出是需要保存的,其他 task 的输出都属于中间文件。例如:

task task1 {
  input {
    File file1
    File file2
  }
  command {
    python do_stuff.py ${file2} ${file2}
  }
  output {
    File results = stdout()
  }
}

task task2 {
  input {
    File foobar
  }
  command {
    python do_stuff2.py ${foobar}
  }
  output {
    File results = stdout()
  }
}

workflow wf {
  input {
    File file1
    File file2
  }

  call task1 {
      input: file1 = file1, file2 = file2
  }
  call task2 {
    input: foobar=task1.results
  }

  output {
      File finals = task2.results
  }
}

在上面的例子中,workflow 最终的输出,只是task2的输出 results 这一个文件。但在 task1 中我们还产生了 task1.results 这样一个中间文件。
如果这些中间文件比较大的话,会占用较多的存储空间,不管是线上存储还是云上存储,都意味着成本。

Release-49 版本开始,Cromwell 支持一个 workflow option,来设置工作流运行结束后是否要将中间文件删除。

使用方法

要使用这个特性,需要配置两个地方:

  • 全局配置中,设置 delete-workflow-files 开关打开
system {
  # Option to allow Cromwell to delete intermediate output files once the workflow succeeds
  delete-workflow-files = true
}
  • 提交工作流时,在 option 中设置 delete_intermediate_output_files 为 true,表示当前工作流需要删除中间文件
{
  "delete_intermediate_output_files": true
}
上一篇:《深入理解C++11:C++ 11新特性解析与应用》——2.11 模板函数的默认模板参数


下一篇:《深入理解C++11:C++ 11新特性解析与应用》——2.10 final/override控制