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

Ron*_*ert 7 parallel-processing r 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)
Run Code Online (Sandbox Code Playgroud)

我明白了:

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

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

Ste*_*ton 12

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

要从函数中导出函数中定义的变量,您可以使用:

clusterExport(cl, varlist=c("functionList", "y"), envir=environment())
Run Code Online (Sandbox Code Playgroud)

我只是猜测这对你来说可能是一个问题,因为我不知道你定义的方式和位置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)
Run Code Online (Sandbox Code Playgroud)

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