Подтвердить что ты не робот

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""
4b9b3361

Ответ 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, который существовал в старых версиях этих пакетов, теперь удалены. Это сработало в моем случае. Я должен упомянуть, что это, скорее всего, поможет, даже если вы не используете эти пакеты в своем проекте/пакете.