gpt4 book ai didi

r - 使我的 R 包中的函数可并行化的最佳实践是什么?

转载 作者:行者123 更新时间:2023-12-04 17:31:41 28 4
gpt4 key购买 nike

我开发了一个 R 包,其中包含 embarassingly parallel职能。

我想以对用户透明的方式为这些功能实现并行化,而不管他/她的操作系统如何(至少在理想情况下)。

我环顾四周,看看其他包作者是如何导入的 foreach-based Parallelism .例如,Max Kuhn 的 caret包进口foreach使用 %dopar%但是 relies在用户上指定并行后端。 (几个示例使用 doMC ,这在 Windows 上不起作用。)

注意到 doParallel适用于 Windows 和 Linux/OSX 并使用内置 parallel包(有关有用的讨论,请参阅评论 here),导入 doParallel 有意义吗?并让我的函数调用 registerDoParallel()每当用户指定 parallel=TRUE作为论据?

最佳答案

我认为允许用户注册自己的并行后端非常重要。 doParallel后端非常便携,但是如果他们想在集群的多个节点上运行您的功能怎么办?如果他们想设置makeCluster怎么办? “输出文件”选项?不幸的是,如果使并行支持透明也会使其对您的许多用户毫无用处。

我建议你使用 getDoParRegistered函数来查看用户是否已经注册了一个并行后端,如果他们还没有注册,则只为他们注册一个。

下面是一个例子:

library(doParallel)
parfun <- function(n=10, parallel=FALSE,
cores=getOption('mc.cores', 2L)) {
if (parallel) {
# honor registration made by user, and only create and register
# our own cluster object once
if (! getDoParRegistered()) {
cl <- makePSOCKcluster(cores)
registerDoParallel(cl)
message('Registered doParallel with ',
cores, ' workers')
} else {
message('Using ', getDoParName(), ' with ',
getDoParWorkers(), ' workers')
}
`%d%` <- `%dopar%`
} else {
message('Executing parfun sequentially')
`%d%` <- `%do%`
}

foreach(i=seq_len(n), .combine='c') %d% {
Sys.sleep(1)
i
}
}

这样做是为了它仅在 parallel=TRUE 时并行运行,即使他们注册了并行后端:
> parfun()
Executing parfun sequentially
[1] 1 2 3 4 5 6 7 8 9 10

parallel=TRUE并且他们还没有注册后端,那么它会为他们创建和注册一个集群对象:
> parfun(parallel=TRUE, cores=3)
Registered doParallel with 3 workers
[1] 1 2 3 4 5 6 7 8 9 10

parfunparallel=TRUE 调用再次,它将使用之前注册的集群:
> parfun(parallel=TRUE)
Using doParallelSNOW with 3 workers
[1] 1 2 3 4 5 6 7 8 9 10

这可以通过多种方式进行改进:这只是一个简单的演示。但至少它提供了一种便利,而不会阻止用户使用他们环境中可能需要的自定义选项注册不同的后端。

请注意,选择默认数量的内核/ worker 也是一个棘手的问题,也是 CRAN 维护人员关心的问题。这就是为什么我没有设置默认内核数 detectCores() .相反,我使用了 mclapply 使用的方法,虽然也许应该使用不同的选项名称。

关于 stopCluster
请注意,此示例有时会创建一个新的集群对象,但它永远不会通过调用 stopCluster 来停止它。 .原因是创建集群对象可能很昂贵,所以我喜欢在多个 foreach 循环中重用它们,而不是每次都创建和销毁它们。我宁愿把它留给用户,但是,在这个例子中,用户没有办法做到这一点,因为他们无权访问 cl多变的。

有以下三种处理方法:
  • 调用 stopClusterparfun每当 makePSOCKcluster叫做;
  • 编写一个额外的函数,允许用户停止隐式创建的集群对象(相当于 stopImplicitCluster 包中的 doParallel 函数);
  • 不要担心隐式创建的集群对象。

  • 我可能会为我自己的代码选择第二个选项,但这会使这个例子变得非常复杂。已经比较复杂了。

    关于r - 使我的 R 包中的函数可并行化的最佳实践是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42374125/

    28 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com