IT TIP

% dopar %를 사용할 때 어떻게 인쇄 할 수 있습니까?

itqueen 2020. 11. 27. 21:53
반응형

% dopar %를 사용할 때 어떻게 인쇄 할 수 있습니까?


with 를 백엔드로 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)
    }   

여기에 많은 좋은 솔루션이 게시되어 있지만 소켓에 로그하고 별도의 프로세스를 사용하여 콘솔에서 로그 호출을 출력하는 것이 가장 쉬운 방법입니다.

다음 기능을 사용합니다.

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

이 방법은 원격으로 작업 할 수있는 장점이 있으며 기록하려는만큼 자세한 출력을 제공합니다.

ps Windows 사용자는 Jon Craton의 netcat 포트를 참조하십시오 .

조달청은 내가 추측하고있어 write.socket당신은 높은 주파수에있어 로깅, 당신이 어떤 문제로 실행 가능성이 아니라면 R 기능이 아마 스레드로부터 안전하지 않습니다,하지만. 그래도 알아야 할 것.


스노우 워커가 생성 한 출력은 기본적으로 버려지지만 makeCluster "outfile"옵션을 사용하여 변경할 수 있습니다. outfile을 빈 문자열 ( "")로 설정하면 눈이 출력을 리디렉션하는 것을 방지하여 종종 마스터 프로세스의 터미널에 표시되는 인쇄 메시지의 출력이 나타납니다.

다음과 같이 클러스터를 만들고 등록하기 만하면됩니다.

library(doSNOW)
cl <- makeCluster(4, outfile="")
registerDoSNOW(cl)

foreach 루프는 전혀 변경할 필요가 없습니다.

이것은 Open MPI로 빌드 된 Rmpi를 사용하는 SOCK 클러스터와 MPI 클러스터 모두에서 작동합니다. Windows에서 Rgui를 사용하는 경우 출력이 표시되지 않습니다. 대신 Rterm.exe를 사용하면됩니다.

자신의 출력 이외에도 유용 할 수있는 눈으로 생성 된 메시지를 볼 수 있습니다.


진행률 표시 줄을 사용하려면 doSNOW 버전 1.0.14에 progress옵션이 있습니다. 다음은 완전한 예입니다.

library(doSNOW)
library(tcltk)
library(randomForest)
cl <- makeSOCKcluster(3)
registerDoSNOW(cl)

ntasks <- 100
pb <- tkProgressBar(max=ntasks)
progress <- function(n) setTkProgressBar(pb, n)
opts <- list(progress=progress)

x <- matrix(runif(500), 100)
y <- gl(2, 50)

rf <- foreach(ntree=rep(25, ntasks), .combine=combine,
        .multicombine=TRUE, .packages='randomForest',
        .options.snow=opts) %dopar% {
  randomForest(x, y, ntree=ntree)
}

progress옵션은 매우 일반적이므로 다음과 같은 기능을 사용하여 간단히 메시지를 인쇄 할 수 있습니다.

progress <- function(n) cat(sprintf("task %d is complete\n", n))

이 함수는 0, 1 또는 2 개의 인수를 사용할 수 있습니다. 제공된 첫 번째 인수는 완료된 작업의 총 수이고 두 번째는 방금 완료된 작업의 작업 번호입니다.

가장 간단한 예제 .는 작업이 완료 될 때 간단히 인쇄합니다 .

progress <- function() cat('.')

This example displays both arguments and can be used to demonstrate that tasks aren't always completed in order:

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

A way I've kept track of progress on nodes during long operations is to create a progress bar using tkProgressBar from the tcltk package. It's not quite what you asked for, but it should let you see something from the nodes. At least it does when the cluster is a socket cluster running on the local host (which is a Windows machine). The potential problem is that the progress bar either remains and clutters your monitor or it gets closed and the printed info is gone. For me, that wasn't a problem, though, since I just wanted to know what the current status was.

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

Using your code,

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
    }

Here's a more general use example:

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
}

I had the same issue too. I was tuning parameters for random forest using foreach package and wanted to print a "Results" line after each iteration, but couldn't figure out without going through displaying a progress bar and such.

Here's what I did, In my function, I added this line

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

So after every iteration, the results are written to a text file with names such as RF_ntree_250_dims_100.txt.

So if I want to keep track of the progress I just refresh the folder to which the text files are being written to.

PS: the results are being accumulated in a data frame too.


cat("blah-blah-blah\n", file=stdout()) tends to work for me (linux/emacs/ess). I guess it also works for some other platforms.


An alternative is to use file logging (for instance, log4r package) and separately print the output on the screen (for instance, by 'tail -f').

This works well if you consider creating logs anyway, and you can use the existing packages with all the related bells and whistles.

참고URL : https://stackoverflow.com/questions/10903787/how-can-i-print-when-using-dopar

반응형