10

我喜欢 data.table,它既快速又直观,还有什么更好的呢?data.table唉,这是我的问题:当在循环中引用 a 时foreach()(使用doMC实现),我偶尔会收到以下错误: EXAMPEN IN APPENDIX

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

这里令人讨厌的问题之一是我无法让它以任何一致性重现,但它会在一些长时间(几个小时)的任务中发生,所以我想确保它永远不会发生,如果可能的话。

由于我在每个循环中都引用了相同的data.table, DT,因此我尝试在每个循环的开头运行以下命令:

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

...删除无效/损坏的 self ref 属性。这有效,内部 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())
4

3 回答 3

4

感谢您的报告和寻找它的所有帮助!现在在 v1.8.11 中修复。来自新闻

在多次重复调用 data.table 的长时间运行计算中,有时会出现以下错误,#2647:已
Internal error: .internal.selfref prot is not itself an extptr
修复。感谢 EricStone、StevieP 和 JasonB 提供的(困难的)可重现示例。

可能相关的是分组中的内存泄漏,现在也已修复。

固定分组中长期未解决(通常很小)的内存泄漏,#2648。当最后一组小于最大组时,这些大小的差异不会被释放。同样在非平凡的聚合中,每个组返回不同数量的行。大多数用户运行一次分组查询并且永远不会注意到这些,但是任何循环调用分组的人(例如并行运行或基准测试时)都可能会受到影响。添加了测试。多亏了许多,包括 vc273 和 Y
T。data.table 中的内存泄漏通过引用分组分配
当返回 j 中的命名列表时,data.table 中的内存泄漏缓慢(试图重塑 data.table)

于 2014-01-02T19:07:42.283 回答
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”修复。

希望这会有所帮助,谢谢,杰森

这是对似乎每运行 50-100k 次就会产生 1 次错误的代码段之一的简化​​:

谢谢@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
于 2013-03-24T16:35:59.650 回答
1

为了重现错误,我有一个脚本供你们倾倒并找出这个错误来自哪里。错误内容如下:

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

我正在使用doParallelforeach.

背景:我正在 MNIST 手写数字数据集上测试分类器。您可以通过以下方式从我这里获取数据

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

只需确保修改脚本(上图),使其正确指向load_data.R并且 load_data.R 正确指向 MNIST 数据——尽管克隆我的 repo 可能更容易,跳上 random_gov 分支,然后运行 ​​dt_centric_random_gov.R。

抱歉,我无法制作一个更简单的可重现示例,但就像@JasonB 的回答一样,在您进行大量计算之前,这个错误似乎不会出现。

编辑:我使用上面建议的解决方法重新运行了我的脚本,它似乎顺利进行。

于 2013-12-19T20:06:35.603 回答