не удалось найти функцию внутри цикла foreach - PullRequest
18 голосов
/ 22 января 2011

Я пытаюсь использовать foreach для многоядерных вычислений в R.

A <-function(....) {
    foreach(i=1:10) %dopar% {
    B()
    }
}

, затем вызываю функцию A в консоли.Проблема в том, что я вызываю функцию Posdef внутри B, которая определена в другом файле сценария, который я поставил.Мне пришлось поставить Posdef в список аргументов экспорта foreach: .export=c("Posdef").Однако я получаю следующую ошибку:

Error in { : task 3 failed - "could not find function "Posdef""

Почему R не может найти эту определенную функцию?

Ответы [ 3 ]

13 голосов
/ 12 апреля 2012

Так что я могу воспроизвести это, для любопытных:

require(doSNOW)
registerDoSNOW(makeCluster(5, type="SOCK"))
getDoParWorkers()
getDoParName()
getDoParVersion()

fib <- function(n) {
  if (n <= 1) { return(1) }
  return(fib(n-1) + fib(n-2))
}

my.matrix <- matrix(runif(2500, 10, 50), nrow=50)

calcLotsaFibs <- function() {
  result <- foreach(row.num=1:nrow(my.matrix), .export=c("fib", "my.matrix")) %dopar% {
    return(Vectorize(fib)(my.matrix[row.num,]))
  }
  return(result)
}

lotsa.fibs <- calcLotsaFibs()

Мне удалось обойти это, поместив функцию в другой файл и загрузив этот файл в тело foreach. Вы также можете переместить определение функции в тело самого foreach.

[РЕДАКТИРОВАТЬ - Ранее я предполагал, что, возможно, .export не работает должным образом с именами функций, но был исправлен ниже.]

10 голосов
/ 26 июля 2013

Короткий ответ - это ошибка в параллельных бэкэндах, таких как doSNOW, doParallel и doMPI, но с тех пор она была исправлена.

Немного более длинный ответ заключается в том, что foreach экспортирует функции для работников, используя специальную "экспортную" среду, а не глобальную среду. Раньше это вызывало проблемы для функций, которые были созданы в глобальной среде, потому что среда «экспорта» не входила в их область действия, даже если теперь они были определены в той же среде «экспорта». Таким образом, они не могли видеть никакие другие функции или переменные, определенные в среде «экспорта», такие как «Posdef» в вашем случае.

Бэкэнды doSNOW, doParallel и doMPI теперь изменяют связанную среду с глобальной на «экспортную» для функций, экспортируемых через «.export», и, похоже, решили эти проблемы.

1 голос
/ 21 августа 2017

Быстрое решение проблемы с foreach% dopar% - переустановить эти пакеты:

install.packages("doSNOW")

install.packages("doParallel") 

install.packages("doMPI")

В моем случае это сработало.

...