在foreach包的mannual中,高效并行的例子:
将行分块后,发送到各个workers:
applyKernel <- function(newX, FUN, d2, d.call, dn.call = NULL, ...) {
foreach(x = iblkcol(newX, 3), .combine = "c", .packages = "foreach")%dopar% {
foreach(i = 1:ncol(x)) %do% FUN(array(x[, i], d.call, dn.call), ...)
}
}
applyKernel(matrix(1:16, 4), mean, 4, 4)
会报错:Error in eval(expr, envir, enclos) : could not find function "iblkcol"
解决方法一:将以下iblkcol函数加入foreach/iterators包的source中
iblkcol <- function(a, chunks) {
n <- ncol(a)
i <- 1
nextElem <- function() {
if (chunks <= 0 || n <= 0) stop('StopIteration')
m <- ceiling(n / chunks)
r <- seq(i, length=m)
i <<- i + m
n <<- n - m
chunks <<- chunks - 1
a[,r, drop=FALSE]
}
structure(list(nextElem=nextElem), class=c('iblkcol', 'iter'))
}
nextElem.iblkcol <- function(obj) obj$nextElem()
解决方法二:改用通用的iter函数参数iterator
applyKernel <- function(newX, FUN, d2, d.call, dn.call = NULL, ...) {
foreach(x = iter(newX,chunks=3), .combine = "c", .packages = "foreach")%dopar% {
foreach(i = 1:ncol(x)) %do% FUN(array(x[, i], d.call, dn.call), ...)
}
}
applyKernel(matrix(1:16, 4), mean, 4, 4)