如何在没有评估环境的情况下集群导出函数

时间:2013-07-01 10:18:21

标签: r parallel-processing environment-variables

我正在尝试在未在全局环境中定义的另一个函数中使用parLapply。 worker函数预先使用我希望clusterExport其他函数列表,这些函数也未在全局环境中定义。我的问题是两个函数都将它们的评估环境导出到集群,这些巨大且不需要。

让我们调用worker函数workerFunction和函数列表functionList

    workerFunction <- function(i) {
        intermediateOutput <- functionList[[i]](y)
        result <- otherCalculations(intermediateOutput)
        return(result)    
    }

    library(parallel)
    cl <- makeCluster(detectCores())
    environment(workerFunction) <- .GlobalEnv
    environment(functionList) <- .GlobalEnv
    clusterExport(cl, varlist=c("functionList", "y"), envir=.GlobalEnv)
    output <- parLapply(cl, inputVector, workerFunction)

我明白了:

Error in get(name, envir = envir) (from <text>#53) : object 'functionList' not found

如果我没有设置environment(functionList) <- .GlobalEnv,那么functionList的巨大封闭环境将导出到群集。为什么R不能在全局环境中找到functionList

1 个答案:

答案 0 :(得分:11)

如果没有完整的示例,很难猜出问题,但我想知道错误消息是否来自clusterExport,而不是来自parLapply。如果在函数而不是全局环境中定义functionList,则会发生这种情况,因为clusterExport envir参数指定了从中导出变量的环境。

要导出函数中定义的变量,请使用相同的函数:

clusterExport(cl, varlist=c("functionList", "y"), envir=environment())

我只是猜测这可能对你有用,因为我不知道你如何定义functionList。请注意,clusterExport始终将变量分配给集群工作者的全局环境。

我也怀疑你显然是如何设置列表环境的方式:这似乎是合法的,但我认为它不会改变该列表中函数的环境。事实上,我怀疑将函数导出到列表中的worker可能还有其他一些您尚未遇到的问题。我会用这样的东西:

mainFunction <- function(cl) {
    fa <- function(x) fb(x)
    fb <- function(x) fc(x)
    fc <- function(x) x
    y <- 7
    workerFunction <- function(i) {
        do.call(functionNames[[i]], list(y))
    }
    environment(workerFunction) <- .GlobalEnv
    environment(fa) <- .GlobalEnv
    environment(fb) <- .GlobalEnv
    environment(fc) <- .GlobalEnv
    functionNames <- c("fa", "fb", "fc")
    clusterExport(cl, varlist=c("functionNames", functionNames, "y"),
                  envir=environment())
    parLapply(cl, seq_along(functionNames), workerFunction)
}

library(parallel)
cl <- makeCluster(detectCores())
mainFunction(cl)
stopCluster(cl)

请注意,我对你的例子采取了自由,所以我不确定这与你的问题有多好。