使用%dopar%时如何打印

时间:2012-06-05 19:38:39

标签: r foreach parallel-processing

我有foreach循环使用%dopar%并以doSNOW作为后端。如何在每次迭代中打印循环?

下面的代码是我目前使用的代码,但它不会打印任何内容。

foreach(ntree=rep(25,2),.combine=combine,.packages='randomForest',
    .inorder=FALSE) %dopar% {
        print("RANDOM FOREST")
        randomForest(classForm,data=data,na.action=na.action,do.trace=do.trace,ntree=ntree,mtry=mtry)
    }   

5 个答案:

答案 0 :(得分:23)

这里发布了许多好的解决方案,但我发现最简单的方法是登录套接字并使用单独的进程在控制台中输出日志调用。

我使用以下功能:

log.socket <- make.socket(port=4000)

Log <- function(text, ...) {
  msg <- sprintf(paste0(as.character(Sys.time()), ": ", text, "\n"), ...)
  cat(msg)
  write.socket(log.socket, msg)
}

然后,您可以将日志语句放在代码中,例如:

Log("Processing block %d of %d", i, n.blocks)

可以使用任何简单的套接字侦听工具实时查看日志输出。例如,在Linux上使用netcat:

nc -l 4000

以上日志语句将在netcat终端中显示为:

2014-06-25 12:30:45: Processing block 2 of 13

此方法具有远程工作的优点,并提供您需要记录的详细输出。

p.s。对于Windows上的用户,请参阅Jon Craton's netcat port

pps 我猜测write.socket R函数可能不是线程安全的,但除非您以高频率进行日志记录,否则您需要&#39 ;不太可能遇到任何问题。但要注意的事情。

答案 1 :(得分:12)

我在长时间操作期间跟踪节点进度的方法是使用tkProgressBar包中的tcltk创建进度条。它不是你要求的,但它应该让你从节点中看到一些东西。至少它是在集群是在本地主机(即Windows机器)上运行的套接字集群时执行的。潜在的问题是,进度条会保持不变并使显示器变得杂乱,或者显示close d并且打印的信息消失了。对我来说,这不是一个问题,因为我只是想知道现状是什么。

library(parallel)
library(doSNOW)
cl<-makeCluster(detectCores(),type="SOCK")
registerDoSNOW(cl)

使用您的代码,

foreach(ntree=rep(25,2),.combine=combine,.packages=c('randomForest','tcltk'),
    .inorder=FALSE) %dopar% {
        mypb <- tkProgressBar(title = "R progress bar", label = "",
          min = 0, max = 1, initial = 0, width = 300)
        setTkProgressBar(mypb, 1, title = "RANDOM FOREST", label = NULL)
    ans <- randomForest(classForm,data=data,na.action=na.action,do.trace=do.trace,ntree=ntree,mtry=mtry)
    close(mypb)
    ans
    }

以下是一个更通用的示例:

jSeq <- seq_len(30)

foreach(i = seq_len(2), .packages = c('tcltk', 'foreach')) %dopar% {
    mypb <- tkProgressBar(title = "R progress bar", label = "",
        min = 0, max = max(jSeq), initial = 0, width = 300)
    foreach(j = jSeq) %do% {
        Sys.sleep(.1)
        setTkProgressBar(mypb, j, title = "RANDOM FOREST", label = NULL)
    }
    NULL
}

答案 2 :(得分:11)

我也有同样的问题。我正在使用foreach包调整随机森林的参数,并希望在每次迭代后打印“结果”行,但如果不经过显示进度条等就无法弄清楚。

这就是我做的, 在我的功能中, 我添加了这一行

write.table(result, file=paste("RF_ntree_",ntree,"_dims_",dims,".txt", sep=""),
  sep="\t", row.names=F)

因此,在每次迭代后,结果都会写入一个文本文件,其名称为RF_ntree_250_dims_100.txt。

因此,如果我想跟踪进度,我只需刷新正在写入文本文件的文件夹。

PS:结果也在数据框中累积。

答案 3 :(得分:2)

cat("blah-blah-blah\n", file=stdout())倾向于为我工作(linux / emacs / ess)。我想它也适用于其他一些平台。

答案 4 :(得分:0)

另一种方法是使用文件记录(例如,log4r包)并在屏幕上单独打印输出(例如,通过&#39; tail -f&#39;)。

如果您考虑创建日志,这很有效,并且您可以使用现有的包以及所有相关的铃声和口哨声。