缺少来自foreach和Parallel

时间:2017-08-05 03:13:16

标签: r foreach parallel-processing parallel.foreach

由于先前脚本中的内存限制,我在与我的类似问题中遵循此建议进行了修改(不提供超出工作人员需要的数据 -  reading global variables using foreach in R)。不幸的是,现在我正在努力解决缺失的问题。

脚本遍历1.9M列矩阵,处理每一列并返回一行数据帧(来自foreach的rbind函数组合每一行)。但是,在打印结果时,行数(结果)少于列数,并且每次运行时此数量都会更改。看起来,foreach循环中的函数没有错误,因为它在以前的脚本中运行平稳,并且不会弹出错误或警告消息。

新脚本

if(!require(R.utils)) { install.packages("R.utils"); require(R.utils)}
if(!require(foreach)) { install.packages("foreach"); require(foreach)}
if(!require(doParallel)) { install.packages("doParallel"); require(doParallel)}
if(!require(data.table)) { install.packages("data.table"); require(data.table)}
registerDoParallel(cores=6)

out.file = "data.result.167_6_inside.out"
out.file2 = "data.result.167_6_outside.out"

data1 = fread("data.txt",sep = "auto", header=FALSE, stringsAsFactors=FALSE,na.strings = "NA")
data2 = transpose(data1)
rm(data1)
data3 = data2[,3: dim(data2)[2]]
levels2 = data2[-1,1:(3-1)]
rm(data2)

colClasses=c(ID="character",Col1="character",Col2="character",Col3="character",Col4="character",Col5="character",Col6="character") 
res_table = dataFrame(colClasses,nrow=0)

write.table(res_table , file=out.file, append = T, col.names=TRUE, row.names=FALSE, quote=FALSE)
write.table(res_table, file=out.file2, append = T, col.names=TRUE, row.names=FALSE, quote=FALSE)

tableRes =  foreach(col1=data3, .combine="rbind") %dopar% {

    id1 = col1[1]
    df2function = data.frame(levels2[,1,drop=F],levels2[,2,drop=F],as.numeric(col1[-1]))
    mode(df2function[,1])="numeric"
    mode(df2function[,2])="numeric"
    values1 <- try (genericFuntion(df2function), TRUE)
        if (is.numeric(try (values1$F, TRUE))) 
        {
            res_table [1,1] = id1
            res_table [1,2] = values1$F[1,1] 
            res_table [1,3] = values1$F[1,2] 
            res_table [1,4] = values1$F[1,3] 
            res_table [1,5] = values1$F[2,2] 
            res_table [1,6] = values1$F[2,3] 
            res_table [1,7] = values1$F[3,3] 
        } else 
        { 
            res_table[1,1] = id1 
            res_table[1,2] = NA 
            res_table[1,3] = NA 
            res_table[1,4] = NA 
            res_table[1,5] = NA 
            res_table[1,6] = NA 
            res_table[1,7] = NA 
        }
write.table(fstats_table, file=out.file, append = T, col.names=FALSE, row.names=FALSE, quote=FALSE)
return(fstats_table[1,]) 
}
write.table(tableFst, file=out.file, append = T, col.names=FALSE, row.names=FALSE, quote=FALSE)

上一个剧本中,foreach就是这样:

tableRes =  foreach(i=1:length(data3), iter=icount(), .combine="rbind") %dopar% { (same code as above) }

因此,我想知道这种行为的可能原因是什么。

我在群集中运行此脚本,要求80 Gb内存(在此示例中为6个内核)。这是我可以请求单个节点的最大RAM量,以确保脚本不会因内存不足而失败。 (每个节点都有一对14核Intel Xeon skylake CPU 2.6GHz,128GB RAM; OS - RHEL 7)

Ps 1:虽然新脚本不再是分页(即使有超过8个内核),但似乎每个子进程仍在内存中加载大量数据(~6 Gb),因为我使用top命令进行跟踪。 / p>

Ps 2:新脚本在foreach循环内外打印结果,以跟踪循环结束期间或之后是否发生数据丢失,因为我注意到每次运行都会在内部和外部给出不同数量的打印结果循环。

P3:最快的运行基于20个核心(1000次迭代为6秒),单个核心的最慢运行时间为56秒(使用microbenchmark进行的测试,重复10次)。但是,更多核心导致在完整矩阵(1.9M列)中返回的结果更少。

我非常感谢您提供的任何帮助,

0 个答案:

没有答案