не могу найти функцию внутри цикла foreach

Я пытаюсь использовать 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""

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

3 ответов


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

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

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


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

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 -- я ранее предлагал это возможно .экспорт не работает должным образом с именами функций, но был исправлен ниже.]


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

install.packages("doSNOW")

install.packages("doParallel") 

install.packages("doMPI")

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