【问题标题】:How to avoid 'sink stack is full' error when sink() is used to capture messages in foreach loop使用 sink() 在 foreach 循环中捕获消息时如何避免“sink stack is full”错误
【发布时间】:2014-12-05 10:31:17
【问题描述】:

为了查看在foreach() 循环中运行的函数输出的控制台消息,我遵循this guy 的建议并添加了sink() 调用,如下所示:

   library(foreach)    
   library(doMC)
   cores <- detectCores()
   registerDoMC(cores)

   X <- foreach(i=1:100) %dopar%{
   sink("./out/log.branchpies.txt", append=TRUE)
   cat(paste("\n","Starting iteration",i,"\n"), append=TRUE)
   myFunction(data, argument1="foo", argument2="bar")
   }

但是,在第 77 次迭代中,我收到错误“接收器堆栈已满”。 well-answered questions 在使用 for 循环时避免此错误,但不是 foreach。将原本隐藏的 foreach 输出写入文件的最佳方法是什么?

【问题讨论】:

  • 您实际上是在并行运行吗?你为什么在文件中使用sink cat
  • 我正在使用 foreach 对列表的 100 个元素并行运行相同的计算密集型函数,因为使用 for 循环甚至 mclapply 会花费很长时间(我已经试过了,速度要慢得多)。我使用 sinkcat 是因为链接页面建议我这样做,并且因为它有助于跟踪 foreach 循环正在进行的迭代。
  • 您没有回答问题。您没有展示如何设置集群。此外,您链接到的教程不使用catfile 参数。
  • 如果您正确设置集群,mclapply 不应比 foreach 慢。
  • 抱歉,我实际上并没有在cat 中使用文件参数——这是我正在试验的东西。我打错了代码。我现在就修。

标签: r foreach cat sink


【解决方案1】:

这在我的 Mac 上运行没有错误:

library(foreach)    
library(doMC)
cores <- detectCores()
registerDoMC(cores)

X <- foreach(i=1:100) %dopar%{
  sink("log.branchpies.txt", append=TRUE)
  cat(paste("\n","Starting iteration",i,"\n"))
  sink() #end diversion of output
  rnorm(i*1e4)
}

这样更好:

library(foreach)    
library(doMC)
cores <- detectCores()
registerDoMC(cores)
sink("log.branchpies.txt", append=TRUE)
X <- foreach(i=1:100) %dopar%{
  cat(paste("\n","Starting iteration",i,"\n"))
    rnorm(i*1e4)
}
sink() #end diversion of output

这也有效:

library(foreach)    
library(doMC)
cores <- detectCores()
registerDoMC(cores)

X <- foreach(i=1:100) %dopar%{
  cat(paste("\n","Starting iteration",i,"\n"), 
       file="log.branchpies.txt", append=TRUE)
  rnorm(i*1e4)
}

【讨论】:

  • 谢谢。我的原始代码的问题一定是它没有包含 sink() 来结束输出的转移。
【解决方案2】:

正如this guy 所建议的那样,跟踪接收器堆栈非常棘手。因此,建议使用cat 写入文件的能力,例如上面的答案中建议的:

cat(..., file="log.txt", append=TRUE)

为了节省一些输入,您可以创建一个包装函数,每次调用 cat 时将输出转移到文件:

catf <- function(..., file="log.txt", append=TRUE){
  cat(..., file=file, append=append)
}

所以最后,当你调用foreach 时,你会使用这样的东西:

library(foreach)    
library(doMC)
cores <- detectCores()
registerDoMC(cores)

X <- foreach(i=1:100) %dopar%{
  catf(paste("\n","Starting iteration",i,"\n"))
  rnorm(i*1e4)
}

希望对你有帮助!

【讨论】:

    【解决方案3】:

    在 for 循环中调用一次不带参数的 sink() 以将其重置为在每次迭代结束时结束文件写入,您将不会再次收到此错误。

    【讨论】:

    • 对我不起作用,我怀疑是因为每个工作人员都事先脱离了循环,所以这可能取决于循环到达它。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-11-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-07-28
    相关资源
    最近更新 更多