DEoptim error: objective function result has different length than parameter matrix due to foreachArgs specification

DEoptim error: objective function result has different length than parameter matrix due to foreachArgs specification

我有一个非常奇怪的 DEoptim 错误,我有 "fixed",但不明白。

当我将 DEoptim 的并行功能与 parallel 包(即 pType=1)一起使用时,我没有遇到任何问题。但是,当我改用 foreach 时(我必须在可用的网格计算设置上使用它),我遇到了问题。下面是我遇到的问题的简化版本的 MRE。 pType=1 有效,pType=2 当指定 foreachArgs 时 returns 错误:

objective function result has different length than parameter matrix

当我没有指定 foreachArgs 时,问题就消失了。有人想过这个问题的根本原因吗?

library(zoo)
library(parallel)
library(doParallel)
library(DEoptim)


myfunc1 <- function(params){
    s <- myfunc2(params,ncal,n_left_cens,astats, X_ret, disc_length, X_acq, POP_0, POP_ann_growth)
    loss_func(s)
    }

myfunc2 = function(params,ncal,n_left_cens,astats, X_ret, disc_length, X_acq, POP_0, POP_ann_growth){
    sum(params) + ncal + n_left_cens + astats + X_ret + disc_length + X_acq + POP_0 + POP_ann_growth 
    }

loss_func = function(s){
    s
    }   


# General setup
ncal = 1
n_left_cens = 1
astats= 1
disc_length = 1
POP_0 = 1
POP_ann_growth = 1
X_acq = 1
X_ret = 1
params = c(1,1)
W = 1

paral = TRUE
itermax=100
ncores = detectCores()
cltype <- ifelse(.Platform$OS.type != "windows", "FORK", "PSOCK")
trace=TRUE

# bounds for search for DEoptim
lower = rep(-1,length(params))
upper = lower*-1




# parallel: works               
pType = 1
parVar = c("myfunc1","myfunc2","loss_func","W","ncal","n_left_cens","astats","X_ret","disc_length",
                        "X_acq","POP_0","POP_ann_growth")               
foreachArguments <- list("myfunc1","myfunc2","loss_func","ncal","n_left_cens","astats","X_ret","disc_length",
                        "X_acq","POP_0","POP_ann_growth")
clusters <- makeCluster(ncores, type = cltype)
registerDoParallel(clusters)
clusterExport(cl=clusters, varlist=foreachArguments, envir=environment())
results <- DEoptim(fn=myfunc1,lower=lower,upper=upper,
                DEoptim.control(itermax=itermax,trace=trace,parallelType=pType,
                parVar=parVar))
showConnections(all = TRUE)
closeAllConnections()





# foreach with foreachArgs specified: doesn't work
pType = 2               
clusters <- makeCluster(ncores, type = cltype)
registerDoParallel(clusters)
clusterExport(cl=clusters, varlist=foreachArguments, envir=environment())

results <- DEoptim(fn=myfunc1,lower=lower,upper=upper,
                DEoptim.control(itermax=itermax,trace=trace,parallelType=pType,
                foreachArgs=foreachArguments))
showConnections(all = TRUE)
closeAllConnections()





# foreach with foreachArgs unspecified: works
pType = 2               
foreachArguments <- list("myfunc1","myfunc2","loss_func","ncal","n_left_cens","astats","X_ret","disc_length",
                        "X_acq","POP_0","POP_ann_growth")
clusters <- makeCluster(ncores, type = cltype)
registerDoParallel(clusters)
clusterExport(cl=clusters, varlist=foreachArguments, envir=environment())

results <- DEoptim(fn=myfunc1,lower=lower,upper=upper,
                DEoptim.control(itermax=itermax,trace=trace,parallelType=pType))
showConnections(all = TRUE)
closeAllConnections()

来自?DEoptim.control

foreachArgs: A list of named arguments for the ‘foreach’ function from the package ‘foreach’. The arguments ‘i’, ‘.combine’ and ‘.export’ are not possible to set here; they are set internally.

您似乎将其与 parVar 的行为混为一谈:

parVar: Used if ‘parallelType=1’; a list of variable names (as strings) that need to exist in the environment for use by the objective function or are used as arguments by the objective function.

您需要将传递给 foreach 的参数指定为 name = value 对。例如:

foreachArguments <- list(.export = c("myfunc1", "myfunc2", "loss_func", "ncal",
 "n_left_cens", "astats", "X_ret", "disc_length", "X_acq","POP_0","POP_ann_growth")

我不确定是什么导致了该特定错误,但解决方法是 "don't do that." ;)

这是一个实际使用 foreachArgs 参数的示例。请注意,我正在设置 .verbose 参数以进行 foreach 打印诊断:

library(doParallel)
library(DEoptim)
clusters <- makeCluster(detectCores())
registerDoParallel(clusters)
obj_func <- function(params) { sum(params) }
results <- DEoptim(fn=obj_func, lower=c(-1, -1), upper=c(1, 1),
  DEoptim.control(parallelType=2, foreachArgs=list(.verbose=TRUE)))
stopCluster(clusters)