r - 并行化 foreach 循环内的赋值

标签 r parallel-processing

我一直在尝试运行一个大型并行操作,但让我懊恼的是,我无法在并行化 foreach 中进行分配。环形。也就是说,尝试运行以下代码不会改变 p

p <- numeric(3)
foreach(i=1:3) %dopar% {
  p[i] <- 1
}
p
# [1] 0 0 0

我认为这可能是环境问题(即对 p 的分配是本地的),但更改了 <-<<-只给了我一个错误:Error in { : task 1 failed - "object 'p' not found"
有没有办法让子分配工作或解决这个问题?

在我的真实案例中,p[i] <- 1实际上是一次对许多元素的子赋值,随机(但在循环之前预先确定)放置在向量中,因此利用诸如 .combine = c 之类的东西遗憾的是,这是不可能的。

到目前为止我尝试过的:

我尝试使用 .combine = `+` 解决此问题,像这样:
s <- foreach(i=1:3, .combine = `+`) %dopar% {
  p <- numeric(3)
  p[i] <- 1
  p
}

虽然这适用于我的小型测试用例,但当我将它应用于我的全尺寸用例时,我收到一个错误(在它运行了大约 6 个小时之后,请注意)R 无法分配大小为 6.1 GB 的向量。请注意,这比每个循环要生成的单个数百 MB 向量的大小要大得多,我想这意味着发生了一些隐藏的连接。

我的案件详情

我的问题涉及执行 k 折交叉验证,这意味着每行数据都分配了一个折叠 1K ,并且 foreach 循环在折叠中循环 k = 1:K ,使用 folds != k 拟合数据模型,然后使用该模型预测剩余数据 ( folds == k )。所以,暂时忽略这段代码不起作用,我想做一些类似的事情
folds <- sample(1:K, nrow(mydata), replace = TRUE)
preds <- numeric(nrow(mydata))
foreach(k=1:K) %do% {
  m <- fit_model(...)                    # Pseudocode
  preds[folds == k] <- predict_on_model(...) # Pseudocode
}

因此,我的挑战是以正确的顺序获得 foreach 循环的输出。

最佳答案

许多人在第一次注意到不能使用 foreach 修改并行循环之外的变量时会感到困惑。您可以通过使用执行适当分配的“组合”函数来解决您的问题。例如:

library(doSNOW)
cl <- makeSOCKcluster(4)
registerDoSNOW(cl)
K <- 10
N <- 100
set.seed(4325)
folds <- sample(1:K, N, replace=TRUE)

comb <- function(p, ...) {
  for (r in list(...)) {
    p[folds == r$k] <- r$p
  }
  p
}

preds <-
  foreach(k=1:K, .combine='comb', .init=numeric(N),
          .multicombine=TRUE) %dopar% {
    p <- 100 + k  # replace this
    list(k=k, p=p)  # include data needed by the combine function
  }

foreach 循环执行并行计算,“combine”函数执行分配。注意foreach的使用.init参数来指定 preds 的初始值向量。每次调用 combine 函数时,预测都会在此向量中累积。

另一种解决方案是使用使用 folds 的“最终”函数对结果重新排序。向量:
reorder <- function(p) p[folds]
preds <-
  foreach(k=1:K, .combine='c', .final=reorder) %dopar% {
    100 + k  # replace this
  }

虽然这是一种不太通用的技术,但我怀疑这会更有效。

关于r - 并行化 foreach 循环内的赋值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35592073/

相关文章:

math - 并行任意精度算术库

concurrency - GPar 的数据并行性

c# - AsParallel.ForAll 与 Parallel.ForEach

multithreading - pthreads - 如何并行化一个作业

R:在向量列表中查找共性并删除不常见的部分

r - 如何在R中计算求和

R 中的 R2WinBUGS 错误

r - R中下一整年的上个月年值

R 和 twitteR - userTimeline() 函数不返回请求的推文数量

java - 是否有可用于 Java 的 HashMap 的并行处理实现?有可能吗?