R程序包将来:plan()的初始化失败

时间:2018-11-28 22:29:59

标签: r r-future

尝试此代码

library(future)
library(foreach)

ncores <- 3
cl <- parallel::makeCluster(3)
avail <- bigstatsr::FBM(ncores, 1, type = "integer", init = 1)
doFuture::registerDoFuture()

res <- vector("list", 5)
for (i in seq_along(res)) {

  while (sum(avail[]) == 0) {
    cat("Waiting..\n")
    Sys.sleep(0.5)
  }
  ind.avail <- which(avail[] == 1)
  cat("Available:", length(ind.avail), "\n")

  plan(cluster, workers = cl[ind.avail])
  foo <- foreach(i = 3:1) %dopar% {
    Sys.sleep(i)
  }

  print(one <- ind.avail[1])
  avail[one] <- 0; print(avail[])
  res[[i]] <- cluster(workers = cl[one], {
    Sys.sleep(5)
    avail[one] <- 1
    i
  })
}

sapply(res, resolved)
parallel::stopCluster(cl)

我得到错误:Initialization of plan() failed, because the test future used for validation failed. The reason was: Unexpected result (of class ‘NULL’ != ‘FutureResult’) retrieved for ClusterFuture future (label = ‘<none>’, expression = ‘NA’)

我的示例试图重现我的真实问题的说明:

  • 我分两步循环了许多次(此处为5次)
  • 第一步很容易与foreach并行
  • 第二步不容易并行化,取决于第一步

所以我的想法是在所有可用集群上并行执行第一步,并仅使用一个集群异步运行第二步。在完成此异步作业之前,该群集不再可用。然后,下一步将减少一个可用的群集,依此类推。当第一步没有可用的集群时,它将等待一些异步作业完成并释放一些集群。

1 个答案:

答案 0 :(得分:1)

我可以复制这个。我相信您正在通过调用带有保存尚未返回主R进程的未来结果的群集节点的plan()来破坏与主R进程和群集节点的通信。 (我试图给出一个更简单的例子来说明这种类型的腐败,但是如果不花费更多的时间,这种情况就不明显了。)

将来的框架已经检测到此问题(因此出现错误)。我对develop version of future进行了更新,以提供更多有关发生情况的线索和证据:

Error: Initialization of plan() failed, because the test future used for
  validation failed. The reason was: Unexpected result (of class ‘character’
  != ‘FutureResult’) retrieved for ClusterFuture future (label = 
  ‘future-plan-test’, expression = ‘NA’): future-grmall. This suggests that
  the communication with ClusterFuture worker (‘SOCKnode’ #1) is out of sync.

我认为您可以通过以下方法来解决此问题:在重新使用其工人之前,确保您收集了已结算期货的价值。 plan(cluster, ...)调用可验证至少一个未来可以成功解决。