2011-01-22 178 views
16

我試圖使用的foreach做多核計算在R.不能foreach循環

A <-function(....) { 
    foreach(i=1:10) %dopar% { 
    B() 
    } 
} 

然後調用函數A在控制檯中發現的功能。問題是我打電話Posdef裏面B這是在另一個腳本文件,我來源定義。我必須將Posdef放在foreach.export=c("Posdef")的導出參數列表中。但我得到以下錯誤:

Error in { : task 3 failed - "could not find function "Posdef"" 

爲什麼不能找到這個定義的函數?

+1

我會推薦使用R來搜索關於動態作用域的信息。它根本不是直觀的,你會發現很多關於SO的問題,詳細說明在函數內定義函數時遇到問題的人。 – 2011-01-23 09:21:04

+0

我們將不勝感激一個可重複的例子。另外,你有沒有嘗試過多色的降雪?我發現它更直觀,更容易適應(修改應用功能)。 – 2011-01-23 11:50:33

回答

7

簡短的回答是,這是平行的後端,比如doSNOW錯誤,doParalleldoMPI,但它已被固定。

稍長的答案是foreach使用特殊的「出口」環境向工作人員輸出功能,而不是全球環境。過去這會導致在全局環境中創建的函數出現問題,因爲「導出」環境不在其範圍內,即使它們現在在相同的「導出」環境中定義。因此,他們看不到在「導出」環境中定義的任何其他函數或變量,例如您的案例中的「Posdef」。

doSNOWdoParalleldoMPI後端現在從全球相關的環境切換到「出口」環境,通過「.EXPORT」導出的函數,並且似乎已經解決了這些問題。

11

所以我可以重現此,爲好奇:

require(doSNOW) 
registerDoSNOW(makeCluster(5, type="SOCK")) 
getDoParWorkers() 
getDoParName() 
getDoParVersion() 

fib <- function(n) { 
    if (n <= 1) { return(1) } 
    return(fib(n-1) + fib(n-2)) 
} 

my.matrix <- matrix(runif(2500, 10, 50), nrow=50) 

calcLotsaFibs <- function() { 
    result <- foreach(row.num=1:nrow(my.matrix), .export=c("fib", "my.matrix")) %dopar% { 
    return(Vectorize(fib)(my.matrix[row.num,])) 
    } 
    return(result) 
} 

lotsa.fibs <- calcLotsaFibs() 

我已經能夠通過將在另一個文件中的函數和加載該文件在foreach的身體來解決這個問題。你顯然也可以將函數定義移入foreach本身。

[編輯 - 我以前曾建議,也許.EXPORT不能正常使用功能名稱工作,但低於已得到糾正。]

0

爲用foreach%dopar%的問題快速修復是重新安裝這些程序包:

install.packages("doSNOW") 

install.packages("doParallel") 

install.packages("doMPI") 

它的工作在我的情況。