2012-06-05 12 views
41

Mam pętlę foreach, która używa %dopar% z doSNOW jako back-end. W jaki sposób mogę wydrukować coś z każdej iteracji?Jak mogę drukować, gdy używam% dopar%

Mój kod poniżej jest tym, czego aktualnie używam, ale nie drukuje niczego.

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) 
    } 
+2

ah, ale to jest drukowanie, po prostu nie na głównym węźle ... –

+0

oh, okay. W takim razie czy istnieje sposób, w jaki mogę zobaczyć, co jest drukowane lub czy jest drukowane do węzła głównego? – someoneHuman

+0

Nie znam żadnych i nie jestem pewien, jak można to zrobić. –

Odpowiedz

19

Istnieje wiele dobrych rozwiązań opublikowanych tutaj, ale najłatwiej jest zalogować się do gniazda i użyć osobnego procesu do wyprowadzenia wywołań dziennika w konsoli.

używam następującą funkcję:

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) 
} 

Następnie można umieszczać oświadczenia w kodzie takich jak log:

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

wyjście Log można oglądać w czasie rzeczywistym przy użyciu dowolnego prostego narzędzia gniazdo nasłuchuje . Na przykład za pomocą netcata w systemie Linux:

nc -l 4000 

Powyższe oświadczenie dziennika wyświetli w terminalu netcat jak:

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

Metoda ta ma tę zaletę, pracy zdalnej i stanowi szczegółowe wyjścia, jak ci zależy zalogować.

p.s. Dla użytkowników systemu Windows, zobacz Jon Craton's netcat port.

p.p.s Zgaduję funkcja write.socket R prawdopodobnie nie jest bezpieczny wątku, ale jeśli nie jesteś zalogowaniu przy wysokiej częstotliwości, jesteś mało prawdopodobne, aby uruchomić w każdej kwestii. Coś, o czym trzeba pamiętać.

+0

Musisz uruchomić 'nc -l 4000' w terminalu linux * przed * wykonaniem' log.sock = make.socket (port = 4000) 'w' R' – horaceT

12

Droga ja śledził postępy w węzłach podczas długich operacji jest stworzenie pasek postępu przy użyciu tkProgressBar z pakietu tcltk. Nie jest to dokładnie to, o co prosiłeś, ale powinno pozwolić ci zobaczyć coś z węzłów. Przynajmniej działa, gdy klaster jest klastrem gniazd działającym na hoście lokalnym (który jest komputerem z systemem Windows). Potencjalny problem polega na tym, że pasek postępu albo pozostaje i zaśmieca twój monitor, albo dostanie się close d, a drukowane informacje zniknęły. Dla mnie to nie był problem, ponieważ chciałem tylko wiedzieć, jaki jest obecny status.

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

Używając kodu,

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 
    } 

Oto bardziej ogólny przykład zastosowanie:

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 
} 
+0

Witam, próbowałem użyć paska postępu, ale nie mogę sprawić, by działał on równolegle w pętlach. Za każdym razem, gdy go uruchamiam, pojawia się "XIO: fatalny błąd IO". Jak sobie z tym poradzić? @BenBarnes – TAllieri

+0

@traieri, zobacz zaktualizowany przykład (oryginalny przykład nie był bardzo ilustracyjny). Jeśli nadal masz problemy, proszę podać więcej informacji i rozważyć zadanie nowego pytania. – BenBarnes

10

miałem ten sam problem zbyt. Stworzyłem parametry dla losowego lasu przy użyciu pakietu foreach i chciałem wydrukować wiersz "Wyniki" po każdej iteracji, ale nie mogłem się zorientować bez przechodzenia przez pasek postępu i takie.

Oto co zrobiłem, W mojej funkcji, Dodałem tę linię

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

Więc po każdej iteracji, wyniki zapisywane są do pliku tekstowego z nazwami takimi jak RF_ntree_250_dims_100.txt.

Więc jeśli chcę śledzić postęp, po prostu odświeżam folder, do którego zapisywane są pliki tekstowe.

PS: wyniki są również gromadzone w ramce danych.

41

Dane wyjściowe produkowane przez pracowników śniegu są domyślnie odrzucane, ale można użyć opcji "outfile" makeCluster, aby to zmienić. Ustawienie pliku wyjściowego na pusty ciąg znaków ("") zapobiegnie przekierowaniu śniegu na wyjście, co często spowoduje, że dane wyjściowe z twoich komunikatów drukowania pojawią się na terminalu procesu głównego.

Wystarczy utworzyć i zarejestrować klastra z czymś takim:

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

pętla foreach nie trzeba wcale zmieniać.

Działa to dla mnie z obu klastrów SOCK i klastrów MPI za pomocą Rmpi ​​zbudowany z Open MPI. W systemie Windows nie zobaczysz żadnych danych wyjściowych, jeśli używasz Rgui. Jeśli użyjesz programu Rterm.exe, zrobisz to.

Pamiętaj, że oprócz własnych wyników zobaczysz wiadomości wyprodukowane przez śnieg, które również mogą być przydatne.


Aby użyć paska postępu, doSNOW wersja 1.0.14 posiada opcję progress. Powyżej znajduje się pełna przykład:

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) 
} 

Opcja progress jest dość ogólny, więc można po prostu wydrukować wiadomość przy użyciu funkcji takich jak:

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

Funkcja może mieć 0, 1 lub 2 argumenty. Pierwszy dostarczony argument to całkowita liczba zakończonych zadań, a drugi to numer zadania, które właśnie się zakończyło.

Najprostszym przykładem prostu drukuje . gdy zadanie kończy:

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

Ten przykład pokazuje oba argumenty i może być stosowane do wykazania, że ​​zadania nie zawsze są zakończone w kolejności:

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

Czy istnieją równoważne rozwiązania do kierowania wyjścia komunikatów drukowania do konsoli za pomocą 'doMC'? –

+0

@MattSM W przypadku doMC dane wyjściowe z robotników są domyślnie wyświetlane na konsoli podczas korzystania z standardowego R. Podczas uruchamiania RStudio mogą wystąpić problemy, ale nie sądzę, że zalecana jest instrukcja DoMC podczas korzystania z RStudio z powodu problemów z rozwidleniem. Ponadto, doMC nie obsługuje paska postępu z powodu ograniczeń w pakiecie równoległym. –

+0

@SteveWeston Podoba mi się rozwiązanie paska postępu. Ale są chwile, kiedy chcę zobaczyć fragmenty wyniku w każdej iteracji. Czy istnieje sposób na zrobienie odpowiednika kota ("wynik w iter i")? – horaceT

0

Alternatywą jest użycie rejestrowania plików (na przykład, pakiet log4r) i osobne wydrukowanie danych wyjściowych na ekranie (na przykład "tail-f").

Działa to dobrze, jeśli weźmiesz pod uwagę tworzenie dzienników i możesz używać istniejących pakietów z wszystkimi powiązanymi dzwonkami i gwizdkami.

+0

Jakieś pojęcie o tym, co jest hitem na wydajność? to znaczy. dodatkowy czas przetwarzania w pliku IO. – horaceT

+0

Nie. Ale możesz to przetestować. Używałem tego tylko do stosunkowo powolnych zadań. –

1

cat("blah-blah-blah\n", file=stdout()) ma tendencję do pracy dla mnie (linux/emacs/ess). Sądzę, że działa również na niektórych innych platformach.

Powiązane problemy