【问题标题】:How to parallelize future_pmap() across multiple slurm nodes如何跨多个 slurm 节点并行化 future_pmap()
【发布时间】:2022-02-04 08:40:27
【问题描述】:

我可以访问一个包含许多节点的大型计算集群,每个节点都有 >16 个内核,运行 Slurm 20.11.3。我想使用furrr::future_pmap() 并行运行作业。我可以在单个节点上跨多个内核并行化,但我无法找出正确的语法来利用多个节点上的内核。看到这个related question

这是一个可重现的示例,我创建了一个休眠 5 秒并返回开始时间、结束时间和节点名称的函数。

library(furrr)

# Set up parallel processing 
options(mc.cores = 64)
plan(
    list(tweak(multicore, workers = 16),
         tweak(multicore, workers = 16),
         tweak(multicore, workers = 16),
         tweak(multicore, workers = 16))
)


fake_fn <- function(x) {
  t1 <- Sys.time()
  Sys.sleep(x)
  t2 <- Sys.time()
  hn <- system2('hostname', stdout = TRUE)
  data.frame(start=t1, end=t2, hostname=hn)
}

stuff <- data.frame(x = rep(5, 64))

output <- future_pmap_dfr(stuff, function(x) fake_fn(x))

我使用salloc --nodes=4 --ntasks=64 运行该作业并以交互方式运行上述 R 脚本。

脚本在大约 20 秒内运行,并为所有行返回相同的主机名,表明它在一个节点上同时运行 16 次迭代,但不是按预期在 4 个节点上同时运行 64 次迭代。我应该如何更改plan() 语法以便我可以利用多个节点?

edit:我还尝试了其他一些方法:

  • 我将multicore 替换为multisession,但没有发现输出有任何差异。
  • 我将plan(list(...)) 替换为plan(cluster(workers = availableWorkers()),但它只是挂起。

【问题讨论】:

    标签: r slurm r-future furrr


    【解决方案1】:
    options(mc.cores = 64)
    plan(
        list(tweak(multicore, workers = 16),
             tweak(multicore, workers = 16),
             tweak(multicore, workers = 16),
             tweak(multicore, workers = 16))
    )
    

    对不起,这不起作用。当您指定这样的未来策略列表时,您正在指定应该在 nested 未来调用中使用什么。在您的 future_pmap_dfr() 示例中,它只会使用此列表中的第一级。其他三个级别从不使用。详情请见https://future.futureverse.org/articles/future-3-topologies.html


    我将 ... 替换为 plan(clu​​ster(workers = availableWorkers()) ...

    是的,

    plan(cluster, workers = availableWorkers())
    

    相当于默认的,

    plan(cluster)
    

    这里是正确的尝试。

    ...但它只是挂起。

    这里可能发生了两件事。第一个,工人是一个一个设置的。所以,如果你有很多,plan() 需要很长时间才能完成。我建议您只尝试两个工人来确认它是否有效。您还可以打开调试输出以查看发生了什么,即

    library(future)
    options(parallelly.debug = TRUE)
    plan(cluster)
    

    其次,跨节点使用 PSOCK 集群需要您对这些并行工作人员具有 SSH 访问权限。并非所有 HPC 环境都支持这一点,例如他们可能会阻止用户通过 SSH:ing 进入计算节点。这也可能是您正在经历的。如上所述,打开调试以找出它停止的位置。

    现在,即使您设法让这项工作正常进行,您也会面临 R 中的限制,即您最多只能拥有 125 个并行工作程序,但通常会少一些。您可以在https://github.com/HenrikBengtsson/Wishlist-for-R/issues/28 中阅读有关此限制的更多信息。它还表明,可以调整 R 源代码并重新编译以将此限制增加到数千。


    上述方法的替代方法是使用 future.batchtools;

    plan(future.batchtools::batchtools_slurm, workers = availableCores())
    

    这将导致future_pmap_dfr() 中的任务将通过n = availableCores() Slurm 作业解决。当然,这会带来调度程序的额外开销,例如排队、启动、运行、完成和读回数据。

    顺便说一句,讨论这些事情的最佳地点是https://github.com/HenrikBengtsson/future/discussions

    【讨论】:

    • 仅供参考,我还没有时间完全通过您的答案并测试所有内容。一旦我有机会这样做,我希望接受答案!
    • 到目前为止,我已经运行了带有调试输出的plan(cluster)。在成功设置一名工人后,它似乎确实挂在工人 2 上。我想尝试您建议的替代方案,但我不清楚如何在 HPC 集群上使用 future.batchtools::batchtools_slurm。它不能从现有的 Slurm 作业中运行,对吗?
    猜你喜欢
    • 2019-07-21
    • 2015-09-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多