2013-02-06 14 views
44

Sto tentando di eseguire del codice ricorsivo abbastanza profonda nella R e continua a darmi questo errore:Errore: C utilizzo stack è troppo vicino al limite

Error: C stack usage is too close to the limit

La mia uscita da CStack_info() è:

Cstack_info() 
    size current direction eval_depth 
67108864  8120   1   2 

ho un sacco di memoria sulla mia macchina, io sto solo cercando di capire come posso aumentare la CStack per R.

EDIT: qualcuno ha chiesto per esempio riproducibile. Ecco alcuni codici di esempio di base che causano il problema. Eseguendo f (1,1) un paio di volte otterrai l'errore. Tieni presente che ho già impostato --max-ppsize = 500000 e opzioni (espressioni = 500000), quindi se non li imposti potresti ottenere un errore su una di queste due cose. Come puoi vedere, la ricorsione può andare piuttosto in profondità qui e non ho idea di come farlo funzionare in modo coerente. Grazie.

f <- function(root=1,lambda=1) { 
    x <- c(0,1); 
    prob <- c(1/(lambda+1),lambda/(lambda+1)); 
     repeat { 
     if(root == 0) { 
     break; 
     } 
     else { 
     child <- sample(x,2,replace=TRUE,prob); 
     if(child[1] == 0 && child[2] == 0) { 
      break; 
     } 
     if(child[1] == 1) { 
      child[1] <- f(root=child[1],lambda); 
     } 
     if(child[2] == 1 && child[1] == 0) { 
      child[2] <- f(root=child[2],lambda); 
     } 
     } 
     if(child[1] == 0 && child[2] == 0) { 
     break; 
     } 
     if(child[1] == 1 || child[2] == 1) { 
     root <- sample(x,1,replace=TRUE,prob); 
     } 
     } 
    return(root) 
} 
+0

