R - проблема с функцией foreach% dopar% внутри функции, называемой оптимизацией
Вызов функции, включающей foreach% dopar% construct from optim, вызывает ошибку:
> workers <- startWorkers(6) # 6 cores
>
> registerDoSMP(workers)
>
> t0 <- Sys.time()
>
> optim(w,maxProb2,control=list(fnscale=-1))
>
> Error in { : task 1 failed - "unused argument(s) (isPrebuilt = TRUE)"
>
> Sys.time()-t0
>
> Time difference of 2.032 secs
>
> stopWorkers(workers)
Вызываемая функция выглядит так:
> maxProb2 <- function(wp) {
>
> r <- foreach (i=s0:s1, .combine=c) %dopar% { pf(i,x[i,5],wp,isPrebuilt=TRUE) }
>
> cat("w=",wp,"max=",sum(r),"\n")
>
> sum(r)
>
> }
pf - некоторая другая функция, x - статическая таблица предварительно вычисленных элементов.
Также вызов функции, которую нужно оптимизировать только один раз, вызывает ту же ошибку:
> workers <- startWorkers(6) # 6 cores
>
> Warning message:
> In startWorkers(6) : there is an existing doSMP session using doSMP1
>
> registerDoSMP(workers)
>
> maxProb2(w)
> Error in { : task 1 failed - "unused argument(s) (isPrebuilt = TRUE)"
>
> stopWorkers(workers)
Что странно, идентичный код работает нормально, когда вызывается непосредственно за один раз (оптимизация вызывает одну и ту же функцию много раз):
> workers <- startWorkers(6) # 6 - ilosc rdzeni
>
> Warning message:
> In startWorkers(6) : there is an existing doSMP session using doSMP1
>
> registerDoSMP(workers)
>
> r <- foreach (i=s0:s1, .combine=c) %dopar% { pf(i,x[i,5],w,isPrebuilt=TRUE) }
>
> sum(r)
> [1] 187.1781
>
> stopWorkers(workers)
Вызываемая функция (maxProb2) работает нормально, когда вместо% dopar% используется% do%%.
Как правильно вызвать функцию, включая конструкцию foreach% dopar%?
ОБНОВЛЕНИЕ 2011-07-17:
Я переименовал функцию pf в probf, но проблема остается.
Функции
probf определены в script, а не в некотором внешнем пакете.
Две заметки: ОС: Windows 7, IDE: Revolution Analytics Enterprise 4.3
> workers <- startWorkers(workerCount = 3)
>
> registerDoSMP(workers)
>
> maxProb2(w)
>
Error in { : task 1 failed - "could not find function "probf""
Ответы
Ответ 1
Я столкнулся с той же проблемой, и проблема связана с тем, что среда не включена в подпотоки. Ваша ошибка
Ошибка в {: task 1 failed - "не удалось найти функцию simple_fn" "
можно воспроизвести на этом очень простом примере:
simple_fn <- function(x)
x+1
test_par <- function(){
library("parallel")
no_cores <- detectCores()
library("foreach")
cl<-makeCluster(no_cores)
library("doSNOW")
registerDoSNOW(cl)
out <- foreach(i=1:10) %dopar% {
simple_fn(i)
}
stopCluster(cl)
return(out)
}
test_par()
Теперь вам нужно изменить foreach(i=1:10)
на foreach(i=1:10, .export=c("simple_fn"))
. Если вы хотите экспортировать свою полную глобальную среду, просто напишите .export=ls(envir=globalenv())
, и вы получите ее лучше или хуже.
Ответ 2
[[ред]]
Ваша функция pf
и ваша "статическая таблица" x
должны быть распределены всем рабочим узлам. Вы должны прочитать документацию для вашей параллельной библиотеки о том, как это работает.
Кажется, что при запуске optim, функция pf
, которую он находит, является другой (возможно, stats::pf
, которая не имеет аргумента isPrebuilt
).
Можете ли вы попробовать переименовать свою функцию pf
(например, в mypf
)?
mypf <- pf # renaming the function
maxProb2 <- function(wp) {
r <- foreach (i=s0:s1, .combine=c) %dopar% { mypf(i,x[i,5],wp,isPrebuilt=TRUE) }
cat("w=",wp,"max=",sum(r),"\n")
sum(r)
}
Или, если ваша функция pf
является частью пакета с пространством имен (например, mypackage
), вы можете ссылаться на него следующим образом: mypackage::pf
maxProb2 <- function(wp) {
r <- foreach (i=s0:s1, .combine=c) %dopar% { mypackage::pf(i,x[i,5],wp,isPrebuilt=TRUE) }
cat("w=",wp,"max=",sum(r),"\n")
sum(r)
}
Ответ 3
Быстрое исправление проблемы с foreach% dopar% заключается в переустановке этих пакетов:
install.packages("doSNOW")
install.packages("doParallel")
install.packages("doMPI")
Как упоминалось в разных потоках в StackOverflow, они отвечают за parallelism в R. Bug, который существовал в старых версиях этих пакетов, теперь удалены. Это сработало в моем случае. Я должен упомянуть, что это, скорее всего, поможет, даже если вы не используете эти пакеты в своем проекте/пакете.