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

Не удалось найти функцию внутри цикла foreach

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

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

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

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

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

4b9b3361

Ответ 1

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

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

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

Ответ 2

Поэтому я могу воспроизвести это для любопытных:

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.

[EDIT. Ранее я предположил, что, возможно,.export не работает должным образом с именами функций, но был исправлен ниже.]

Ответ 3

Быстрое исправление проблемы с foreach% dopar% заключается в переустановке этих пакетов:

install.packages("doSNOW")

install.packages("doParallel") 

install.packages("doMPI")

Это сработало в моем случае.