2013-08-26 12 views
7

Sto usando fread in data.table (1.8.8, R 3.0.1) nel tentativo di leggere file molto grandi.errore di overflow stack protezione freading

Il file nelle domande ha 313 righe e ~ 6,6 milioni di colonne di righe di dati numerici e il file è di circa 12 GB. Questo è un Centos 6.4 con 512 GB di RAM.

Quando tento di leggere nel file:

g=fread('final.results',header=T,sep=' ') 
'header' changed by user from 'auto' to TRUE 
Error: protect(): protection stack overflow 

ho provato a partire con R---max ppsize 500000, che è il massimo, ma lo stesso errore.

Ho anche provato a installare la dimensione dello stack per illimitate via

ulimit -s unlimited 

La memoria virtuale è stato già impostato su illimitato.

Sono irrealistico con un file di queste dimensioni? Mi sono perso qualcosa di abbastanza ovvio?

+0

Provare v1.8.9 su R-Forge (collegamento sulla homepage di data.table). Ci sono 10 correzioni di bug a 'fread' lì, vedi NEWS. Il supporto di file di grandi dimensioni è uno di questi, ma su Windows come già dovrebbe essere ok su Linux. 6,6 milioni di colonne (!) Sono nuove e potrebbero essere un nuovo bug. Si prega di confermare con v1.8.9 e andremo da lì ... –

+0

@MatthewDowle Sì, non sono contento neanche con 6 milioni di righe. Installa 1.8.9, stesso errore. Ho creato un file molto più piccolo, 10 righe x 50K colonne, lo stesso errore. 10 righe x 49,999 cols funziona. – mpmorley

+1

Intendevi colonne in quel commento (hai scritto 6 milioni di righe)? Molto interessante e strano non riesce esattamente a 50.000 colonne. Ben fatto per affinare così rapidamente. Non ricordo alcun limite di colonne del genere. Dare un'occhiata. –

risposta

6

Ora corretto in v1.8.9 su R-Fucina.

  • Un limite di 50.000 colonna volute è stata rimossa in fread. Grazie a mpmorley per la segnalazione. Test aggiunto.

La ragione era ho avuto questa parte sbagliata nella fread.c fonte:

// ********************************************************************* 
// 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); 
} 

Secondo R-exts section 5.9.1, che proteggono all'interno del ciclo non è necessaria:

In alcuni In alcuni casi è necessario tenere sotto controllo se la protezione è davvero necessaria. Sii particolarmente attento alle situazioni in cui viene generato un numero elevato di oggetti. Lo stack di protezione del puntatore ha una dimensione fissa (valore predefinito 10.000) e può essere pieno. Non è una buona idea quindi PROTEGGERE TUTTO tutto in vista e NON PROTETTERE diverse migliaia di oggetti alla fine. È quasi invariabilmente possibile assegnare gli oggetti come parte di un altro oggetto (che li protegge automaticamente da ) o non proteggerli immediatamente dopo l'uso.

Così PROTECT ora viene rimosso e tutto va bene. (Sembra che il limite dello stack di protezione del puntatore sia stato ridotto a 50.000 da quando è stato scritto quel testo: Defn.h contiene #define R_PPSSIZE 50000L.) Ho controllato tutti gli altri PROTECT nella sorgente C di data.table per qualcosa di simile e trovato e risolto in assegnamento .c anche (quando si aggiungono più di 50.000 colonne per riferimento), nessun altro.

Grazie per aver segnalato!

+0

Testato con un file di 313 righe e 6536299 colonne. 'system.time (geno <-fread ('final.results', sep ='', intestazione = true))' ' sistema dell'utente elapsed' ' 881,321 16,594 923.957' – mpmorley

+0

@mpmorley Grande, grazie per il test. 15 minuti per leggere un file da 12 GB suona bene, forse, dato che è così ampio. Va bene per te? Qualcos'altro lo legge più velocemente? Sarebbe interessante vedere la ripartizione temporale riportata da 'verbose = TRUE'. Ad esempio, se per la maggior parte spende mmap'ing, potrebbero esserci ulteriori opzioni da mettere a punto. –

+0

Per me è accettabile, non sono concentrato a fare qualcosa di utile con tutti questi dati, potrei vedere un nuovo post. Comunque sono contento di correre e pubblicare se tu e altri siete interessati. – mpmorley