0

我正在测试这个targets包并且在自定义并行化方面遇到了问题。我的工作流程有两个步骤,我想将第一步并行化超过 4 个工作人员,第二步并行化超过 16 个工作人员。

我想知道我是否可以通过调用来解决问题tar_make_future(),然后在调用中指定每个步骤需要多少工人tar_target。我在下面有一个简单的示例,我希望data使用 1 个工作人员执行该sums步骤,以及使用 3 个工作人员执行该步骤。

library(targets)

tar_dir({
  tar_script({
    library(future)
    library(future.callr)
    library(dplyr)

    plan(callr)

    list(
      # Goal: this step should execute with 1 worker
      tar_target(
        data,
        data.frame(
          x = seq_len(6),
          id = rep(letters[seq_len(3)], each = 2)
        ) %>%
          group_by(id) %>%
          tar_group(),
        iteration = "group"
      ),
      # Goal: this step should execute with 3 workers, in parallel
      tar_target(
        sums,
        sum(data$x),
        pattern = map(data),
        iteration = "vector"
      )
    )
  })
  tar_make_future()
})

我知道一种选择是在每个步骤中单独配置并行后端,然后调用tar_make()以串行执行工作流。我很好奇我是否可以得到这种结果tar_make_future()

4

2 回答 2

1

我建议您致电tar_make_future(workers = <max_parallel_workers>)targets确定要并行运行的工人数量。targets自动确定哪些目标可以并行运行,哪些需要等待上游依赖项完成。在您的情况下,某些data分支可能会先于其他分支完成,在这种情况下sum可以立即开始。换句话说,一些sum分支将在其他sum分支启动之前开始运行,并且您可以信任targets在需要时扩展临时工作人员。https://books.ropensci.org/targets/hpc.html#future上的动画可能有助于可视化这一点。如果您要分别对并行度进行微观管理datasum您可能必须等待所有data在任何sum开始之前完成,这可能需要很长时间。

于 2021-06-02T18:58:22.467 回答
0

一个适用于我的案例的解决方案是调用tar_make_future()两次。在上面的示例中,这将是:

tar_make_future(data, workers = 1)
tar_make_future(workers = 3)

尽管在我的实际工作流程中,它看起来更像:

tar_make_future(data, workers = 4)
tar_make_future(workers = <max_parallel_workers>)

data@landau 提出了一个很好的观点,即在继续执行后续步骤之前,这完全构建了目标。当然,在某些工作流中,干净有效的解决方案是调用tar_make_future(workers = <max_parallel_workers>)并接受生成的运行时。

就我而言,等待data完成不是问题:我的data目标包含许多快速的分支,后续目标的构建速度要慢得多,并且我可以将慢步并行处理比快步更多的工作人员(16 个以上工作人员慢步,而快步只有 4 个)。如果您的情况并非如此,@landau 的建议可能是一个更好的解决方案。

于 2021-06-03T14:50:58.167 回答