joe*_*237 6 parallel-processing r sparse-matrix
我一直在使用R中的库'doParallel'来提高一组函数的速度.但是,我遇到了一个我无法解决的错误.我相信以下代码隔离了问题的精髓:
library(Matrix)
library(doParallel)
test_mat = Matrix(c(0,1,2,NA,0,0,2,NA,1,NA,1,2,2,NA,0,1,0,2,2,2,0,0,NA,NA,1,2,1,1,2,1,rep(NA,5)), ncol=7, byrow=TRUE, sparse=TRUE)
par_func <- function(mat, ncores)
{
cl <- makePSOCKcluster(ncores)
clusterSetRNGStream(cl)
registerDoParallel(cl, cores = ncores)
df = data.frame(1:7, NA)
temp_vec = foreach(i=iter(df, by='row'), .combine=rbind) %dopar%
{
i[,2] <- sum(mat[,i[,1]] == 1, na.rm = TRUE) + 1
}
stopCluster(cl)
return(temp_vec)
}
par_func(mat=test_mat, ncores=5)
Run Code Online (Sandbox Code Playgroud)
这会产生以下错误消息:
Error in { : task 1 failed - "object of type 'S4' is not subsettable"
Run Code Online (Sandbox Code Playgroud)
如果'mat'是'matrix'类而不是'dgCMatrix',则此函数有效,因此问题似乎是由于稀疏矩阵的子集化.我有什么选择可以解决这个问题吗?矩阵"mat"可以非常大并且可以包含许多零,因此我想继续使用稀疏矩阵.
根本问题是工作人员没有加载Matrix包,因此他们不知道如何将Matrix对象"mat"子集化.您可以使用foreach .packages选项解决此问题:
temp_vec = foreach(i=iter(df, by='row'), .packages='Matrix', .combine=rbind) %dopar% {
# snip
}
Run Code Online (Sandbox Code Playgroud)
请注意,您的示例在所有平台上都失败,但是如果您要使用以下命令注册doParallel:
registerDoParallel(4)
Run Code Online (Sandbox Code Playgroud)
那么你的foreach循环可以在Linux和Mac OS X上运行,但在Windows上失败了!原因是在Linux和Mac OS X上,将使用mclapply函数,但在Windows上,将隐式创建一个集群对象,然后将使用clusterApplyLB函数.工作人员由mclapply分叉,因此他们继承了父项的环境,包括加载的包,因此foreach循环起作用.但是当使用makePSOCKcluster时,工作者不会继承环境,因此您必须使用.packages选项之类的东西来初始化工作者的环境,否则foreach循环将失败.具有讽刺意味的是,由于doParallel软件包隐藏了这种差异以使事情变得更容易,因此它为Windows用户设置了一个小的可移植性陷阱.
还有其他方法可以改进这个例子(正如@agstudy所提到的),但正如我所说,基本问题是Matrix包没有加载到worker上.
| 归档时间: |
|
| 查看次数: |
824 次 |
| 最近记录: |