2013-06-20 14 views
5

Mam kod R, który obejmuje kilku pracowników foreach do wykonywania niektórych zadań równolegle. Używam foreach i doMC w tym celu. Chcę, aby każdy z pracowników foreach rekrutował kilku nowych pracowników i rozpowszechniał niektóre części ich kodu, które można zrównoleglić.Umożliwiaj pracownikom forex rejestrowanie i dystrybucję zadań podrzędnych innym pracownikom.

Obecny kod wygląda następująco:

require(doMC) 
require(foreach) 
registerDoMC(cores = 8) 

foreach (i = (1:8)) %dopar% { 
<<some code here>> 
    for (j in c(1:4)) { 
    <<some other code here>> 
    } 
} 

szukam idealnej kodu, który wyglądałby następująco:

require(doMC) 
require(foreach) 
registerDoMC(cores = 8) 

foreach (i = (1:8)) %dopar% { 
<<some code here>> 
    foreach (j = (1:4)) %dopar% { 
    <<some other code here>> 
    } 
} 

Widziałem przykład multi-paradygmatu równoległości korzystając doSNOW i doMC here (https://www.rmetrics.org/files/Meielisalp2009/Presentations/Lewis.pdf#page=17) . Jednak nie wiem, czy robi to, co chcę, czy nie.

Również wydaje się, że Nested foreach nie ma zastosowania, ponieważ wymaga połączenia dwóch pętli (see here), podczas gdy w moim przypadku nie jest to preferowane; druga pętla pomaga tylko pierwszej części fragmentu kodu. Proszę, popraw mnie jeśli się mylę.

Dzięki.

+0

Może nie dokładnie to, co chcesz, ale możesz mieć zagnieżdżone wyrażenia "foreach": http://cran.r-project.org/web/packages/foreach/vignettes/nested.pdf. Nie wiem jednak o rekrutacji większej liczby robotników w pętlach. – ialm

+0

Dzięki. Jednak wydaje się, że zagnieżdżone foreach nie dotyczy mojego przypadku, ponieważ wymaga scalenia dwóch zagnieżdżonych pętli, podczas gdy potrzebuję wewnętrznej pętli, która jest wywoływana tylko dla części kodu. Zaktualizuję pytanie, aby to odzwierciedlić. – imriss

Odpowiedz

6

Nie ma szczególnego problemu z posiadaniem pętli foreach wewnątrz pętli foreach. Oto przykład z pętlą doMC wewnątrz pętli doSNOW:

library(doSNOW) 
hosts <- c('host-1', 'host-2') 
cl <- makeSOCKcluster(hosts) 
registerDoSNOW(cl) 
r <- foreach(i=1:4, .packages='doMC') %dopar% { 
    registerDoMC(2) 
    foreach(j=1:8, .combine='c') %dopar% { 
    i * j 
    } 
} 
stopCluster(cl) 

Wydaje mi się naturalny używać doMC do pętli wewnętrznej, ale można to zrobić tak chcesz. Możesz także użyć doSNOW dla obu pętli, ale wtedy będziesz musiał stworzyć i zatrzymać klaster śniegu wewnątrz zewnętrznej pętli foreach.

Poniżej przedstawiono przykład zastosowania doMC wewnątrz pętli doMC:

library(doMC) 
registerDoMC(2) 
r <- foreach(i=1:2, .packages='doMC') %dopar% { 
    ppid <- Sys.getpid() 
    registerDoMC(2) 
    foreach(j=1:2) %dopar% { 
    c(ppid, Sys.getpid()) 
    } 
} 

Wyniki pokazują, że w sumie sześć sposobami rozwidlony pakietem doMC, chociaż tylko cztery wykonania ciała pętli wewnętrznej:

> r 
[[1]] 
[[1]][[1]] 
[1] 14946 14949 

[[1]][[2]] 
[1] 14946 14951 


[[2]] 
[[2]][[1]] 
[1] 14947 14948 

[[2]][[2]] 
[1] 14947 14950 

Oczywiście należy uważać, aby nie rozpocząć zbyt wielu procesów w jednym węźle. Ten rodzaj zagnieżdżania był nieco niezręczny, co doprowadziło do rozwoju operatora zagnieżdżania.

+0

Dzięki. Używam MOAB do przesyłania zadań, dlatego nie mogę wybrać nazw hostów. Czy istnieje jakaś najlepsza praktyka ustawiania liczby węzłów i procesorów w żądaniu MOAB w celu uniknięcia koligacji procesorów? Na przykład, w pierwszym przykładzie powyżej, powinienem prosić o węzły = 4; ppn = 8? – imriss

+0

@imriss Czy chcesz użyć klastra MPI lub SOCK? Jeśli MPI, używasz Open MPI lub czegoś innego? Czy używasz Torque jako menedżera zasobów z Moabem? –

+0

Wiersz skryptu msub zaczyna się od #PBS, dlatego uważam, że jest to Torque/Moab. W bieżącym kodzie używam doMC i foreach dla zewnętrznej pętli, podczas gdy wewnętrzna pętla jest szeregowa. Nie mam uprawnień administracyjnych, ale mogę instalować pakiety w moim katalogu domowym. Dzięki. – imriss

Powiązane problemy