【问题标题】:How to parallelise an algorithm that includes a sparse matrix, in R如何在 R 中并行化包含稀疏矩阵的算法
【发布时间】:2014-06-13 13:46:41
【问题描述】:

我一直在使用 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)

这会产生以下错误消息:

Error in { : task 1 failed - "object of type 'S4' is not subsettable" 

如果“mat”属于“matrix”类而不是“dgCMatrix”类,则此函数有效,因此问题似乎是由于稀疏矩阵的子集所致。我有什么办法可以解决这个问题吗?矩阵 'mat' 可以非常大并且可以包含许多零,所以我想继续使用稀疏矩阵。

【问题讨论】:

    标签: r parallel-processing sparse-matrix


    【解决方案1】:

    根本问题是工作人员没有加载 Matrix 包,所以他们不知道如何对 Matrix 对象“mat”进行子集化。你可以使用 foreach .packages 选项来解决这个问题:

    temp_vec = foreach(i=iter(df, by='row'), .packages='Matrix', .combine=rbind) %dopar% {
      # snip
    }
    

    请注意,您的示例在所有平台上均失败,但如果您要注册 doParallel:

    registerDoParallel(4)
    

    那么你的 foreach 循环可以在 Linux 和 Mac OS X 上运行,但在 Windows 上失败了!原因是在 Linux 和 Mac OS X 上会使用 mclapply 函数,但在 Windows 上会隐式创建集群对象,然后会使用 clusterApplyLB 函数。工人是由 mclapply 派生的,因此它们继承了父级的环境,包括加载的包,因此 foreach 循环可以工作。但是在使用 makePSOCKcluster 时,工作人员不会继承环境,因此您必须使用 .packages 选项之类的东西来初始化工作人员的环境,否则 foreach 循环将失败。具有讽刺意味的是,由于 doParallel 包隐藏了这种差异以使事情变得更容易,它为 Windows 用户设置了一个小小的可移植性陷阱。

    还有其他方法可以改进此示例(如 @agstudy 所述),但正如我所说,根本问题是 Matrix 包没有加载到工作程序上。

    【讨论】:

    • 添加 .packages=Matrix 命令适用于问题中的玩具代码,以及更复杂的功能(问题中未说明)。另外,感谢您提供背景信息。
    【解决方案2】:

    您不能迭代 S4 对象。没有为 Matrix 对象定义 iter 方法。

    • 无需使用df data.frame。您只需要遍历列
    • 在子集之前将迭代器强制为整数。

    例如,您可以用 2 行替换您的函数:

    foreach(i = seq_len(ncol(test_mat)), .combine=rbind) 
    %dopar% sum(test_mat[,as.integer(i)]==1,na.rm=TRUE)+1
    
          [,1]
    result.1    1
    result.2    5
    result.3    1
    result.4    3
    result.5    1
    result.6    2
    result.7    2
    

    【讨论】:

      猜你喜欢
      • 2018-05-11
      • 2013-05-24
      • 1970-01-01
      • 1970-01-01
      • 2020-04-20
      • 1970-01-01
      • 1970-01-01
      • 2017-10-03
      • 1970-01-01
      相关资源
      最近更新 更多