2013-03-11 15 views
9

Amo data.table, è veloce e intuitivo, cosa potrebbe essere migliore? Ahimè, ecco il mio problema: quando si parla di un data.table all'interno di un ciclo foreach() (usando l'implementazione doMC) io a volte il seguente errore: ESEMPIO IN APPENDICEOttenere un errore selfref interno casuale in data.table per R

Error in { : 
    Internal error: .internal.selfref prot is not itself an extptr 

Uno dei fastidiosi problemi qui è che non riesco a riprodurlo con una certa coerenza, ma accadrà durante alcune lunghe (molte ore) attività, quindi voglio assicurarmi che non accada mai, se possibile.

Dal momento che si riferiscono allo stesso data.table, DT, in ogni ciclo, ho provato a fare funzionare il seguente all'inizio di ogni ciclo:

setattr(DT,".internal.selfref",NULL) 

... per rimuovere l'attributo non valido/corrotto auto rif. Funziona e l'errore selfref interno non si verifica più. È una soluzione, però.

Qualche idea per affrontare il problema di root?

Molte grazie per qualsiasi aiuto!

Eric

Appendice: R abbreviate Info Sessione per confermare le versioni più recenti:

R version 2.15.3 (2013-03-01) 
Platform: x86_64-apple-darwin9.8.0/x86_64 (64-bit) 
other attached packages: 
[1] data.table_1.8.8 doMC_1.3.0 

esempio utilizzando dati simulati - potrebbe essere necessario eseguire i history() funzione molte volte (come, centinaia) per ottenere l'errore:

##~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
## Load packages and Prepare Data 
##~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
require(data.table) 
##this is the package we use for multicore 
require(doMC) 
##register n-2 of your machine's cores 
registerDoMC(multicore:::detectCores()-2) 

## Build simulated data 
value.a <- runif(500,0,1) 
value.b <- 1-value.a 
value <- c(value.a,value.b) 
answer.opt <- c(rep("a",500),rep("b",500)) 
answer.id <- rep(6000:6499 , 2) 
question.id <- rep(sample(c(1001,1010,1041,1121,1124),500,replace=TRUE) ,2) 
date <- rep((Sys.Date() - sample.int(150, size=500, replace=TRUE)) , 2) 
user.id <- rep(sample(250:350, size=500, replace=TRUE) ,2) 
condition <- substr(as.character(user.id),1,1) 
condition[which(condition=="2")] <- "x" 
condition[which(condition=="3")] <- "y" 

##Put everything in a data.table 
DT.full <- data.table(user.id = user.id, 
         answer.opt = answer.opt, 
         question.id = question.id, 
         date = date, 
         answer.id = answer.id, 
         condition = condition, 
         value = value) 

##~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
## Daily Aggregation Function 
## 
##a basic function that aggregates all the values from 
##all users for every question on a given day: 
##~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
each.day <- function(val.date){ 
    DT <- DT.full[ date < val.date ] 

    #count the number of updates per user (for weighting) 
    setkey(DT, question.id, user.id) 
    DT <- DT[ DT[answer.opt=="a",length(value),by="question.id,user.id"] ] 
    setnames(DT, "V1", "freq") 

    #retain only the most recent value from each user on each question 
    setkey(DT, question.id, user.id, answer.id) 
    DT <- DT[ DT[ ,answer.id == max(answer.id), by="question.id,user.id", ][[3]] ] 

    #now get a weighted mean (with freq) of the value for each question 
    records <- lapply(unique(DT$question.id), function(q.id) { 
    DT <- DT[ question.id == q.id ] 
    probs <- DT[ ,weighted.mean(value,freq), by="answer.opt" ] 
    return(data.table(q.id = rep(q.id,nrow(probs)), 
         ans.opt = probs$answer.opt, 
         date = rep(val.date,nrow(probs)), 
         value = probs$V1)) 
    }) 
    return(do.call("rbind",records)) 
} 

##~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
## foreach History Function 
## 
##to aggregate accross many days quickly 
##~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
history <- function(start, end){ 
    #define a sequence of dates 
    date.seq <- seq(as.Date(start),as.Date(end),by="day") 

    #now run a foreach to get the history for each date 
    hist <- foreach(day = date.seq, .combine = "rbind") %dopar% { 
    #setattr(DT,".internal.selfref",NULL) #resolves occasional internal selfref error 
    each.day(val.date = day) 
    } 
} 

##~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
## Examples 
##~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 

##aggregate only one day 
each.day(val.date = "2012-12-13") 

##generate a history 
hist.example <- history (start = "2012-11-01", end = Sys.Date()) 
+1

puoi incollare qui l'implementazione del ciclo foreach (anche se potrebbe non riprodurre il problema come dici tu?)? – Arun

+0

Re il tentativo di soluzione, buona idea, ma è 'setattr' non' setattrib'. Per la soluzione corretta Arun è azzeccata, non ha bisogno di essere riproducibile in modo affidabile, ma se si incolla il codice possiamo probabilmente stressarlo nel modo giusto per farlo fallire. –

+1

E vedo 'doMC' è stato aggiornato a 1.3.0 il 22 febbraio e data.table a 1.8.8 il 6 marzo. Assicurati di fornire i numeri di versione di tutto ciò che stai utilizzando in anticipo, ad es. 'SessionInfo()'. –

risposta

2

Un problema simile è stato mi affliggono da mesi. Forse possiamo vedere uno schema mettendo insieme le nostre esperienze.

Ho aspettato di postare fino a quando non sono riuscito a creare un esempio riproducibile. Non è possibile fino ad ora. Il bug non si verifica nello stesso percorso del codice. In passato sono stato in grado di evitare spesso l'errore semplicemente ripetendo esattamente lo stesso codice. Altre volte ho riformulato un'espressione e rieseguito con successo. In ogni caso sono abbastanza sicuro che questi errori siano veramente interni a data.table.

Ho salvato gli ultimi 4 messaggi di errore nel tentativo di rilevare un modello (incollato di seguito).

--------------------------------------------------- 
[1] "err msg: location 1" 
Error in selfrefok(x) : 
    Internal error: .internal.selfref prot is not itself an extptr 
Calls: my.fun1 ... $<- -> $<-.data.table -> [<-.data.table -> selfrefok 
Execution halted 


--------------------------------------------------- 
[1] "err msg: location 1" 
Error in alloc.col(newx) : 
    Internal error: .internal.selfref prot is not itself an extptr 
Calls: my.fun1 -> $<- -> $<-.data.table -> copy -> alloc.col 
Execution halted 


--------------------------------------------------- 
[1] "err msg: location 2" 
Error in shallow(x) : 
    Internal error: .internal.selfref prot is not itself an extptr 
Calls: print ... do.call -> lapply -> as.list -> as.list.data.table -> shallow 
Execution halted 

--------------------------------------------------- 
[1] "err msg: location 3" 
Error in shallow(x) : 
    Internal error: .internal.selfref prot is not itself an extptr 
Calls: calc.book.summ ... .rbind.data.table -> as.list -> as.list.data.table -> shallow 
Execution halted 

Un'altra somiglianza all'esempio precedente: sto passando data.tables giro tra fili paralleli, in modo che vengono serializzati/deserializzato.

Proverò la correzione 'setattr' di cui sopra.

speranza che questo aiuta e grazie, jason

qui è una semplificazione di uno dei segmenti di codice che sembra generare questo errore 1 su ogni 50-100k volte è gestito:

grazie @MatthewDowle btw. data.table è stato molto utile.Ecco una ridotta porzione di codice:

require(data.table) 
require(xts) 

book <- data.frame(name='', 
        s=0, 
        Value=0.0, 
        x=0.0, 
        Qty=0)[0, ] 

for (thing in list(1,2,3,4,5)) { 

    tmp <- xts(1:5, order.by= make.index.unique(rep(Sys.time(), 5))) 
    colnames(tmp) <- 'A' 
    tmp <- cbind(coredata(tmp[nrow(tmp), 'A']), 
       coredata(colSums(tmp[, 'A'])), 
       coredata(tmp[nrow(tmp), 'A'])) 

    book <- rbind(book, 
       data.table(name='ALPHA', 
          s=0*NA, 
          Value=tmp[1], 
          x=tmp[2], 
          Qty=tmp[3])) 

} 

qualcosa di simile sembra essere la causa di questo errore:

Error in shallow(x) : 
    Internal error: .internal.selfref prot is not itself an extptr 
Calls: my.function ... .rbind.data.table -> as.list -> as.list.data.table -> shallow 
Execution halted 
+0

Molto interessante. Non scoraggiarti se la tua prima risposta viene cancellata! Penso che il mod diamante lo abbia cancellato da un punto di vista tecnico, dal momento che hai scritto che non era una risposta, forse. Ad ogni modo l'ho cancellato. Grazie per queste informazioni! –

+0

Posso iniziare a fare alcune ipotesi con queste informazioni. Ma non dovete fornire un esempio riproducibile.In casi come questo, puoi semplicemente fornire più codice che puoi. Quindi possiamo stressare provarlo da lì. Ho solo bisogno di almeno uno scheletro di codice che funzioni come il tuo. Non ha bisogno di arrestarsi in modo affidabile. –

+0

Se si risponde, assicurarsi di iniziare i commenti con @MatthewDowle altrimenti è improbabile che lo veda. –

1

Per il bene di riprodurre l'errore, ho un script per voi ragazzi riversarsi e capire da dove proviene questo bug. L'errore si legge:

Error in { : 
task 96 failed - "Internal error: .internal.selfref prot is not itself an extptr" 
Calls: apply ... system.time -> apply -> FUN -> %dopar% -> <Anonymous> 
Execution halted 

e sto usando doParallel a registrare il mio backend per foreach.

Contesto: sto testando le classificazioni sul set di dati numerati a mano di MNIST. È possibile ottenere i dati da me via

wget -nc https://www.dropbox.com/s/xr4i8gy11ed8bsh/digit_id_data_and_benchmarks.zip 

basta essere sicuri di modificare lo script (sopra) in modo che punti correttamente per load_data.R e load_data.R sottolinea giustamente ai dati MNIST - anche se può essere più facile per basta clonare il mio repository, saltare sul ramo random_gov e quindi eseguire dt_centric_random_gov.R.

Spiacente, non sono riuscito a creare un esempio riproducibile più minimale, ma come la risposta di @ JasonB, questo errore sembra non comparire finché non si eseguono molti calcoli.

modifica: Ho rielaborato la mia sceneggiatura utilizzando l'aggettivo suggerito sopra e sembrava partire senza intoppi.

+0

Grazie. Sta funzionando. Quanto tempo ci vuole prima che fallisca con quell'errore? –

+0

Sono occorse diverse ore, utilizzando 8 core su un cluster. Non sono sicuro di quanto tempo ci vorrebbe per catturare un singolo core ... – StevieP

+0

Risolto il problema ora. Vedi una risposta separata da me. Grazie per l'aiuto! –

4

Grazie per la segnalazione e tutto l'aiuto nel trovarlo! Ora risolto in v1.8.11. Da NEWS:

In long running computations where data.table is called many times repetitively, the following error could sometimes occur, #2647 :
Internal error: .internal.selfref prot is not itself an extptr
Fixed. Thanks to theEricStone, StevieP and JasonB for (difficult) reproducible examples.

eventualmente collegate è una perdita di memoria nel gruppo, che è anche ora risolto.

Long outstanding (usually small) memory leak in grouping fixed, #2648. When the last group is smaller than the largest group, the difference in those sizes was not being released. Also in non-trivial aggregations where each group returns a different number of rows. Most users run a grouping query once and will never have noticed these, but anyone looping calls to grouping (such as when running in parallel, or benchmarking) may have suffered. Tests added. Thanks to many including vc273 and Y T.
Memory leak in data.table grouped assignment by reference
Slow memory leak in data.table when returning named lists in j (trying to reshape a data.table)