R doParallel 进度条来监控完成的工作

Fed*_*rgi 6 parallel-processing r

我正在尝试编写一个具有多线程功能的 CRAN 包。我使用 实现了一个完美的解决方案doSNOW,但该软件包已被 CRAN 团队标记为“已取代”,他们要求我切换到一个doParallel解决方案。这很好,但是我找不到一种方法来监视已完成的作业数量,doParallel就像我使用doSNOW. 这是我的doSNOW解决方案:

# Set up parameters
nthreads<-2
nreps<-100
funrep<-function(i){
    Sys.sleep(0.1)
    res<-c(log2(i),log10(i))
    return(res)
}
# doSNOW solution
library(doSNOW)
cl<-makeCluster(nthreads)
registerDoSNOW(cl)
pb<-txtProgressBar(0,nreps,style=3)
progress<-function(n){
    setTxtProgressBar(pb,n)
}
opts<-list(progress=progress)
i<-0
output<-foreach(i=icount(nreps),.combine=c,.options.snow=opts) %dopar% {
    s<-funrep(i)
    return(s)
}
close(pb)
stopCluster(cl)
Run Code Online (Sandbox Code Playgroud)

这是之前 Stack Overflow 帖子中建议的 doParallel 解决方案。但是,如您所见,它不会在作业完成时打印进度,它只会在最后合并结果时打印。

# doParallel solution
library(doParallel)
progcombine<-function(){
  count<-0
  function(...) {
    count<<-count+length(list(...))
    setTxtProgressBar(pb,count)
    utils::flush.console()
    c(...)
  }
}
cl <- makeCluster(nthreads)
registerDoParallel(cl)
output<-foreach(i = icount(nreps),.combine=progcombine()) %dopar% {
    funrep(i)
}
stopCluster(cl)
Run Code Online (Sandbox Code Playgroud)

您能否建议我使用doParallel或至少不使用被取代的来监视作业状态完成的解决方案doSNOW?可能带有进度条,也可能带有多操作系统功能。非常感谢!

Hen*_*ikB 7

(免责声明:我是 Progressr 包和未来框架的作者)

当使用doFuture作为foreach的并行后端时, progressr包可以实现这一点:

library(progressr) ## use progressr for procession updates
library(doFuture)  ## attaches also foreach and future
registerDoFuture() ## tell foreach to use futures
plan(multisession) ## parallelize over a local PSOCK cluster

xs <- 1:5

with_progress({
  p <- progressor(along = xs) ## create a 5-step progressor
  y <- foreach(x = xs) %dopar% {
    p()                       ## signal a progression update
    Sys.sleep(6.0-x)
    sqrt(x)
  }
})
Run Code Online (Sandbox Code Playgroud)

默认设置用于utils::txtProgressBar()进展报告,但您可以更改此设置。progress::progress_bar()例如,以下内容将通过和报告进度更新beepr::beep():

library(progressr) ## use progressr for procession updates
library(doFuture)  ## attaches also foreach and future
registerDoFuture() ## tell foreach to use futures
plan(multisession) ## parallelize over a local PSOCK cluster

xs <- 1:5

with_progress({
  p <- progressor(along = xs) ## create a 5-step progressor
  y <- foreach(x = xs) %dopar% {
    p()                       ## signal a progression update
    Sys.sleep(6.0-x)
    sqrt(x)
  }
})
Run Code Online (Sandbox Code Playgroud)

您还可以为每个进度更新添加消息,例如

progressr::handlers("progress", "beepr")
Run Code Online (Sandbox Code Playgroud)

FYI,是基本上whereplan(multisession, workers = 2)的缩写。plan(cluster, workers = cl)clcl <- parallel::makeCluster(2L)

附言。Progressr 包的目标是为进度更新提供最小的、可持续的、可扩展的和统一的 API。这对于使用的迭代器框架是不变的。

聚苯硫醚。Progressr API 正在开发中;它可能需要一段时间才能识别出真实的自我。


小智 4

我找不到 doParallel 的解决方案(我认为它不支持作业完成的进度条),但也许您可以尝试新的包pbapply:

# pbapply solution
library(pbapply)
cl<-parallel::makeCluster(nthreads)
invisible(parallel::clusterExport(cl=cl,varlist=c("nreps")))
invisible(parallel::clusterEvalQ(cl=cl,library(utils)))
result<-pblapply(cl=cl,
                 X=1:nreps,
                 FUN=funrep)
parallel::stopCluster(cl)
Run Code Online (Sandbox Code Playgroud)