Мне нужно выполнить анализ перестановки для данных нейровизуализации, который обычно будет очень требовательным к памяти, если мы будем хранить каждое решение перестановки в памяти.Чтобы избежать этой проблемы, мы отслеживаем, во сколько раз результаты перестановок превышают значения эталона, поэтому все, что нам нужно, - это один вектор превышения количества.Это прекрасно работает в цикле for
, но я не могу понять, как распараллелить задачу, используя foreach
.Моя проблема в том, что я не могу найти способ обновить одну общую переменную (или объект) отдельными foreach
работниками.Все онлайн-рекомендации - создать таблицу данных со всеми выходными данными цикла foreach, но это неэффективно для анализа больших данных.Я мог бы попытаться сделать так, чтобы все foreach
работники записывали в общий файл, но тогда было бы другой проблемой, как обработать такой файл для получения подсчета по столбцам (не элегантное решение).Тем не менее, концептуально решение должно быть простым: каждый foreach
работник должен прочитать и изменить, ссылаясь на один общий вектор, сохраняемый в памяти.
Я использую для анализа пакет ANTsR, в котором изображения хранятся как объекты S4 (указатели на память), чтобы избежать дублирования информации при передаче аргументов функциям и т. Д. Поскольку объекты S4 являются указателями на память, яможет заставить foreach
обновить отдельный объект S4, но похоже, что указатели на S4 неправильно передаются при передаче foreach
работникам.
У кого-нибудь есть решение?
library(ANTsR)
# load example image and make a mask
img = antsImageRead(getANTsRData( "r16" ))
mask = getMask(img)
###########################################
library(doParallel)
ncores = 2
registerDoParallel(cores=ncores)
###############################
# parallel loop cannot update img S4 object
foreach (i=1:10, .combine='c', .export = c('img','mask'),
.packages = c('ITKR', 'ANTsRCore', 'ANTsR') ) %dopar% {
# max(img) # output: 254
# print(img@pointer) # output: <pointer: (nil)>
img[mask] = 0 # output: no change to img
}
# standard for loop works
for (i in 1:10) {
# print(img@pointer) output: <pointer: 0x5510610>
# max(img) # output: 254
img[mask] = 0 # output: img black
}