Ash*_*Ash 5 parallel-processing r s4
我在使用R中的并行包获取一些代码时遇到问题.我正在使用R 2.15.
这是一个简化的例子......我有一个'animal.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) { x@legs})
setGeneric("countAfterChopping",function(x) standardGeneric("countAfterChopping"))
setMethod("countAfterChopping", "Animal", function(x) { x@legs <- x@legs-1; x@legs})
Run Code Online (Sandbox Code Playgroud)
然后,在我的R终端中,我运行:
library(parallel)
source('animal.R')
Run Code Online (Sandbox Code Playgroud)
启动两个节点的本地群集:
cl <- makeCluster(rep('localhost', 2))
Run Code Online (Sandbox Code Playgroud)
告诉群集节点有关Animal类的信息:
clusterEvalQ(cl, parse('animal.R'))
Run Code Online (Sandbox Code Playgroud)
然后在集群上运行一些代码:
# This works
parSapply(cl, list(daisy, fred), count)
# This doesn't...
parSapply(cl, list(daisy, fred), countAfterChopping)
Run Code Online (Sandbox Code Playgroud)
停止群集:
stopCluster(cl)
Run Code Online (Sandbox Code Playgroud)
对parSapply的第一次调用按预期工作,但第二次调用会产生此错误:
Error in checkForRemoteErrors(val) :
2 nodes produced errors; first error: "Animal" is not a defined class
Run Code Online (Sandbox Code Playgroud)
有什么想法发生了什么?为什么第二次调用parSapply不起作用?
所以这是发生了什么事:
对于“Animal”类的 S4 对象,该count函数只是提取legs槽。如果这就是您所做的全部,则无需animal.R在集群节点上评估或获取该文件。所有必要的信息都会被传递parSapply。
然而,该countAfterChopping函数为槽分配了一个新值legs,这就是乐趣的开始。槽分配函数包含对参数的`@<-`调用。这会触发函数的评估,该函数通过查阅类的定义来检查“所提供的值是否允许用于此插槽”(来自)。`slot<-`check = TRUEcheckSlotAssignment?checkSlotAssignment
因此,以这种方式分配给槽时必须知道类定义,并且 S4 类“Animal”在集群节点上是未知的。这就是评估解析文件animal.R或获取它的工作原理的原因。但是,您只需评估文件的第一行即可,即在每个节点上定义类“Animal”。
这是一个简化的、可重现的示例:
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) { x@legs})
setGeneric('countAfterChopping',function(x) standardGeneric('countAfterChopping'))
setMethod('countAfterChopping', signature(x='Animal'),
function(x) { x@legs <- x@legs-1; x@legs})
"
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
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5646 次 |
| 最近记录: |