fread保护堆栈溢出错误
Posted
技术标签:
【中文标题】fread保护堆栈溢出错误【英文标题】:fread protection stack overflow error 【发布时间】:2013-08-29 06:56:33 【问题描述】:我在 data.table (1.8.8, R 3.0.1) 中使用 fread 来尝试读取非常大的文件。
有问题的文件有 313 行和大约 660 万列数字数据行,文件大约 12gb。这是具有 512GB 内存的 Centos 6.4。
当我尝试读取文件时:
g=fread('final.results',header=T,sep=' ')
'header' changed by user from 'auto' to TRUE
Error: protect(): protection stack overflow
我尝试使用 --max-ppsize 500000 启动 R,这是最大值,但同样的错误。
我还尝试通过将堆栈大小设置为无限制
ulimit -s unlimited
虚拟内存已设置为无限。
我对这种大小的文件是否不切实际?我错过了一些相当明显的事情吗?
【问题讨论】:
请在 R-Forge 上试用 v1.8.9(data.table 主页上的链接)。fread
有 10 个错误修复,请参阅新闻。大文件支持就是其中之一,但在 Windows 上应该可以在 Linux 上使用。 660 万列 (!) 是新的,很可能是一个新错误。请确认 v1.8.9,我们将从那里开始......
@MatthewDowle 是的,我对 600 万行也不满意。安装 1.8.9,同样的错误。我制作了一个小得多的文件,10 行 x 50K 列,同样的错误。 10 行 x 49,999 列它可以工作。
您是指该评论中的列(您写了 600 万行)?非常有趣和奇怪,它恰好在 50,000 列时失败。如此迅速地磨练这一点做得很好。我不记得有任何这样的列限制。会看看。
抱歉,是的列。关于第一个评论的问题,我有 512Gb 的 RAM,为什么文件不适合?感谢 data.table 的出色工作。
Apols,我看错了。出于某种原因,我将 512 解释为 MB,因为那时 512GB RAM 相当大!即使你写了 512GB。所以,是的,应该当然读得很好。 read.table
/ read.csv
是否适用于 50k 列和 6e6 列?
【参考方案1】:
现已在 R-Forge 的 v1.8.9 中修复。
已在fread
中删除了意外的 50,000 列限制。感谢 mpmorley 的报告。添加了测试。
原因是我在fread.c 源中弄错了这部分:
// *********************************************************************
// Allocate columns for known nrow
// *********************************************************************
ans=PROTECT(allocVector(VECSXP,ncol));
protecti++;
setAttrib(ans,R_NamesSymbol,names);
for (i=0; i<ncol; i++)
thistype = TypeSxp[ type[i] ];
thiscol = PROTECT(allocVector(thistype,nrow)); // ** HERE **
protecti++;
if (type[i]==SXP_INT64)
setAttrib(thiscol, R_ClassSymbol, ScalarString(mkChar("integer64")));
SET_TRUELENGTH(thiscol, nrow);
SET_VECTOR_ELT(ans,i,thiscol);
根据R-exts section 5.9.1,不需要循环内的保护:
在某些情况下,有必要更好地跟踪是否确实需要保护。是 特别注意生成大量对象的情况。指针 保护堆栈具有固定大小(默认为 10,000)并且可以变满。这不是一个好主意 然后只保护视线中的所有东西,最后取消保护数千个物体。它 几乎总是可以将对象分配为另一个对象的一部分( 自动保护它们)或在使用后立即取消保护。
所以现在删除了 PROTECT,一切都很好。 (自从编写该文本以来,指针保护堆栈限制似乎已减少到 50,000;Defn.h 包含 #define R_PPSSIZE 50000L
。)我检查了 data.table C 源中的所有其他 PROTECT 是否有类似的东西,并找到并修复了一个在 assign.c 中(通过引用添加超过 50,000 列时),没有其他。
感谢您的报告!
【讨论】:
使用 313 行和 6536299 列的文件进行测试。system.time(geno<-fread('final.results',sep=' ',header=TRUE))
user system elapsed
881.321 16.594 923.957
@mpmorley 太好了,感谢您的测试。读一个 12GB 的文件需要 15 分钟,这听起来不错,因为它太宽了。你可以吗?还有什么读得更快吗?有兴趣查看verbose=TRUE
报告的时间细分。例如,如果它主要用于映射,则可能有更多选项需要调整。
对我来说这是可以接受的,我并不专注于对所有这些数据做有用的事情,可能会看到一个新帖子。但是,如果您和其他人有兴趣,我很高兴运行和发布。以上是关于fread保护堆栈溢出错误的主要内容,如果未能解决你的问题,请参考以下文章