10

我正在尝试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被导出到集群。为什么 RfunctionList在全局环境中找不到?

4

1 回答 1

14

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

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

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

我只是猜测这对您来说可能是个问题,因为我不知道您如何或在何处定义functionList. 请注意,clusterExport始终将变量分配给集群工作人员的全局环境。

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

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)

请注意,我对您的示例有所冒犯,因此我不确定这与您的问题的对应程度如何。

于 2013-07-01T14:38:04.487 回答