【问题标题】:R parallel computation with foreach for multiple output by different operationR并行计算与foreach通过不同的操作进行多个输出
【发布时间】:2019-08-06 03:11:11
【问题描述】:

我想使用foreach 来提高计算速度。我想要做的是从单个 foreach 循环中输出两个结果。

以下是原想法的简化版:

output <- list(matrix_addition = matrix(0, nrow = 2, ncol = 2), process_list = list())

for(i in c(1:10)){
  # value_1 indicates some calculation to get the matrix
  value_1 <- i * 2

  # value_2 indicates some calculation to process_list for each i
  value_2 <- i / 2

  output$matrix_addition <- output$matrix_addition + matrix(value_1, nrow = 2, ncol = 2)
  output$process_list <- append(output$process_list, value_2)
}

预期的output 将是:

$matrix_addition
     [,1] [,2]
[1,]  110  110
[2,]  110  110

$process_list
$process_list[[1]]
[1] 0.5

$process_list[[2]]
[1] 1

...

$process_list[[10]]
[1] 5

我尝试将foreach.combine = "+" 一起用于矩阵加法部分,但是当涉及到多个输出时,mapply 似乎无法与"+" 结合使用。我使用.combine = "cbind", .multicombine=TRUE 在网上找到了几个对两个输出具有相同操作的代码。当涉及到两个输出的不同操作时,有什么办法吗?

感谢您的帮助!

编辑:

我的foreach 代码仅用于矩阵加法

library(foreach)
library(doParallel)

cl <- makeCluster(2)
registerDoParallel(cl)

output <- foreach(i = 1:10, .combine = "+") %dopar% {
  value_1 <- i * 2
  matrix <- matrix(value_1, nrow = 2, ncol = 2)
}

stopCluster(cl)

我对这两个输出的第一次尝试是

output <- foreach(i = 1:10) %dopar% {
  if(exists("temp") == FALSE) {
    output <- list(matrix_addition = matrix(0, nrow = 2, ncol = 2), process_list = list())
  }

  value_1 <- i * 2
  value_2 <- i / 2

  output$matrix_addition <- output$matrix_addition + matrix(value_1, nrow = 2, ncol = 2)
  output$process_list <- append(output$process_list, value_2)
  output
}

原来for的循环思路好像不能直接用在foreach中。

接下来,我在网上找到了这些代码,看起来是这样的:

comb <- function(...) {
  mapply("cbind", ..., SIMPLIFY=FALSE)
}

output <- foreach(i = 1:10, .combine="comb", .multicombine = TRUE) %dopar% {
  value_1 <- i * 2
  value_2 <- i / 2

  matrix_addition_part  <- matrix(value_1, nrow = 2, ncol = 2)
  process_list_part     <- value_2
  list(matrix_addition_part, process_list_part)
}

comb <- function(x, ...) {
  lapply(seq_along(x),
         function(i){c(x[[i]], lapply(list(...), function(y) y[[i]]))})
}

output <- foreach(i=1:10, .combine="comb", .multicombine=TRUE, .init=list(list(), list())) %dopar% {
  value_1 <- i * 2
  value_2 <- i / 2

  list(matrix(value_1, nrow = 2, ncol = 2), value_2)
}

这两个是类似的,这里的思路是将所有矩阵保存在矩阵加法部分,foreach之后,矩阵就可以相加了。但是对我来说问题是我的代码中的每个矩阵都太大了,需要很大的空间来存储,因此我无法保存所有矩阵。我想我需要将矩阵加法部分中的"cbind" 替换为"+" 之类的东西,但它在mapply 中不起作用。

我的猜测是我需要让函数comp 同时包含"+""append",但仍然无法通过使用apply 提出适当的解决方案。

【问题讨论】:

  • 你能出示foreach的代码
  • 我在上面添加了几个foreach我的尝试。
  • 请在 SO 中查找“[r] foreach multiple”。这已经回答了好几次了。您基本上有两种解决方案:要么制作自定义 .combine 函数,要么只输出一个列表并在之后组合结果。
  • 感谢您的帮助,请弄清楚如何去做。

标签: r foreach parallel-processing


【解决方案1】:

只要弄清楚怎么做:

library(foreach)
library(doParallel)
cl <- makeCluster(2)
registerDoParallel(cl)

comb <- function(List1, List2) {
  output_a <- apply(abind(List1[[1]], List2[[1]], along = 3), 1:2, sum)
  output_b <- c(List1[[2]], List2[[2]])
  return(list(matrix_addition = output_a, process_list = output_b))
}

output <- foreach(i = 1:10, .combine = "comb", .init=list(matrix(0, 2, 2), list())) %dopar% {
  value_1 <- i * 2
  value_2 <- i / 2

  list(matrix_addition = matrix(value_1, nrow = 2, ncol = 2), process_list = value_2)
}

stopCluster(cl)

这里通过自定义.combine函数comb,将矩阵加法部分和进程列表部分分开,合并成一个列表。此外,comp 函数的第一个输入(此处为 List1)将是 .init 或先前的循环迭代(i-1)结果,第二个输入(此处为List2)将是当前循环迭代(i ) 结果。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-03-18
    • 2012-06-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-15
    • 1970-01-01
    • 2013-01-16
    相关资源
    最近更新 更多