Не удалось найти функцию внутри цикла 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 найти эту определенную функцию?
Ответы
Ответ 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")
Это сработало в моем случае.