R doSnow / foreach内存泄漏和过多的迭代

时间:2016-09-20 23:41:52

标签: r foreach memory-leaks doparallel

未解决问题摘要:

1。内存不足 - 主进程需要太多内存,但不应该

我会尝试计算一种任意网络的很多组合,并使用doparralel和foreach来解决一些问题。只要有一定的问题,即使使用makeCluster(3)也只有一个进程启动。另外,我的内存耗尽(使用~50GB后 - 错误:杀死9 - 在Mac上)。奇怪的是,问题的规模越小,已经非常大,它运行没有任何问题。我真的无法理解它,为什么它会填满内存并且不会启动多个进程。可能是因为它太大而无法计算?

代码:

pacman::p_load(iterpc, doSNOW,data.table, gtools, e1071)
source('adj.R', chdir = TRUE)
source('mm.R', chdir = TRUE)

ptm<-proc.time()
###with n<-5 and p<-3 it is running without any problems
n<-6 #genotype length
p<-3 #phenotype length
pevo<-NULL
prob<-NULL
I = iterpc(2^p, 2^n, replace=TRUE, ordered=F) #all combinations
bgg   <- adjmatrix(n)

cl <- makeCluster(6)
registerDoSNOW(cl)

res<-foreach(elem = iter_wrapper(I,100) ,.combine='rbind') %dopar% {
gc()
rm()

  for(z in 1:nrow(elem)){

    bzz<-matmult(t(matmult(bgg,elem[z,])),elem[z,])
    size<-NULL
    for(k in 1:ncol(bzz)){
            size[k]<-length(which(elem==k))
    }

    prob<-rbind(prob,diag(bzz)/colSums(bgz)/n)
    diag(bzz)<-0
    pevo<-rbind(pevo,colSums(bzz != 0))
  }

    return(cbind(pevo,prob))    
}
proc.time()-ptm

write.table(res,'res2.txt',col.names=F,row.names=F,sep=" ")
print(object.size(res), units='auto')
gc()
rm()

以下是我的Activity Monitor的截图,其中一个R进程需要更多内存(最高55GB): Activity Monitor

以下是错误的屏幕截图:Error

编辑09/22:

我已更新上述代码。似乎使用DoSNOW包而不是doParallel解决了进程的问题。使用DoSNOW时,会启动正确数量的进程。但这开启了一个新问题。 foreach运行了太多次迭代。

我已添加到功能中:

  1. 使用函数bgg计算adjmatrix

    adjmatrix <- function(n){
    require(e1071)
    
    combi <- bincombinations(n)
    l     <- length(combi[,1])
    bgg   <- matrix(0,l,l)
    
    for(i in 1:(length(combi[,1])-1)){
      for(j in (i+1):length(combi[,1])){
        check <- 0
        for(h in 1:length(combi[j,])){
          if(combi[j,h]!=combi[i,h]){
            check <- check+1
          }
        }   
        if(check==1){
          bgg[i,j] <- 1
          bgg[j,i] <- 1
        }
      }
    }
    return(bgg)
    }
    
  2. 使用函数bzz

    更改了matmult的计算
    matmult <- function(A,B){
    
    c <- matrix(0,nrow(A),length(B))
    for(i in 1:nrow(A)){
        for(j in 1:length(B)){
            sum <- 0
            for(k in 1:length(B)){
                if(j == B[k]){
                sum <- sum+A[i,k]}
            }
                c[i,j] <- sum
        }
    }
    return(c)
    }
    
  3. 编辑09/23: 解决了:DoSNOW包:foreach运行了太多次迭代

    原因是代码的这一部分:

    if(is.null(prob)){
            prob<-diag(bzz)/size/n
        }
        else{
            prob<-rbind(prob,diag(bzz)/size/n)  
        }
        diag(bzz)<-0
        if(is.null(pevo)){
            pevo<-colSums(bzz != 0)
        }
        else{
            pevo<-rbind(pevo,colSums(bzz != 0))
        }
    

    以下更改会导致正确的迭代次数(或结果):

    prob<-rbind(prob,diag(bzz)/colSums(bgz)/n)
    diag(bzz)<-0
    pevo<-rbind(pevo,colSums(bzz != 0))
    

    更新了代码。

0 个答案:

没有答案