如何跨多个 slurm 节点并行化 future_pmap()
How to parallelize future_pmap() across multiple slurm nodes
我可以访问具有许多节点的大型计算集群,每个节点都有 >16 个核心,运行ning Slurm 20.11.3。我想 运行 使用 furrr::future_pmap()
并行工作。我可以在单个节点上跨多个内核并行化,但我无法找出正确的语法来利用多个节点上的内核。看到这个 .
这是一个可重现的例子,我做了一个休眠 5 秒的函数,returns 开始时间、结束时间和节点名称。
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 脚本的作业。
脚本 运行s 在大约 20 秒内并且 returns 所有行的主机名相同,表明它在一个节点上同时 运行ning 16 次迭代而不是 64 次迭代按预期同时拆分 4 个节点。我应该如何更改 plan()
语法以便我可以利用多个节点?
编辑:我还尝试了一些其他的东西:
- 我用
multisession
替换了 multicore
,但没有发现输出有任何差异。
- 我用
plan(cluster(workers = availableWorkers())
替换了 plan(list(...))
但它只是挂起。
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。
I replaced ... with plan(cluster(workers = availableWorkers()) ...
是的,
plan(cluster, workers = availableWorkers())
相当于默认,
plan(cluster)
这里是正确的尝试。
... but it just hangs.
这里可能发生了两件事。第一个,就是工人一个一个的设置。所以,如果你有很多,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。
我可以访问具有许多节点的大型计算集群,每个节点都有 >16 个核心,运行ning Slurm 20.11.3。我想 运行 使用 furrr::future_pmap()
并行工作。我可以在单个节点上跨多个内核并行化,但我无法找出正确的语法来利用多个节点上的内核。看到这个
这是一个可重现的例子,我做了一个休眠 5 秒的函数,returns 开始时间、结束时间和节点名称。
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 脚本的作业。
脚本 运行s 在大约 20 秒内并且 returns 所有行的主机名相同,表明它在一个节点上同时 运行ning 16 次迭代而不是 64 次迭代按预期同时拆分 4 个节点。我应该如何更改 plan()
语法以便我可以利用多个节点?
编辑:我还尝试了一些其他的东西:
- 我用
multisession
替换了multicore
,但没有发现输出有任何差异。 - 我用
plan(cluster(workers = availableWorkers())
替换了plan(list(...))
但它只是挂起。
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。
I replaced ... with plan(cluster(workers = availableWorkers()) ...
是的,
plan(cluster, workers = availableWorkers())
相当于默认,
plan(cluster)
这里是正确的尝试。
... but it just hangs.
这里可能发生了两件事。第一个,就是工人一个一个的设置。所以,如果你有很多,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。