Questo [domanda] (http://stackoverflow.com/q/8997198/1385941) suggerisce forse 'opzioni (espressioni = somethinglarge) ' – mnel

+0

@mnel L'altezza di annidamento delle espressioni, lo stack di protezione del puntatore e lo stack di C sono tre cose distinte (ma correlate). – zwol

+0

Grazie mille per la tua pronta risposta, Zack. Penso che la tua risposta potrebbe essere per un sistema operativo Linux? Al momento sto eseguendo Windows 7 a 64 bit, questo cambia le cose? Grazie ancora per qualsiasi aiuto. – user2045093

risposta

39

La dimensione dello stack è un parametro del sistema operativo, regolabile per processo (vedi setrlimit(2)). Non è possibile regolarlo da R per quanto posso dire, ma è possibile regolarlo dalla shell prima di avviare R, con il comando ulimit. Funziona così:

$ ulimit -s # print default 
8192 
$ R --slave -e 'Cstack_info()["size"]' 
    size 
8388608 

8388608 = 1024 * 8192; R sta stampando lo stesso valore di ulimit -s, ma in byte invece di kilobyte.

$ ulimit -s 16384 # enlarge stack limit to 16 megs 
$ R --slave -e 'Cstack_info()["size"]' 
    size 
16777216 
+9

... o semplicemente impostarlo su 'unlimited'. –

+1

Il [pacchetto '' RAppArmor'] (https://cran.r-project.org/web/packages/RAppArmor/index.html) offre un'interfaccia per 'setrlimit (2)'. Questa funzionalità potrebbe essere disponibile nel pacchetto 'ulimit' ad un certo punto. – krlmlr

+0

Questa funzione non esiste più nel pacchetto ** RAppArmor **. Qualche idea dove è andata? – Deleet

12

Ho il sospetto che, a prescindere dal limite dello stack, vi ritroverete con ricorsioni che sono troppo profonde. Ad esempio, con lambda = Inf, f (1) porta a una ricorsione immediata, indefinitamente. La profondità della ricorsione sembra essere una passeggiata casuale, con alcune probabilità di andare più in profondità, 1 - r di finire la ricorsione corrente. Quando hai raggiunto il limite di stack, hai eseguito un numero elevato di passaggi "più profondi". Ciò implica che r> 1/2 e la stragrande maggioranza del tempo continuerai a recitare.

Inoltre, sembra che è quasi possibile ricavare un analitico o soluzione meno numerica anche a fronte di ricorsione infinita. Si può definire p come la probabilità che f (1) == 1, scrivere le espressioni implicite per gli stati "figli" dopo una singola iterazione ed equare queste con p e risolvere. p può quindi essere usato come la possibilità di successo in una sola estrazione da una distribuzione binomiale.

+0

qui è in realtà la risposta corretta nascosta - assicurati di non ottenere quella profondità nella ricusazione ... –

4

Questo mi è successo per una ragione completamente diversa. Ho creato accidentalmente una stringa superlong combinando due colonne:

output_table_subset = mutate(big_data_frame, 
    combined_table = paste0(first_part, second_part, col = "_")) 

invece di

output_table_subset = mutate(big_data_frame, 
    combined_table = paste0(first_part, second_part, sep = "_")) 

Mi ha portato per sempre per capirlo, come mi sarei mai aspettato la pasta per aver causato il problema.

+0

Stessa cosa qui, ma stavo facendo un riassunto. Mi è piaciuto così: 'riepilogare ( states = paste0 (state, collapse = ',') )'. Quando avrei dovuto fare qualcosa di simile: 'riepilogare ( states = paste0 (sort (unique (stato)), collapse = ',') )'. L'obiettivo era ottenere un elenco separato da virgole di stati univoci disponibili per ciascun sottogruppo. –

0

Come Martin Morgan ha scritto ... Il problema è che si ottiene troppo in profondità all'interno della ricorsione. Se la ricorsione non converge affatto, devi romperla da sola. Spero che questo codice funzioni, perché non è testato. Comunque almeno il punto dovrebbe essere chiaro qui.

f <- function(root=1,lambda=1,depth=1) { 
if(depth > 256){ 
    return(NA) 
} 
x <- c(0,1); 
prob <- c(1/(lambda+1),lambda/(lambda+1)); 
repeat { 
    if(root == 0) { 
    break; 
    } else { 
    child <- sample(x,2,replace=TRUE,prob); 
    if(child[1] == 0 && child[2] == 0) { 
    break; 
    } 
    if(child[1] == 1) { 
    child[1] <- f(root=child[1],lambda,depth+1); 
    } 
    if(child[2] == 1 && child[1] == 0) { 
    child[2] <- f(root=child[2],lambda,depth+1); 
    } 
    } 
    if(child[1] == NA | child[2] == NA){ 
    return NA; 
    } 
    if(child[1] == 0 && child[2] == 0) { 
    break; 
    } 
    if(child[1] == 1 || child[2] == 1) { 
    root <- sample(x,1,replace=TRUE,prob); 
    } 
} 
return(root) 
} 
1

ho incontrato lo stesso problema di ricevere il "utilizzo C pila è troppo vicino al limite" errore (anche se per un'altra applicazione di quella dichiarata dal user2045093 sopra).Ho provato la proposta di zwol ma non ha funzionato.

Con mia sorpresa, ho potuto risolvere il problema installando la versione più recente di R per OS X (attualmente: versione 3.2.3) e la versione più recente di R Studio per OS X (attualmente: 0.99.840), dal momento che sto lavorando con R Studio.

Speriamo che questo possa essere di aiuto anche a voi.

0

Un problema qui può essere che si sta chiamando f suo interno

plop <- function(a = 2){ 
    pouet <- sample(a) 
    plop(pouet) 
} 
plop() 
Erreur : évaluations trop profondément imbriquées : récursion infinie/options(expressions=) ? 
Erreur pendant l'emballage (wrapup) : évaluations trop profondément imbriquées : récursion infinie/options(expressions=) ? 
Problemi correlati