在R中的doParallel错误:Error in serialize(data, node$con) : error writing to connection。

35

这是我的代码。循环内的东西是有意义的。

        library(foreach)
        library(doParallel)
        cl <- makeCluster(7)
        registerDoParallel(cl) 

        elasticitylist = foreach(i=1:nhousehold) %dopar% {

            pricedraws = out$betadraw[i,12,] 
            elasticitydraws[,,i]= probarray[,,i] %*% diag(pricedraws)
            elasticitydraws[,,i] = elasticitydraws[,,i] * as.vector(medianpricemat)

        } 

我一直收到这个错误:

Error in serialize(data, node$con) : error writing to connection

我知道我有足够的内核(有20个)。 有人能帮忙解决吗?看起来答案在文档中无处可寻!

当我在我的Unix服务器上运行ps -ef| grep user时,我会得到:

/apps/R.3.1.2/lib64/R/bin/exec/R --slave --no-restore -e parallel:::.slaveRSOCK() --args MASTER=localhost PORT=11025 OUT=/dev/null TIMEOUT=2592000 METHODS=TRUE XDR=TRUE

除了一些手动生成的数据之外,代码基本与您的相同,对我有效。如果您能使示例可重现,我可以再次查看。您是否使用了不寻常的数据结构? - kasterma
数据非常大,但并不异常。我认为out$betadraw是一个矩阵切片,可能是这个原因吗? - wolfsatthedoor
6个回答

21
函数serializeunserialize用于主进程在使用套接字集群时与工作进程通信。如果这些函数中的任何一个出现错误,通常意味着至少有一个工作进程已经停止运行。在Linux机器上,它可能已经死亡是因为机器几乎没有内存可用,所以内存杀手决定将其杀死,但还有许多其他可能性。
我建议您在创建集群对象时使用makeCluster outfile=""选项,以便显示来自工作进程的输出。如果幸运的话,在工作进程停止之前,您可以从工作进程获得错误消息,帮助您解决问题。

5
我朋友说,如果你试图让输出的内存过高,通常会出现错误,无论你有多少RAM。你知道有什么解决方法吗? - wolfsatthedoor

10

我曾经遇到过同样的问题,当我尝试使用我的机器上的所有8个核心时。当我留下一个空闲时,问题就消失了。我相信系统需要一个核心来处理服务任务,否则你会收到错误提示:

library(doParallel)
#Find out how many cores are available (if you don't already know)
cores<-detectCores()
#Create cluster with desired number of cores, leave one open for the machine         
#core processes
cl <- makeCluster(cores[1]-1)
#Register cluster
registerDoParallel(cl)

6
我认为引起错误的不是核心数量本身;我注意到,当我处理大文件(4GB或更大)并使用“doParallel”时,我需要减少使用的核心数,否则内存不足。因此,问题可能是使用太多核心会占用过多内存,从而导致错误。有更多知识的人能确认/否定/解释这一点吗? - g_puffo
2
很可能doParallel会将所有数据从主节点复制到从节点。因此,内存需求会随核心数线性增长。主节点和从节点都从同一内存池中获取数据,所以很容易超出内存限制。 - Kevin L. Keys

5

我从以下内容中收到了类似的错误,当我提前结束模型训练并尝试再次运行它时。这里是一个例子,我正在使用caret包来训练模型,但我认为它适用于任何涉及并行处理的应用。

> cluster <- makeCluster(10)
> registerDoParallel(cluster)
> train(... , trControl = trainControl(allowParallel = T)
# Terminated before complete
> train(... , trControl = trainControl(allowParallel = T)
Error in serialize(data, node$con) : error writing to connection

我关闭了集群并重新初始化它:

stopCluster(cluster)
registerDoSEQ()
cluster <- makeCluster(10)
registerDoParallel(cluster)

当再次运行模型时,没有看到错误。有时候真的把它关掉然后重新打开可能会是解决方法。


4
每个分配的核心都会消耗内存。因此,核心数量越多,需要的内存就越多,一旦用完,就会收到这个错误。因此,我的建议是减少并行化的核心数。
我自己有8个核心和32 GB可用内存,我尝试使用7个,然后是6个核心,遇到了类似的错误。之后,我决定只分配4个核心,它正在消耗大约70%的内存:

enter image description here

再多一个核心可能会更好。

P.S:不要介意图片质量。


3
收到此错误消息后,我将代码改为非并行for循环。然后我收到了错误消息“无法分配大小为*** Gb的向量”。我猜测并行失败可能是由于同样的原因造成的,只是错误消息不同。

0

我在使用mclapply函数时遇到了类似的问题。我不知道原因,因为错误似乎是随机出现的。但是我使用了这个解决方法,对我来说完美地解决了问题:

for(....( {
    .
    .
    .
 
    error_count <- 1
    while (error_count <= 3) {
      error <- try(
        FUNCTION THAT USES mclapply
      )
  
      if(class(error) != "try-error") break
  
      error_count <- error_count + 1
      invisible(gc()); Sys.sleep(1)
    }
    if(class(error) == "try-error") next

    .
    .
    .
}

到目前为止,当错误发生时,它会在第二个while迭代中工作。


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