2012-05-24 4 views
5

R의 병렬 패키지에서 작동하도록 일부 코드를 가져 오는 데 문제가 있습니다. R 2.15를 사용하고 있습니다.R 병렬 S4 클래스 클러스터 오류

가 여기에 파일 다음이 들어 'animal.R'을 가지고 ... 간단한 예입니다 : 내 R 단자에,

# animal.R 
setClass("Animal", representation(species = "character", legs = "numeric")) 

##Define some Animal methods 
setGeneric("count",function(x) standardGeneric("count")) 
setMethod("count", "Animal", function(x) { [email protected]}) 

setGeneric("countAfterChopping",function(x) standardGeneric("countAfterChopping")) 
setMethod("countAfterChopping", "Animal", function(x) { [email protected] <- [email protected]; [email protected]}) 

그럼, 실행

library(parallel) 
source('animal.R') 

시작 두 노드의 로컬 클러스터 :

cl <- makeCluster(rep('localhost', 2)) 

동물 클래스에 대한 클러스터 노드 알려주기 :

# This works 
parSapply(cl, list(daisy, fred), count) 

# This doesn't... 
parSapply(cl, list(daisy, fred), countAfterChopping) 

정지 클러스터 :

clusterEvalQ(cl, parse('animal.R')) 

그런 다음 클러스터의 일부 코드 실행

stopCluster(cl) 

parSapply에 대한 첫 번째 호출이 예상 작품으로,하지만 두 번째는이 오류가 발생합니다 :

Error in checkForRemoteErrors(val) : 
    2 nodes produced errors; first error: "Animal" is not a defined class 

아이디어가 있습니까? parSapply에 대한 두 번째 호출이 작동하지 않는 이유는 무엇입니까?

+0

'clusterEvalQ (CL, 평가 (구문 분석 ('animal.R는 ')))'또는 스크립트를 소스로 사용하십시오. 그게 속임수 였어? – BenBarnes

+0

아, 그래 ... 그 트릭을하는 것 같습니다. 매우 감사합니다! – Ash

답변

3

그래서 여기에 무슨 일이 일어나고 있는지의 : 클래스 "동물"의 S4 개체에 대한

count 기능은 단순히 legs 슬롯을 추출합니다. 이것이 전부라면 클러스터 노드에서 animal.R 파일을 평가하거나 소스 할 필요가 없습니다. 필요한 모든 정보는 parSapply에 전달됩니다.

그러나 countAfterChopping 함수는 legs 슬롯에 새 값을 할당하며 여기에서 재미가 시작됩니다. 슬롯 할당 기능 `@<-`에는 `slot<-`에 대한 호출이 포함되어 있는데, 인수는 check = TRUE입니다. 이 함수는 checkSlotAssignment 함수의 평가를 트리거합니다.이 함수는 "제공된 값이이 슬롯에 허용됩니다."(?checkSlotAssignment에서) 클래스 정의를 참조합니다.

따라서 이러한 방식으로 슬롯에 할당 할 때 클래스 정의를 알고 있어야하며 S4 클래스 "동물"은 클러스터 노드에서 알 수 없습니다. 따라서 파싱 된 파일 animal.R을 평가하거나 소싱하는 것이 좋습니다. 그러나 각 노드에서 파일의 첫 번째 줄 (예 : 클래스 "동물")을 평가하면됩니다.

여기 축소, 재현 예 : 당신이 사용할 수 중 하나는`animal.R parse`, 당신이 평가되지 않은 표현을 얻을 때, 그래서

animal.R<-" 
    setClass('Animal', representation(species = 'character', legs = 'numeric')) 

    ##Define some Animal methods 
    setGeneric('count',function(x) standardGeneric('count')) 
    setMethod('count', signature(x='Animal'), function(x) { [email protected]}) 

    setGeneric('countAfterChopping',function(x) standardGeneric('countAfterChopping')) 
    setMethod('countAfterChopping', signature(x='Animal'), 
    function(x) { [email protected] <- [email protected]; [email protected]}) 
" 
library(parallel) 

source(textConnection(animal.R)) 

cl <- makeCluster(rep('localhost', 2)) 

daisy<-new("Animal",legs=2,species="H.sapiens") 
fred<-new("Animal",legs=4,species="C.lupus") 

parSapply(cl, list(daisy, fred), count) 
# [1] 2 4 

clusterExport(cl,"animal.R") # 
clusterEvalQ(cl,eval(parse(textConnection(animal.R),n=1))) 

parSapply(cl, list(daisy, fred), countAfterChopping) 
# [1] 1 3 
+0

예, 도움이되었습니다. – Ash

관련 문제