2014-03-28 70 views
1

我正在通過在一臺計算機上運行一臺工作站並在另一臺計算機上運行主服務器來測試doRedis程序包。我的主人的代碼如下所示:運行doRedis-即使已導出對象也不會找到對象

#Register ... 
r <- foreach(a=1:numreps, .export(...)) %dopar% { 
     train <- func1(..) 

     best <- func2(...) 

     weights <- func3(...) 

     return ... 
     } 

在每個函數中,全局變量都被訪問,但沒有被修改。我在foreach循環的.export部分導出了全局變量,但是每當我運行代碼時,都會發生錯誤,指出找不到該變量。有趣的是,當我的所有工作人員都在一臺機器上時,代碼運行正常,但當我有一名「外部」工人時,代碼崩潰。任何想法爲什麼這個錯誤正在發生,以及如何糾正它?

謝謝!

更新:我有一些代碼在這裏一個要點:https://gist.github.com/liangricha/fbf29094474b67333c3b

UPDATE2:我問了另一個doRedis相關的問題:「有沒有可能讓每個工人機可利用其所有核

@Steve Weston迴應說:「每個核心啓動一個Redis工作者往往會充分利用一臺機器。」

+0

我認爲我們需要看到更多的代碼。也許是一個鏈接到一些擴展片段的要點? – hrbrmstr

+0

嗨!對不起,遲到的迴應。我已經在這裏上傳了一份要求:https://gist.github.com/liangricha/fbf29094474b67333c3b。並行化發生在「howmanypulses」函數中,並且「parttable」全局變量的訪問發生在「createdataset」函數中。根據doRedis的日誌,前300個工作正常運行,但是在第一批300之後程序崩潰並且聲明無法找到對象「parttable1」。診斷這個問題的任何幫助將是最有幫助的。非常感謝! –

回答

1

這種類型的代碼在過去是doParallel,doSNOW和doMPI包的問題,​​但它們在最後一年左右來處理它更好。問題是變量被導出爲speci al「出口」環境,而不是地球環境。這在各種方面都是可取的,但這意味着後端必須做更多的工作,以便導出的變量位於導出函數的範圍內。看起來doRedis尚未更新以使用這些改進。

下面是一個簡單的例子,示出了該問題:如果使用doParallel後端

library(doRedis) 
registerDoRedis('jobs') 
startLocalWorkers(3, 'jobs') 
glob <- 6 
f1 <- function() { 
    glob 
} 
f2 <- function() { 
    foreach(1:3, .export=c('f1', 'glob')) %dopar% { 
    f1() 
    } 
} 

f2() # fails with the error: "object 'glob' not found" 

,它成功:

library(doParallel) 
cl <- makePSOCKcluster(3) 
registerDoParallel(cl) 

f2() # works with doParallel 

一個解決方法是,以限定內部的函數「F1」 功能「f2」:

f2 <- function() { 
    f1 <- function() { 
    glob 
    } 
    foreach(1:3, .export=c('glob')) %dopar% { 
    f1() 
    } 
} 

f2() # works with doParallel and doRedis 

另一個解決方案重要的是使用某種機制將變量導出到每個工作人員的全球環境中。使用doParallel或doSNOW,你可以用clusterExport函數來做到這一點,但我不確定如何用doRedis來做到這一點。

我會將此問題報告給doRedis包的作者,並建議他更新doRedis以處理像doParallel這樣的導出函數。

+0

@liangricha每個核心啓動一個redis worker會經常充分利用一臺機器。 –

+0

再次感謝您的幫助!由於一個小的語法錯誤,刪除了我原來的評論,但是更新了我的問題並跟進了。 –

+0

等同於clusterExport()的doRedis是setExport()函數 –

相關問題