5

为了查看foreach()循环中运行的函数输出的控制台消息,我遵循了这个人的建议并添加了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 次迭代中,我收到错误“接收器堆栈已满”。在使用 for 循环而不是 foreach 时,关于避免此错误的问题得到了很好的回答。将原本隐藏的 foreach 输出写入文件的最佳方法是什么?

4

4 回答 4

7

这在我的 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)
}
于 2014-10-10T17:08:42.747 回答
4

正如这个家伙所建议的那样,跟踪水槽堆栈非常棘手。因此,建议使用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)
}

希望能帮助到你!

于 2015-12-13T18:41:22.403 回答
0

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

于 2016-07-07T09:30:04.983 回答
0

不幸的是,上述方法都不适合我:sink()foreach()-loop 中,它并没有停止抛出“sink stack is full” -错误。在sink()循环之外,文件被创建,但从未更新。

对我来说,创建日志文件以跟踪并行foreach()循环的进度的最简单方法是应用良好的旧write.table()功能。

    library(foreach)
    library(doParallel)

    availableClusters <- makeCluster(detectCores() - 1) #use all cpu-threads but one (i.e. one is reserved for the OS)
    registerDoParallel(availableClusters) #register the available cores for the parallisation

    x <- foreach (i = 1 to 100) %dopar% {
           log.text <- paste0(Sys.time(), " processing loop run ", i, "/100")
           write.table(log.text, "loop-log.txt", append = TRUE, row.names = FALSE, col.names = FALSE)

           #your statements here
    }

并且不要忘记(就像我多次做过的那样......)append = TRUEwrite.table().

于 2022-03-01T18:07:38.400 回答