2011-07-14 7 views
18

Wywołanie funkcję zawiera foreach% dopar% skonstruować z Optim powoduje błąd:R - błąd foreach% dopar% W zależności wywoływana przez optim

> workers <- startWorkers(6) # 6 cores 
> 
> registerDoSMP(workers) 
> 
> t0 <- Sys.time() 
> 
> optim(w,maxProb2,control=list(fnscale=-1)) 
> 
> Error in { : task 1 failed - "unused argument(s) (isPrebuilt = TRUE)" 
> 
> Sys.time()-t0 
> 
> Time difference of 2.032 secs 
> 
> stopWorkers(workers) 

Wywołana funkcja wygląda tak:

> maxProb2 <- function(wp) { 
> 
> r <- foreach (i=s0:s1, .combine=c) %dopar% { pf(i,x[i,5],wp,isPrebuilt=TRUE) } 
> 
> cat("w=",wp,"max=",sum(r),"\n") 
> 
> sum(r) 
> 
> } 

pf to inna funkcja, x jest statyczną tabelą wstępnie obliczonych elementów.

także wywołanie funkcji zostać zoptymalizowane tylko raz powoduje ten sam błąd:

> workers <- startWorkers(6) # 6 cores 
> 
> Warning message: 
> In startWorkers(6) : there is an existing doSMP session using doSMP1 
> 
> registerDoSMP(workers) 
> 
> maxProb2(w) 
> Error in { : task 1 failed - "unused argument(s) (isPrebuilt = TRUE)" 
> 
> stopWorkers(workers) 

Co dziwne, identyczny kod działa poprawnie, gdy wywołana bezpośrednio jeden raz (optim calles tę samą funkcję wiele razy):

> workers <- startWorkers(6) # 6 - ilosc rdzeni 
> 
> Warning message: 
> In startWorkers(6) : there is an existing doSMP session using doSMP1 
> 
> registerDoSMP(workers) 
> 
> r <- foreach (i=s0:s1, .combine=c) %dopar% { pf(i,x[i,5],w,isPrebuilt=TRUE) } 
> 
> sum(r) 
> [1] 187.1781 
> 
> stopWorkers(workers) 

Funkcja nazwana (maxProb2) działa poprawnie, gdy% do% jest używane zamiast% doparu%.

Jak poprawnie wywołać funkcję, w tym foreach% dopar% konstrukcji?

UPDATE 2011-07-17:

Mam przemianowany funkcję pf w probf ale problem pozostaje.

funkcje probf zdefiniowane są w skrypcie, a nie w jakimś zewnętrznym pakiecie.

Dwie uwagi: System operacyjny: Windows 7, IDE: Revolution Analytics Enterprise 4,3

> workers <- startWorkers(workerCount = 3) 
> 
> registerDoSMP(workers) 
> 
> maxProb2(w) 
> 
Error in { : task 1 failed - "could not find function "probf"" 
+0

Proszę zawsze podać dokładny komunikat o błędzie w pytaniu. –

Odpowiedz

2

[[edited]]

Twój pf funkcja a "static stół" x muszą być dystrybuowane do wszystkich pracownika węzły. Musisz przeczytać dokumentację twojej równoległej biblioteki, jak to działa.

Wygląda na to, że po uruchomieniu optymalizacji funkcja pf stwierdza, że ​​jest inna (prawdopodobnie stats::pf, która nie ma argumentu isPrebuilt).

Czy możesz spróbować zmienić nazwę swojej funkcji pf (na przykład na mypf)?

mypf <- pf # renaming the function 

maxProb2 <- function(wp) { 
    r <- foreach (i=s0:s1, .combine=c) %dopar% { mypf(i,x[i,5],wp,isPrebuilt=TRUE) } 
    cat("w=",wp,"max=",sum(r),"\n") 
    sum(r) 
} 

Lub, jeśli funkcja pf jest częścią pakietu z nazw (powiedzmy, mypackage), można odwoływać się do niej tak: mypackage::pf

maxProb2 <- function(wp) { 
    r <- foreach (i=s0:s1, .combine=c) %dopar% { mypackage::pf(i,x[i,5],wp,isPrebuilt=TRUE) } 
    cat("w=",wp,"max=",sum(r),"\n") 
    sum(r) 
} 
+0

W jaki sposób należy się upewnić, że wywoływana funkcja i tabela są dystrybuowane do węzłów roboczych? – mjaniec

+1

'pf' istnieje w wbudowanym pakiecie' stats' i jest funkcją dystrybucji dla dystrybucji F. – James

+0

Zaktualizowałem odpowiedź, ponieważ wydaje mi się, że podejrzewam, że została wywołana niewłaściwa funkcja "pf". – Tommy

18

wpadłem na ten sam problem AN Problem polega na tym, że środowisko nie jest zawarte w podtytułach.Twój błąd

Error in { : task 1 failed - "could not find function "simple_fn""

może być powielana przez to bardzo prosty przykład:

simple_fn <- function(x) 
    x+1 

test_par <- function(){ 
    library("parallel") 
    no_cores <- detectCores() 
    library("foreach") 
    cl<-makeCluster(no_cores) 
    library("doSNOW") 
    registerDoSNOW(cl) 
    out <- foreach(i=1:10) %dopar% { 
     simple_fn(i) 
    } 

    stopCluster(cl) 
    return(out) 
} 

test_par() 

Teraz wszystko, co trzeba, aby to zmienić foreach(i=1:10) do foreach(i=1:10, .export=c("simple_fn")). Jeśli chcesz wyeksportować swoje pełne środowisko globalne, po prostu napisz .export=ls(envir=globalenv()), a otrzymasz je na lepsze lub na gorsze.

+1

Zawsze zastanawiałem się, dlaczego '.export = ls()' nie jest domyślne. W większości sytuacji wydaje się to dobrym pomysłem, sądząc po liczbie postów na ten temat ... Jakiś pomysł? – Ruben

+1

@Ruben - rzeczywiście ma to sens, ponieważ równoległość jest najbardziej istotna przy pracy z dużymi zestawami danych –

+1

Ale wtedy załadowałbyś porcje danych indywidualnie w każdym węźle, prawda? Wówczas nie załadowałbym całego df w sesji globalnej. Niektóre rzeczy są automatycznie ładowane (np. Wektory, które przeglądasz). Co więcej, używanie ls nie działa tak, jak się spodziewałem właśnie teraz. Jedynym rozwiązaniem, w którym niezawodnie uzyskam to, co przewiduję, jest zdefiniowanie wewnątrz pętli. Nieefektywne, czasem brzydkie. – Ruben

0

Szybka poprawka dla problemu z foreach% dopar% jest ponownie zainstalować te pakiety:

install.packages("doSNOW") 

install.packages("doParallel") 

install.packages("doMPI") 

Jak wspomniano w różnych wątków na StackOverflow, są odpowiedzialne za równoległości w R. Bug, która istniała w starych wersjach nich pakiety są teraz usuwane. Działało w moim przypadku. Powinienem wspomnieć, że najprawdopodobniej pomoże to, nawet jeśli nie używasz tych pakietów w projekcie/paczce.

Powiązane problemy