我正在尝试构建一个并行的for-each循环,它修改了两个矩阵。我在开始循环之前创建并初始化矩阵。这是一个虚拟程序,演示了我的代码应该如何工作。程序执行时没有错误,但是在foreach循环结束后矩阵仍然为空。注意:这是我的代码的简化版本,而不是实际的代码本身。
#Assume that I've loaded parallel and doParallel and that my computer has 2+ cores
cluster <- makeCluster(detectCores())
registerDoParallel(cluster)
a1 <- array(dim=c(9,9))
a2 <- array(dim=c(9,9))
numbers <- 1:18
foreach (i=1:9, .combine='c') %dopar%{
a1[i,] = numbers[1:9]
a2[i,] = numbers[10:18]
}
stopCluster(cluster)
为什么这个程序不会填充a1和a2的行?
编辑:我在以前的任何帖子中找不到我的问题的答案。 C#和Perl有类似的线程,但没有一个与R. 有关答案 0 :(得分:3)
您不能使用foreach来执行此类副作用。循环中的赋值发生在工作进程中,故意不发送回主服务器。你为它的返回值执行foreach,所以如果你想生成两个矩阵,foreach应该返回一个包含两个矩阵的列表。
这是一个使用combine函数从worker列表中构建多个矩阵的示例:
rcomb <- function(...) {
args <- list(...)
lapply(seq_along(args[[1]]), function(i)
do.call('rbind', lapply(args, function(a) a[[i]])))
}
numbers <- 1:18
m <- foreach (i=1:9, .combine='rcomb', .multicombine=TRUE) %dopar% {
list(numbers[1:9], numbers[10:18])
}
尽管rcomb
有点复杂,但它可以处理任意数量的矩阵,并且可以通过许多任务结果调用,这对于效率原因很重要。
答案 1 :(得分:0)
也许这有帮助。无法测试,请原谅错误。
require(snowfall)
sfInit(cpus=2,parallel=TRUE)
a1 <- matrix(NA,ncol=9,nrow=0)
a2 <- matrix(NA,ncol=9,nrow=0)
numbers <- 1:18
a1 = rbind(a1,sfSapply(1:9,function(x) return(numbers[1:9]), numbers))
a2 = rbind(a2,sfSapply(1:9,function(x) return(numbers[10:18]), numbers))
sfStop()