Foreach 循环仅针对第一组工作人员返回错误消息

问题描述

在我一直在处理的包中发生了一些非常奇怪的事情。我正在使用带有 doparallel 后端的 foreach 循环来执行重复的随机游走,并在邻接矩阵上重新启动(下面可重现的示例)。

install.packages("Matrix")
install.packages("foreach")
devtools::install_github("https://github.com/Davisweaver/crosstalkr")
library(foreach)
m <- replicate(1000,sample(x = c(0,1),size = 1000,replace = TRUE))
w <- Matrix::Matrix(m,sparse = TRUE)
w <- Matrix::t(Matrix::t(w)/Matrix::colSums(w)) #normalize based on the column sum.
seeds <- sample(1:nrow(w),size = 32)

每次迭代都应该执行随机游走并重新启动并返回一个亲和力分数的数字向量(因此矩阵输入,一维向量输出)。我试图在每次迭代中用一个更简单的任务重现这个错误,但我无法做到。此设置适用于 matrix::colSums(w) 和一些更琐碎的任务。

对于第一组工作器中的每一个都返回以下错误:“”。每次后续迭代都完全按预期执行,没有错误。因此,当您运行下面的第一个 foreach 循环时,您会得到 the following image.

当您使用相同的并行后端运行后续 foreach 循环时,每次迭代都按预期执行,there are no error messages!

cl <- parallel::makeCluster(4)
doParallel::registerDoParallel(cl)

n = 8
null_dist <-
  foreach::foreach(i = 1:n,.errorhandling = 'pass') %dopar% {
    crosstalkr::sparseRWR(w,seed_proteins = seeds,norm = FALSE)[[1]]
  }

null_dist <-
  foreach::foreach(i = 1:n,norm = FALSE)[[1]]
  }


parallel::stopCluster(cl)

我不知道从哪里开始...我猜这与我如何设置并行后端有关?任何建议将不胜感激。

解决方法

我不确定为什么会发生这种情况。但是,要解决此问题,您需要将 .packages = "Matrix" 显式添加到 foreach

如果不指定 .packagesnrow 不会产生正确的结果。

这是一个简化的例子

library(foreach)

w <- Matrix::Matrix()

您可以看到前四个值错误地为 NULL

cl <- parallel::makeCluster(4)
doParallel::registerDoParallel(cl)

null_dist <- foreach::foreach(i = seq_len(6)) %dopar% {
  nrow(w)
}

parallel::stopCluster(cl)

null_dist
#> [[1]]
#> NULL
#> 
#> [[2]]
#> NULL
#> 
#> [[3]]
#> NULL
#> 
#> [[4]]
#> NULL
#> 
#> [[5]]
#> [1] 1
#> 
#> [[6]]
#> [1] 1

添加 .packages = "Matrix" 解决了这个问题。

cl <- parallel::makeCluster(4)
doParallel::registerDoParallel(cl)

null_dist <- foreach::foreach(i = seq_len(6),.packages = "Matrix") %dopar% {
  nrow(w)
}

parallel::stopCluster(cl)

null_dist
#> [[1]]
#> [1] 1
#> 
#> [[2]]
#> [1] 1
#> 
#> [[3]]
#> [1] 1
#> 
#> [[4]]
#> [1] 1
#> 
#> [[5]]
#> [1] 1
#> 
#> [[6]]
#> [1] 1