![](/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.