2013-03-11 2 views
9

Мне нравится data.table, это быстро и интуитивно понятно, что может быть лучше? Увы, вот моя проблема: когда речь идет о data.table в foreach() цикле (с использованием doMC реализации) я иногда получаю следующее сообщение об ошибке: Пример В ПРИЛОЖЕНИИПолучение случайной внутренней ошибки selfref в data.table для R

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

Одной из раздражающих проблем здесь что я не могу заставить его воспроизводить с любой согласованностью, но это произойдет в течение некоторых длительных (несколько часов) задач, поэтому я хочу убедиться, что это никогда не произойдет, если это возможно.

Поскольку я имею в виду то же, data.tableDT, в каждом цикле, я попытался запустить следующую строку в начале каждого цикла:

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

... удалить недопустимый/поврежденную собственного атрибута реф. Это работает, и внутренняя ошибка selfref больше не возникает. Однако это обходное решение.

Любые идеи для решения проблемы с корнем?

Большое спасибо за помощь!

Эрик

Приложение: Сокращенный R Информация Сессия подтверждающими последние версии:

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 

Пример с использованием смоделированного данных - вы, возможно, придется запустить history() функцию много раз (как, сотни), чтобы получить ошибка:

##~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
## 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

Вы можете вставить здесь свою реализацию цикла foreach (даже если она не может воспроизвести проблему, как вы говорите)? – Arun

+0

Повторная попытка обхода, хорошая идея, но это 'setattr' не' setattrib'. Для правильного решения Арун на месте, он не должен быть надежно воспроизводимым, но если вы вставляете код, мы можем, вероятно, стресс проверить его правильно, чтобы он потерпел неудачу. –

+1

И я вижу, что 'doMC' был обновлен до 1.3.0 22 февраля, а data.table до 1.8.8 на 6 марта. Пожалуйста, убедитесь, что вы предоставили номера версий всего, что вы используете спереди, например. 'SessionInfo()'. –

ответ

2

Подобная проблема преследовала меня в течение нескольких месяцев. Возможно, мы можем увидеть образец, объединив наш опыт.

Я ждал сообщения, пока не смогу создать воспроизводимый пример. Пока невозможно. Ошибка в том же кодовом месте. Раньше я часто избегал ошибок, просто повторяя тот же самый код. В других случаях я переформулировал выражение и повторил успех. В любом случае я уверен, что эти ошибки действительно являются внутренними по отношению к data.table.

Я сохранил последние 4 сообщения об ошибках, пытаясь обнаружить шаблон (вставленный ниже).

--------------------------------------------------- 
[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 

Еще одно сходство с приведенным выше примером: я передаю data.tables вокруг среди параллельных потоков, поэтому они сериализации/сериализации.

Я попробую исправление 'setattr', упомянутое выше.

надеюсь, что это помогает, и спасибо, Джейсону

здесь является упрощение одного из сегментов кода, которые, кажется, чтобы генерировать эту ошибку 1 из каждых 50-100k раз он запускается:

благодаря @MatthewDowle кстати. data.table была наиболее полезной.Вот один урезанная бит кода:

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])) 

} 

что-то вроде этого, кажется, причина этой ошибки:

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

Очень интересно. Не отчаивайтесь, удалив свой первый ответ! Я думаю, что алмазный мод удалил его по техническим причинам, так как вы написали, что это не ответ, возможно. В любом случае, я получил его. Спасибо за эту информацию! –

+0

Я могу начать делать некоторые догадки с этой информацией. Но вы не должны давать воспроизводимый пример.В подобных случаях вы можете предоставить столько кода, сколько сможете. Тогда мы можем проверить его оттуда. Мне просто нужен по крайней мере скелет кода, который похож на ваш. Это не обязательно должно быть аварийно завершено. –

+0

Если вы пишите, пожалуйста, убедитесь, что вы начали комментарии с @MatthewDowle, иначе я вряд ли увижу это. –

1

Ради воспроизведения ошибки, у меня есть script для вас, ребята налить и выяснить, откуда эта ошибка. Ошибка гласит:

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 

и я использую doParallel зарегистрировать свой бэкенд для foreach.

Контекст: Я тестирую классификаторы в наборе данных с рукописными цифрами MNIST. Вы можете получить данные от меня через

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

только убедитесь, что изменить сценарий (выше), чтобы он правильно указывает на load_data.R и load_data.R правильно указывает на данные MNIST - хотя это может быть проще вы просто клонируете мое репо, прыгаете на ветку random_gov, а затем запустите dt_centric_random_gov.R.

Извините, я не мог сделать более минимальный воспроизводимый пример, но, как и ответ @ JasonB, эта ошибка, похоже, не всплывает, пока вы не выполните тонну вычислений.

Редактировать: Я перезапустил свой сценарий, используя предложенный выше рабочий ход, и он, казалось, ушел без сучка и задоринки.

+0

Спасибо. Он работает. Сколько времени потребуется, прежде чем он сработает с этой ошибкой? –

+0

Потребовалось несколько часов, используя 8 ядер на кластере. Я не уверен, сколько времени потребуется, чтобы поймать на одном ядре ... – StevieP

+0

Исправлено. См. Отдельный ответ от меня. Спасибо за вашу помощь! –

4

Благодарим за сообщение и всю помощь в его поиске! Теперь исправлено в v1.8.11. От 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.

Возможно, связанная утечка памяти в группировке, которая теперь также фиксируется.

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)