另一个函数内的 运行 parLapply 和 future_map 不必要地将大对象复制到每个 worker

Running parLapply and future_map inside another function unnecessarily copies large objects to each worker

我一直在寻找 furrr:future_map() 的替代方法,因为当这个函数在另一个函数中 运行 时,它会将在该函数中定义的所有对象复制到每个 worker,而不管这些对象是否被显式传递( https://github.com/DavisVaughan/furrr/issues/26).

看起来 parLapply() 在使用 clusterExport() 时做同样的事情:

fun <- function(x) {
  big_obj <- 1
  cl <- parallel::makeCluster(2)
  parallel::clusterExport(cl, c("x"), envir = environment())
  parallel::parLapply(cl, c(1), function(x) {
    x + 1
    env <- environment()
    parent_env <- parent.env(env)
    return(list(this_env = env, parent_env = parent_env))
  })
}

res <- fun(1)
names(res[[1]]$parent_env)
#> [1] "cl"      "big_obj" "x"

reprex package (v0.3.0)

于 2020-01-06 创建

如何防止 big_obj 被复制到每个工作人员?我正在使用 Windows 机器,因此不能选择分叉。

您可以更改本地函数的环境,使其不包含 big_obj,方法是分配例如只有基础环境。

fun <- function(x) {
  big_obj <- 1
  cl <- parallel::makeCluster(2)
  on.exit(parallel::stopCluster(cl), add = TRUE)
  parallel::clusterExport(cl, c("x"), envir = environment())
  local_fun <- function(x) {
    x + 1
    env <- environment()
    parent_env <- parent.env(env)
    return(list(this_env = env, parent_env = parent_env))
  }
  environment(local_fun) <- baseenv()
  parallel::parLapply(cl, c(1), local_fun)
}
res <- fun(1)
"big_obj" %in% names(res[[1]]$parent_env) # FALSE