首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >doParallel工人的产出

doParallel工人的产出
EN

Stack Overflow用户
提问于 2015-09-01 14:55:45
回答 1查看 1.7K关注 0票数 1

假设我有一个代码在foreach循环中执行各种计算,为了简单起见,让它如下所示:

代码语言:javascript
复制
foreach( idx = 1:10 ) %dopar% {
   set.seed(idx)
   smp <- rnorm(10)
   print( sprintf('Index: %d', idx) )
   print( cat(sprintf('Value: %f \n', smp[1:10])) )
}

代码的主要思想是,它的输出是这样写的,索引只显示一次,然后遵循主代码的各种结果。然后,在使用%do%时,很容易读取日志文件并使用这种结构进行调试,但是使用%dopar%,日志文件会变得杂乱无章。

问:在不改变代码的情况下,是否有办法让每个员工创建自己的输出文件?我刚开始使用doParallel,所以到目前为止我发现的并行输出的唯一方法是使用以下方法:

代码语言:javascript
复制
library(doParallel)
cl <- makeCluster(4, outfile = 'log.txt')
registerDoParallel(cl)

但是,outfile只使用一个字符串作为参数,还没有找到将名称向量传递给它的方法。那么,也许有一种方法可以为每个员工指定一个输出文件?

注:在Windows 7上工作。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-09-02 07:14:56

许多解决方案--比如在工作人员中不使用print或在那里指定输出文件--都会浮现出来,但问题是明确要求不更改代码。因此,我假设当前在%dopar%主体中的代码包装在一个不能更改的函数中:

代码语言:javascript
复制
doNotTouch <- function(idx) {
  set.seed(idx)
  smp <- rnorm(10)
  print(sprintf('Index: %d', idx))
  cat(sprintf('Value: %f \n', smp[1:10]))
}

一种解决方案是在调用doNotTouch之前直接指定输出文件(或者更准确地说:在将输出重定向到特定文件的环境中执行函数):

代码语言:javascript
复制
library(doParallel)
cl <- makeCluster(4)
registerDoParallel(cl)


foreach(idx = 1:10) %dopar% {
  capture.output(
    doNotTouch(idx), 
    file = paste0("log", idx, ".txt"))
}

stopCluster(cl)

这不会改变问题中提供的代码,而是将其放在一个包装器中,该包装器负责处理正确的输出文件log_[idx].txt

编辑:在评论中,澄清了问题不是写到单独的文件上,而是关于获得不杂乱无章的输出。在这种情况下,可以在循环中使用return(capture.output(doNotTouch(idx)))来收集属于一起的输出并立即返回它们。此外,@Nutle发现,Sys.getpid()返回一个工人的PID,该PID可用于由工作人员编写单独的日志文件(正如迭代所反对的那样)。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/32334866

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档