错误:找不到对象“.doSnowGlobals”?

11

我正在尝试将一段代码在4个节点(类型为“SOCK”)上并行化。这是我的代码。

library(itertools)
library(foreach)
library(doParallel)
library(parallel)

workers <- ip address of 4 nodes
cl = makePSOCKcluster(workers, master="ip address of master")
registerDoParallel(cl)

z <- read.csv("ProcessedData.csv", header=TRUE, as.is=TRUE)
z <- as.matrix(z)


system.time({
  chunks <- getDoParWorkers()
  b <- foreach (these = isplitIndices(nrow(z),
                                      chunks=chunks),
                .combine = c) %dopar% {
                  a <- rep(0, length(these))
                  for (i in 1:length(these)) {
                    a[i] <- mean(z[these[i],])
                  }
                  a
                }
})

我遇到了这个错误:

  

4个节点产生了错误,第一个错误:找不到对象'.doSnowGlobals'。

如果我使用doMC即使用同一台机器的内核,这段代码可以正常运行。但是当我尝试使用其他计算机进行并行计算时,就会出现上述错误。当我将其更改为registerDoSNOW时,错误仍然存在。

snow和DoSNOW在集群中能否工作?我可以使用snow在本地主机上创建节点,但无法在集群上创建。有人在使用snow吗?

5个回答

8

要在每个工作节点上设置库路径,您可以运行以下命令:

clusterEvalQ(cl, .libPaths("Your library path"))

为什么在某些系统上这是必要的,而在某些系统上却不是呢? - Ahdee

6

如果任何一个工作者无法加载doParallel包,您可能会遇到此错误。您可以通过将doParallel安装到某个目录并通过“.libPaths”将主节点指向它来实现:

> .libPaths('~/R/lib.test')
> library(doParallel)
> cl <- makePSOCKcluster(3, outfile='')
starting worker pid=26240 on localhost:11566 at 13:47:59.470
starting worker pid=26248 on localhost:11566 at 13:47:59.667
starting worker pid=26256 on localhost:11566 at 13:47:59.864
> registerDoParallel(cl)
> foreach(i=1:10) %dopar% i
Warning: namespace ‘doParallel’ is not available and has been replaced
by .GlobalEnv when processing object ‘’
Warning: namespace ‘doParallel’ is not available and has been replaced
by .GlobalEnv when processing object ‘’
Warning: namespace ‘doParallel’ is not available and has been replaced
by .GlobalEnv when processing object ‘’
Error in checkForRemoteErrors(lapply(cl, recvResult)) : 
  3 nodes produced errors; first error: object '.doSnowGlobals' not found

当从doParallel序列化函数到worker时,会出现警告。当执行该函数并尝试访问.doSnowGlobal时,会出现错误,因为.doSnowGlobal是在doParallel命名空间中定义的,而不是在.GlobalEnv中定义的。
您还可以通过执行以下操作验证workers上是否可用doParallel:
> clusterEvalQ(cl, library(doParallel))
Error in checkForRemoteErrors(lapply(cl, recvResult)) : 
  3 nodes produced errors; first error: there is no package called ‘doParallel’

这解释了为什么会发生,但你如何修复它? - Eden

4
@Steve Weston的回答中,一个具体的情况是当你的工作者无法加载给定的软件包(例如doParallel),因为该包在Packrat项目内。将软件包安装到系统库或其他某个工人能够找到它们的地方。

1
我从这个线程中发现,我需要在foreach包内重新指定libpaths。然后它就能够找到所需的包以及.doSnowGlobals。 经过进一步研究后,我发现packrat本身并不是问题,而是因为我使用了packrat加载R,并使用setwd()到一个子文件夹。当启动worker时,它无法在项目目录中找到.Rprofile,也无法加载packrat库。 - Alexis Lucattini

1

对我来说,这些解决方法都没有起作用。在我的情况下,我使用了自定义的R库位置。如果我的工作目录是存放自定义libraries文件夹的基本目录,则并行处理可以正常工作,但是如果我使用setwd()更改工作目录,则会失败。

这个自定义库位置没有被传递到工作节点,因此它们在R的默认库目录中查找不存在的包。@Nat提供的解决方法对我没有用;工作节点仍然找不到我的自定义库文件夹。真正起作用的是:

在将作业发送到节点之前:

paths <- .libPaths()

我随后将任务发送给节点,并附上参数paths。然后,在工作函数内部,我只需调用:

.libPaths(paths)

1
今天我遇到了同样的问题,我尝试了上面所有的答案,但都没有解决我的问题。然后我简单地重新安装了doSNOW包,神奇地,问题就解决了。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接