ошибка переполнения стека fread protection
Я использую fread в данных.таблица (1.8.8, Р 3.0.1) при попытке чтения очень больших файлов.
файл в вопросах имеет 313 строк и ~6.6 миллионов cols числовых строк данных, а файл составляет около 12 ГБ. Это Centos 6.4 с 512 ГБ оперативной памяти.
когда я пытаюсь прочитать в файле:
g=fread('final.results',header=T,sep=' ')
'header' changed by user from 'auto' to TRUE
Error: protect(): protection stack overflow
Я попытался запустить R с --max-ppsize 500000, что является максимальным, но та же ошибка.
Я также попытался установить размер стека неограниченный via
ulimit -s unlimited
Виртуальная память уже была установлена в unlimited.
Я нереалистичен с файлом такого размера? Я пропустил что-то очевидное?
1 ответов
теперь исправлено в 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, что защита внутри цикла не требуется:
в некоторых случаях необходимо держать лучше отслеживать, действительно ли необходима защита. Быть особенно известно о ситуациях, когда генерируется большое количество объектов. Указатель стек защиты имеет фиксированный размер (по умолчанию 10,000) и может стать полным. Это не очень хорошая идея затем просто защитить все в поле зрения и снять защиту несколько тысяч объектов в конце. Он почти всегда можно назначить объекты как часть другого объекта (который автоматически защищает их) и снять их сразу после использования.
Так что защита теперь удалена, и все хорошо. (Кажется, что ограничение стека защиты указателя было уменьшено до 50 000 с момента написания этого текста; Defn.h содержит #define R_PPSSIZE 50000L
.) Я проверил все другие защиты в данных.источник таблицы C для чего-либо подобного и найденного и исправленного в assign.c тоже (при добавлении более 50 000 столбцов по ссылке), никаких других.
Спасибо за отчеты!