Распараллеливание с использованием разделяемой памяти [bigmemory]
Я испытываю некоторые трудности при попытке заставить его работать в параллельном сценарии [doSNOW], с использованием общей памяти [bigmemory]. В итоге я получаю следующую ошибку "Ошибка в {: сбой задачи 1 - " не удается открыть соединение "" в некоторых работниках foreach. Более конкретно, при проверке журнала выходных данных кластера он связан с"/temp/x_bigmatrix.desc': разрешение запрещено", например, если возникла какая-то проблема с одновременным доступом к файлу дескриптора big.matrix.
Пожалуйста, извините, но поскольку код немного сложен, я не включаю воспроизводимый пример, а собираюсь объяснить, как работает рабочий процесс с основными моментами.
У меня есть матрица X, которая преобразуется в big.matrix через:
x_bigmatrix <- as.big.matrix(x_matrix,
type = "double",
separated = FALSE,
backingfile = "x_bigmatrix.bin",
descriptorfile = "x_bigmatrix.desc",
backingpath = "./temp/")
Затем я инициализирую кластер sock с помощью doSNOW [я в Windows 10 x64]:
cl <- parallel::makeCluster(N-1, outfile= "output.log")
registerDoSNOW(cl)
(showConnections () показывает правильно зарегистрированные соединения)
Теперь я должен объяснить, что у меня есть основной цикл (foreach) для каждого работника, а затем есть внутренний цикл, в котором каждый работник циклически перебирает строки в X. Основная идея заключается в том, что в главном корпусе каждый работник питается с порциями данных последовательно через внутренний цикл, а затем каждый работник может хранить некоторые из этих наблюдений, но вместо того, чтобы сохранять сами наблюдения; они хранят индексы строк для последующего извлечения. Чтобы еще больше усложнить ситуацию, каждый работник изменяет соответствующую среду класса R6, в которой хранятся индексы. Я говорю это потому, что доступ к файлу дескриптора big.matrix происходит в двух разных местах: в основном цикле foreach и в каждой среде R6. Основной корпус foreach является следующим:
workersOutput <- foreach(worker = workers, .verbose = TRUE) %dopar% {
# In the main foreach loop I don't include the .packages argument because
# I do source with all the needed libraries at the beginning of the loop
source(libs)
# I attach the big.matrix using attach.big.matrix and the descriptor file
x_bigmatrix <- attach.big.matrix("./temp/x_bigmatrix.desc")
# Now the inner for loop is going to loop over the rows in X.
# Each worker can store some of these indices for posterior retrieval
for (i in seq(1, nrow(X)) {
# Each R6 object associated with each worker is modified, storing indices...
# Within these environments, there is read-only access through a getter using the same
# procedure that above: x_bigmatrix <- attach.big.matrix("./temp/x_bigmatrix.desc")
}
}
stopCluster(cl)
Проблема возникает во внутреннем цикле при попытке доступа к файлу big.matrix, заархивированному в файле. Потому что, если я изменю поведение в этих средах для явного хранения наблюдений вместо индексов строк (таким образом, в этих объектах больше нет доступа к файлу дескриптора), то это будет работать без проблем. Кроме того, если я запускаю его без распараллеливания [registerDoSEQ()], но сохраняя индексы строк в объектах, также нет ошибок. Таким образом, проблема возникает, если я смешиваю распараллеливание и двойной доступ к общей big.matrix в разных средах R6. Странно то, что некоторые работники могут работать дольше, чем другие, и даже в конце, по крайней мере, один завершает работу... Так что я думаю о проблеме с параллельным доступом к файлу дескриптора big.matrix.,
Я терплю неудачу в некоторых основах здесь?
1 ответ
Если проблема заключается в одновременном доступе к файлу дескриптора big.matrix, вы можете просто передать объект дескриптора (с помощью describe
), а не файл дескриптора, который содержит объект.
Объяснение: При подключении из файла дескриптора сначала создается big.matrix.descriptor
объект, а затем прикрепите big.matrix
от этого объекта. Таким образом, если вы используете объект напрямую, он будет скопирован во все ваши кластеры, и вы можете прикрепить big.matrix
от них.