【问题标题】:doParallel error in R: Error in serialize(data, node$con) : error writing to connectionR中的doParallel错误:序列化错误(数据,节点$ con):写入连接时出错
【发布时间】:2015-02-13 15:40:38
【问题描述】:

这是我的代码。循环内的东西是有道理的。

        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

【问题讨论】:

  • 代码与你的基本相同,除了一些手工生成的数据对我有用。如果您使示例可重现,我可以再看一下。您是否使用了不寻常的数据结构?
  • 数据很大,但并不罕见。我认为 out$betadraw 是一个矩阵切片,可以吗?

标签: r parallel-processing


【解决方案1】:

serialize 和 unserialize 函数在使用套接字集群时由主进程调用以与工作人员进行通信。如果您从其中任何一个函数中得到错误,通常意味着至少有一个工人已经死亡。在 Linux 机器上,它可能已经死掉了,因为机器几乎内存不足,所以内存不足杀手决定杀死它,但还有很多其他的可能性。

我建议您在创建集群对象时使用 makeCluster outfile="" 选项,以便显示工作人员的输出。如果幸运的话,您会在工作人员死亡之前收到一条错误消息,这将帮助您解决问题。

【讨论】:

  • 我的朋友说这是因为当你试图让输出内存太高时,无论你有多少内存,它通常都会出错。你知道解决这个问题的方法吗?
【解决方案2】:

当我尝试使用机器的所有 8 个内核时,我遇到了同样的问题。当我打开一个时,问题就消失了。我相信系统需要 1 个核心来完成未打开的服务任务,否则会出现错误:

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)

【讨论】:

  • 我不认为是核心数量导致错误;我注意到,当我处理大文件(4+Gb)并使用“doParallel”时,我需要减少使用的内核数量,否则我的内存不足。所以问题可能是太多的内核使用了太多的内存,这会引发错误。任何有更多知识的人都可以证实/反驳/解释这一点?
  • doParallel 可能会将所有数据从主服务器复制到从服务器。因此,内存需求将随着内核数量线性增长。 master 和 slave 都从同一个内存池中提取,所以突破内存限制并不难。
【解决方案3】:

我收到以下类似错误,我提前通过模型训练终止,然后尝试再次运行它。这是一个例子,我正在使用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】:

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

    【讨论】:

      【解决方案5】:

      您分配的每个核心都会消耗内存。所以更多的核心意味着需要更多的内存,一旦你用完它,你就会收到这个错误。所以我的建议是减少并行化的核心数量。

      我自己有 8 个内核和 32 GB 内存,我自己尝试使用 7 个内核,然后是 6 个内核,但遇到了类似的错误。之后我决定只使用 4 个核心,它消耗了大约 70% 的内存:-

      多 1 个内核可能会起作用。

      PS: 不要介意画质。

      【讨论】:

        【解决方案6】:

        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 迭代。

        【讨论】:

          猜你喜欢
          • 2018-01-04
          • 1970-01-01
          • 1970-01-01
          • 2018-09-24
          • 1970-01-01
          • 1970-01-01
          • 2016-02-15
          • 1970-01-01
          • 2020-02-13
          相关资源
          最近更新 更多