使用%dopar%时如何打印

使用%dopar%时如何打印,r,foreach,parallel-processing,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

我有一个
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)
    }   

在长时间操作期间,我跟踪节点进度的一种方法是使用
tcltk
包中的
tkProgressBar
创建进度条。这并不是你想要的,但它应该让你从节点上看到一些东西。至少当群集是在本地主机(即Windows计算机)上运行的套接字群集时是这样。潜在的问题是,进度条要么保留下来,弄乱了显示器,要么关闭,打印的信息消失了。但对我来说,这不是问题,因为我只是想知道目前的状况

library(parallel)
library(doSNOW)
cl<-makeCluster(detectCores(),type="SOCK")
registerDoSNOW(cl)
库(并行)
图书馆(doSNOW)

cl我也有同样的问题。我正在使用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:结果也在一个数据帧中累积。

默认情况下,雪工生成的输出会被丢弃,但您可以使用makeCluster“outfile”选项来更改它。将outfile设置为空字符串(“”)将防止snow重定向输出,通常会导致打印消息的输出显示在主进程的终端上

只需创建集群并注册如下内容:

library(doSNOW)
cl <- makeCluster(4, outfile="")
registerDoSNOW(cl)
progress
选项相当通用,因此您可以使用以下功能简单地打印消息:

progress <- function(n) cat(sprintf("task %d is complete\n", n))
此示例显示这两个参数,可用于演示任务并非总是按顺序完成:

progress <- function(nfin, tag) {
  cat(sprintf('tasks completed: %d; tag: %d\n', nfin, tag))
}

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

我使用以下功能:

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)
}
可以使用任何简单的套接字侦听工具实时查看日志输出。例如,在Linux上使用netcat:

nc -l 4000
上述日志语句将在netcat终端中显示为:

2014-06-25 12:30:45: Processing block 2 of 13
这种方法的优点是可以远程工作,并提供您想要记录的详细输出

p、 有关Windows上的,请参阅


p、 另外,我猜
write.socket
R函数可能不是线程安全的,但是除非您以高频率登录,否则不太可能遇到任何问题。但是需要注意的是。

另一种方法是使用文件日志记录(例如,log4r包)并在屏幕上单独打印输出(例如,通过“tail-f”)


如果你考虑创建日志,这很好,你可以使用现有的包和所有相关的铃声和哨子。

<代码> CAT(“BLAH BLAH BLAH\N”,文件= STDUT())倾向于为我工作(Linux /Emacs/ESS)。我想它也适用于其他一些平台。

啊,但它正在打印,只是不在主节点上……哦,好的。在这种情况下,是否有一种方法可以查看它打印的内容或让它打印到主节点?我不知道任何方法,也不知道如何执行。是否可以编写一个迭代器函数打印到控制台?迭代器应该由主机运行,不是吗?@NoamRoss是的,迭代器只在主机上运行,所以它可以写入控制台。这将允许您监视发送给工人的任务,而不是工人实际执行任务的时间。每次运行它,我都会得到“XIO:fatal IO error”。你怎么处理这件事@BenBarnes@TAllieri,请参阅更新的示例(原始示例不是很好地说明问题)。如果您仍然有问题,请提供更多的信息,并考虑问一个新的问题。是否有一个等效的解决方案来指导打印消息的输出到控制台的代码> DOMC/<代码>?默认情况下,使用standard R时,workers的输出显示在控制台上。使用RStudio时可能会遇到问题,但我认为在使用RStudio时,由于分叉问题,不建议使用doMC。另外,由于并行包中的限制,doMC不支持进度条。@SteveWeston我喜欢进度条解决方案。但有时我希望在每次迭代中看到结果的片段。有什么方法可以实现cat(“iter i的结果”)的等效功能吗?@horaceT如果您正在使用并行后端动态调用combine函数(如doSNOW或doMPI),那么您可以轻松显示combine函数的结果片段。但是请记住,除非您第一次降低
.maxcombine
@SteveWeston的值,否则每100次结果都会调用combine函数:当我搜索
.options.snow
时,我绝对看不到任何文档,除了您的这个SO线程。你能解释一下引擎盖下面发生了什么吗。
progress
从哪里获得
n
?你知道性能的影响是什么吗?即文件IO.No中的额外处理时间。但是你可以测试它。我只在相对较慢的任务中使用过它。在执行
R
中的
log.sock=make.socket(port=4000)
之前,需要在linux终端中运行
nc-l 4000
,但当您有10个不同的进程时,如何正确地记录它们?为每个R进程建立nc服务器和R套接字?或者干脆把R插座插进去
progress <- function(nfin, tag) {
  cat(sprintf('tasks completed: %d; tag: %d\n', nfin, tag))
}
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)
nc -l 4000
2014-06-25 12:30:45: Processing block 2 of 13