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&lt;-fread('final.results',sep=' ',header=TRUE))user system elapsed881.321 16.594 923.957 @mpmorley 太好了,感谢您的测试。读一个 12GB 的文件需要 15 分钟,这听起来不错,因为它太宽了。你可以吗?还有什么读得更快吗?有兴趣查看verbose=TRUE 报告的时间细分。例如,如果它主要用于映射,则可能有更多选项需要调整。 对我来说这是可以接受的,我并不专注于对所有这些数据做有用的事情,可能会看到一个新帖子。但是,如果您和其他人有兴趣,我很高兴运行和发布。

以上是关于fread保护堆栈溢出错误的主要内容,如果未能解决你的问题,请参考以下文章

错误:protect():使用 dbWriteTable (RSQLite) 写入文件时保护堆栈溢出

r - viterbi RHmm 错误保护堆栈溢出

堆栈溢出

js堆栈溢出错误

分段错误和堆栈溢出有啥区别?

什么是堆栈溢出和缓冲区溢出错误? [复制]