1

我正在尝试构建一个并行的 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 相关。

4

2 回答 2

4

您不能使用 foreach 来执行这种副作用。循环中的分配发生在工作进程中,并且故意不发送回主进程。您对其返回值执行 foreach,因此如果要生成两个矩阵,foreach 应该返回两个矩阵的列表。

这是一个使用 combine 函数从工作人员生成的行列表中构造多个矩阵的示例:

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有点复杂,但它可以处理任意数量的矩阵,并且可以调用许多任务结果,这对于效率来说很重要。

于 2013-03-12T19:03:04.923 回答
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()
于 2013-02-15T21:03:35.413 回答