Ответ 1
Проблема, о которой говорил Уинстон Чанг, которую вы цитируете, была исправлена в R 2.15.3. В mccollect
произошла ошибка, которая произошла при назначении результатов работникам списку результатов:
if (is.raw(r)) res[[which(pid == pids)]] <- unserialize(r)
Это не удается, если unserialize(r)
возвращает NULL, так как присвоение NULL списку таким образом удаляет соответствующий элемент списка. Это было изменено в R 2.15.3:
if (is.raw(r)) # unserialize(r) might be null
res[which(pid == pids)] <- list(unserialize(r))
который является безопасным способом присвоить список неизвестному значению.
Итак, если вы используете R <= 2.15.2, решение должно обновиться до R >= 2.15.3. Если у вас возникла проблема с использованием R >= 2.15.3, то, вероятно, это другая проблема, чем тот, о котором сообщил Уинстон Чанг.
Я также прочитал вопросы, обсуждаемые в потоке R-справки, начатом Элизабет Пурдом. Без конкретного теста я предполагаю, что проблема связана не с ошибкой в mclapply, потому что я могу воспроизвести те же симптомы со следующей функцией:
work <- function(i, poison) {
if (i == poison) quit(save='no')
i
}
Если рабочий, запущенный mclapply, умирает во время выполнения задачи по какой-либо причине (получение сигнала, seg faulting, exiting), mclapply возвращает NULL для всех задач, которые были назначены этому работнику:
> library(parallel)
> mclapply(1:4, work, 3, mc.cores=2)
[[1]]
NULL
[[2]]
[1] 2
[[3]]
NULL
[[4]]
[1] 4
В этом случае NULL были возвращены для задач 1 и 3 из-за предварительной настройки, хотя фактически выполнялась только задача 3.
Если рабочий умирает при использовании функции, такой как parLapply или clusterApply, сообщается об ошибке:
> cl <- makePSOCKcluster(3)
> parLapply(cl, 1:4, work, 3)
Error in unserialize(node$con) : error reading from connection
Я видел много таких отчетов, и я думаю, что они, как правило, происходят в больших программах, которые используют множество пакетов, которые трудно превратить в воспроизводимые тестовые примеры.
Конечно, в этом примере вы также получите ошибку при использовании lapply, хотя ошибка не будет скрыта, как и при использовании mclapply. Если проблема не возникает при использовании lapply, это может быть из-за того, что проблема редко возникает, поэтому это происходит только при очень больших запусках, которые выполняются параллельно с использованием mclapply. Но также возможно, что ошибка возникает не потому, что задачи выполняются параллельно, а потому, что они выполняются разветвленными процессами. Например, при выполнении в разветвленном процессе различные графические операции будут терпеть неудачу.