![](/img/trans.png)
[英]How to use the parallel package inside another package, using devtools?
[英]How to initialize workers to use package functions in parallel
我正在开发一个 R package 并尝试在其中使用并行处理来解决一个令人尴尬的并行问题。 我想编写一个循环或函数,使用我的 package 中的其他函数。我在 Windows 工作,我尝试使用parallel::parLapply
和foreach::%dopar%
,但无法让工作人员(核心)到访问我的 package 中的函数。这是一个带有两个函数的简单 package 的示例,其中第二个使用%dopar%
在并行循环中调用第一个:
add10 <- function(x) x + 10
slowadd <- function(m) {
cl <- parallel::makeCluster(parallel::detectCores() - 1)
doParallel::registerDoParallel(cl)
`%dopar%` <- foreach::`%dopar%` # so %dopar% doesn't need to be attached
foreach::foreach(i = 1:m) %dopar% {
Sys.sleep(1)
add10(i)
}
stopCluster(cl)
}
当我使用devtools::load_all()
加载 package 并调用slowadd
function 时, Error in {: task 1 failed - "could not find function "add10""
被返回。
我还尝试使用我的 package 显式初始化工作人员:
add10 <- function(x) x + 10
slowadd <- function(m) {
cl <- parallel::makeCluster(parallel::detectCores() - 1)
doParallel::registerDoParallel(cl)
`%dopar%` <- foreach::`%dopar%` # so %dopar% doesn't need to be attached
foreach::foreach(i = 1:m, .packages = 'mypackage') %dopar% {
Sys.sleep(1)
add10(i)
}
stopCluster(cl)
}
但我收到错误Error in e$fun(obj, substitute(ex), parent.frame(), e$data): worker initialization failed: there is no package called 'mypackage'
。
如何让工作人员访问我的 package 中的功能? 使用foreach
的解决方案会很棒,但我对使用parLapply
或其他函数/包的解决方案完全开放。
感谢人们的有用评论,我能够用我的包的功能初始化工作人员。 通过确保所需的所有 package 函数都在 NAMESPACE 中导出并使用devtools::install()
安装我的 package, foreach
能够找到 package 进行初始化。 该示例的 R 脚本如下所示:
#' @export
add10 <- function(x) x + 10
#' @export
slowadd <- function(m) {
cl <- parallel::makeCluster(parallel::detectCores() - 1)
doParallel::registerDoParallel(cl)
`%dopar%` <- foreach::`%dopar%` # so %dopar% doesn't need to be attached
out <- foreach::foreach(i = 1:m, .packages = 'mypackage') %dopar% {
Sys.sleep(1)
add10(i)
}
stopCluster(cl)
return(out)
}
这是有效的,但它不是一个理想的解决方案。 首先,它使工作流程慢得多。 每次我对 package 进行更改并想测试它(在合并并行性之前)时,我都在使用devtools::load_all()
),但现在我每次都必须重新安装 package,当 package 很大时,这很慢。 其次,需要导出并行循环中需要的每个 function,以便foreach
可以找到它。 我的实际用例有很多我宁愿保留在内部的小实用程序功能。
您可以在 foreach 循环内使用devtools::load_all()
或使用source
加载您需要的函数。
out <- foreach::foreach(i = 1:m ) %dopar% {
Sys.sleep(1)
source("R/some_functions.R")
load("R/sysdata.rda")
add10(i)
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.