9

我在 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

虚拟内存已经设置为无限。

我对这种大小的文件不切实际吗?我错过了一些相当明显的事情吗?

4

1 回答 1

7

现在在 R-Forge 上的 v1.8.9 中修复。

  • 在 中删除了意外的 50,000 列限制fread。感谢 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 第 5.9.1 节,不需要循环内的 PROTECT :

在某些情况下,有必要更好地跟踪是否确实需要保护。要特别注意生成大量对象的情况。指针保护堆栈具有固定大小(默认为 10,000)并且可以变满。那么只保护视线中的所有东西并在最后取消保护数千个对象并不是一个好主意。几乎总是可以将对象分配为另一个对象的一部分(自动保护它们)或在使用后立即取消保护它们。

所以现在删除了 PROTECT,一切都很好。(似乎自从编写该文本以来,指针保护堆栈限制已减少到 50,000;Defn.h 包含#define R_PPSSIZE 50000L。)我已经检查了 data.table C 源代码中的所有其他 PROTECT 是否有任何类似的东西,并在分配中找到并修复了一个。 c 也是(通过引用添加超过 50,000 列时),没有其他。

感谢您的报告!

于 2013-08-26T20:28:25.473 回答