R 学习笔记:利用 Snow 包来做并行计算

R 语言本身计算速率相对慢,且 CRAN 提供 的 R 本身对于并行计算的支持相对不如 python 那么方便。为了提高计算速度, 可以利用 snow 包来做 并行计算。在较新的核心 R 包中已经加入了基于 snow 包的 parallel 包,可 以直接使用 parallel 包。Snow 包也是 BiocParallel 等方便进行并行计算的包的基础。Snow 采用类似集群的方法来管理并行计算。

开启和结束集群

创建计算节点:

> cl <- makeCluster(2, type='SOCK')

默认的节点类型是 SOCK,如果机器上支持 MPI,还可以指定节点类型。

> cl <- makeCluster(2, type='MPI')

关闭计算节点:

> stopCluster(r)

在节点计算

snow 提供了方便的,在创建好的节点进行计算的函数。

主要的通用计算命令有如下几个:

clusterSplit(cl, seq)

clusterCall(cl, fun, ...)

clusterApply(cl, x, fun, ...)

clusterApplyLB(cl, x, fun, ...)

clusterEvalQ(cl, expr)

clusterExport(cl, list, envir = .GlobalEnv)

clusterMap(cl, fun, ..., MoreArgs = NULL, RECYCLE = TRUE)

向节点传递环境变量

计算节点中本身是没有主近程中的变量和加载的包的,clusterExport 可以把 环境变量传送到计算节点,clusterEvalQ可以在计算节点运行命令。

> clusterEvalQ(cl, library(ggplot2))

可以实现在计算节点中加载ggplot2包。

> myfunc <- function() {1 + 1}
> clusterExport(cl, 'myfunc')

可以使得节点中也有自定义的myfunc函数。

并行的 split 函数

R 中的 split 函数可以把一个向量分成若干个,clusterSplit 函数可以把 向量在不同的节点上进行平均分配,返回一个长度和节点数量一致的 list。

并行的 call 函数

可以在节点并行 call 函数。首先可以创建一个需要运行的函数:

> myfunc <- function(a) {print(a)}

然后利用 clusterCall 进行计算:

> clusterCall(cl, myfunc, 'myfunc')

clusterCall(cl, fun, ...)cl 为创建的集群,fun 为需要计算的函 数,之后是函数输入的参数。

Apply 函数

clusterApplyclusterApplyLB 都是对一个 list 或者 vector 进行并 行计算,也是下面提到的各种并行的 Apply 函数的基础。clusterApplyLB 相 对于 clusterApply 的区别在于,clusterApplyLB 对于超过节点数的 list 或者 vector 的计算采用了更好的分配方法,会在计算好的节点加入新的计算任 务,LB是load balance的缩写。而 clusterApply 则是按照顺序循环利用节点。

> clusterApply(cl, 1:3, `^`, 2)

snow 提供了在 R 中常用的 lapplysapplyapply 函数的并行计算的 包装,分别为 parLapplyparSapplyparApply,基本参数和lapplysapplyapply都一致。同时,parallel 包还提供了load balance版的 parLapplyLBparSapplyLB。为了方便使用,对于 apply 函数的 MARGIN=1MARGIN=2,snow 包还提供了 parRapply 来对行进行分割并 行计算,parCapply 来对列进行分割并行计算。

parLapply(cl = NULL, X, fun, ..., chunk.size = NULL)

parSapply(cl = NULL, X, FUN, ..., simplify = TRUE,
          USE.NAMES = TRUE, chunk.size = NULL)

parApply(cl = NULL, X, MARGIN, FUN, ..., chunk.size = NULL)

parRapply(cl = NULL, x, FUN, ..., chunk.size = NULL)

parCapply(cl = NULL, x, FUN, ..., chunk.size = NULL)

parLapplyLB(cl = NULL, X, fun, ..., chunk.size = NULL)

parSapplyLB(cl = NULL, X, FUN, ..., simplify = TRUE,
            USE.NAMES = TRUE, chunk.size = NULL)
By @Wolfson Liu in
Tags : #r,