代码之家  ›  专栏  ›  技术社区  ›  January

如何在r中并行化包的函数

  •  3
  • January  · 技术社区  · 6 年前

    我想将正在处理的包的一部分并行化。应该使用哪些包和哪些语法使包在不同的体系结构上灵活和可用?我的问题在于 sapply() 调用如下模拟代码所示:

    .heavyStuff <- function(x) { 
       # do a lot of work
       Sys.sleep(1)
    }
    
    listOfX <- 1:20
    
    userFunc1 <- function(listOfX) {    
      res <- sapply(listOfX, .heavyStuff)
      return(res)
    }
    

    根据不同的指南,我炮制了如下:

    userFunc2 <- function(listOfX, dopar.arg=2) {
      if(requireNamespace("doParallel")) {
        doParallel::registerDoParallel(dopar.arg)
        res <- foreach(i=1:length(listOfX)) %dopar% {
           .heavyStuff(listOfX[[i]])
        }
        names(res) <- names(listOfX)
      } else {
        res <- sapply(listOfX, .heavyStuff)
      }
      return(res)
    }
    

    问题:

    1. 我能在包中安全地使用这样的代码吗?它能在一系列平台上正常工作吗?
    2. 有没有办法避免 foreach() 构建?我更喜欢用一个像花哨的或是重叠的函数。然而,并行库中的结构似乎更为特定于平台。
    3. 如果 dopar.arg==NULL ,尽管 the introduction to doParallel says that 没有任何争论“你将得到三个工人和类unix系统 您将获得相当于系统核心数一半的工作线程数。”
    1 回复  |  直到 6 年前
        1
  •  1
  •   HenrikB    6 年前

    作为 future 框架,我建议你看看 future.apply 包装,例如

    library(future.apply)
    userFunc2 <- function(listOfX) {    
      res <- future_sapply(listOfX, .heavyStuff)
      return(res)
    }
    

    默认情况是事情按顺序运行,但是如果 用户 希望,他们可以使用任何他们想要的并行未来后端,例如。

    library(future)
    plan(multiprocess)    # parallel on local machine - all cores by default
    
    library(future.batchtools)
    plan(batchtools_sge)  # parallel on an SGE compute cluster
    
    library(future)
    plan(sequential)      # sequentially
    

    设计模式是由您决定 什么 并行化,而用户 怎样 并行化。