我在%dopar%
並行化環境中嵌套多個級別do.call
(各自使用參數中命名的函數,而非硬編碼) ,並且內部函數無法找到來自我的外部環境的函數。我知道關於foreach
上的.export
參數,並且正在使用它,但不知何故,指定的函數並未沿整個鏈傳播。在foreach%dopar%環境中嵌套的do.call找不到使用.export傳遞的函數
我減少了我的問題,下面的測試情況下,不出現此問題:
library(doParallel)
cl <- makeCluster(4)
registerDoParallel(cl)
simple.func <- function(a, b) {
return(a+b)
}
inner.func <- function(a, b) {
return(do.call(simple.func, list(a=a, b=b)))
}
outer.func <- function(a, b, my.func=inner.func) {
return(do.call(my.func, list(a=a, b=b)))
}
main.func <- function(my.list=1:10, my.func=outer.func,
my.args=list(my.func=inner.func)) {
results <- foreach(i=my.list, .multicombine=TRUE, .inorder=FALSE,
.export="simple.func") %dopar% {
return(do.call(my.func, c(list(a=i, b=i+1), my.args)))
}
return(results)
}
而不是給出正確答案(有一些數字的列表),我得到:
Error in { : task 1 failed - "object 'simple.func' not found"
將if (!exists("simple.func")) stop("Could not find parse.data in scope main.func")
添加到每個功能的開始處(根據需要更改示波器的名稱)顯示它是inner.func
哪一個看不到simple.func
- 即使outer.func
確實是看到它。
我還測試了上述幾個變體,main.func
或outer.func
具有硬編碼的下一級功能,而不是從參數中使用它。這兩種變化做工作(例如,給出預期的結果),但是對於真實世界的情況,我想保留將子功能作爲參數的普遍性。
# Variation number one: Replace main.func() with this version
main.func <- function(my.list=1:10, my.func=outer.func,
my.args=list(my.func=inner.func)) {
results <- foreach(i=my.list, .multicombine=TRUE, .inorder=FALSE,
.export=c("simple.func", "outer.func", "inner.func")) %dopar% {
return(do.call(outer.func, list(a=i, b=i+1, my.func=inner.func)))
}
return(results)
}
# Variation number two: Replace outer.func() and main.func() with these versions
outer.func <- function(a, b, my.func=inner.func) {
return(do.call(inner.func, list(a=a, b=b)))
}
main.func <- function(my.list=1:10, my.func=outer.func,
my.args=list(my.func=inner.func)) {
results <- foreach(i=my.list, .multicombine=TRUE, .inorder=FALSE,
.export=c("simple.func", "inner.func")) %dopar% {
return(do.call(my.func, c(list(a=i, b=i+1), my.args)))
}
return(results)
}
我也可以通過simple.func
下來手動鏈條,通過包括它作爲一個額外的參數,但是這看起來額外的凌亂,並且它爲什麼要在必要時simple.func
應該只是沿着與環境的一部分通過?
# Variation number three: Replace inner.func(), outer.func(), and main.func()
# with these versions
inner.func <- function(a, b, innermost.func=simple.func) {
return(do.call(innermost.func, list(a=a, b=b)))
}
outer.func <- function(a, b, my.func=inner.func,
innermost.args=list(innermost.func=simple.func)) {
return(do.call(my.func, c(list(a=a, b=b), innermost.args)))
}
main.func <- function(my.list=1:10, my.func=outer.func,
my.args=list(my.func=inner.func,
innermost.args=list(innermost.func=simple.func))) {
results <- foreach(i=my.list, .multicombine=TRUE, .inorder=FALSE,
.export="simple.func") %dopar% {
return(do.call(my.func, c(list(a=i, b=i+1), my.args)))
}
return(results)
}
有沒有人有較少的問題解決方案的想法,或這個問題的根本原因?
由於您的代碼充滿了它們,所以只需要注意:所有'return'調用都是不必要的。 R自動返回函數中最後一個表達式的值。你只需要'return'來提前離開一個函數。 –