Параллельная обработка больших растров в R (windows)
Я использую пакет doSNOW и, более конкретно, функцию parLapply для переклассификации (и впоследствии других операций) в списке больших наборов растровых данных (ОС: Windows x64).
Код выглядит как минималистичный пример:
library(raster)
library(doSNOW)
#create list containing test rasters
x <- raster(ncol=10980,nrow=10980)
x <- setValues(x,1:ncell(x))
list.x <- replicate( 9 , x )
#setting up cluster
NumberOfCluster <- 8
cl <- makeCluster(NumberOfCluster)
registerDoSNOW(cl)
junk <- clusterEvalQ(cl,library(raster))
#perform calculations on each raster
list.x <- parLapply(cl,list.x,function(x) calc(x,function(x) { x * 10 }))
#stop cluster
stopCluster(cl)
Код на самом деле работает как задумано. Проблема возникает, когда я хочу продолжить результаты. Я получаю это сообщение об ошибке:
> plot(list.x[[1]])
Error in file(fn, "rb") : cannot open the connection
In addition: Warning message:
In file(fn, "rb") :
cannot open file 'C:\Users\*****\AppData\Local\Temp\RtmpyKYdpY\raster\r_tmp_2016-02-29_133158_752_67867.gri': No such file or directory
Насколько я понял, поскольку растры довольно большие, они сохраняются во временном файле на диске. И когда я закрываю снежный кластер, к этим файлам больше нельзя получить доступ.
Итак, мой вопрос, как я могу получить доступ к данным после закрытия кластера? Могу ли я продолжить использовать этот метод?
Спасибо!
2 ответа
У меня была именно эта проблема при выполнении функции растрирования внутри кластера в R.
Все тесты работали безупречно, но когда я увеличивал масштаб до растров очень большого и высокого разрешения, я неоднократно получал ошибки относительно временных файлов, которые я даже не мог найти на своем компьютере. Объект списка, который мне нужно было объединить и записать как 1 растр, был в R, но я ничего не мог с этим поделать.
Посмотрев каталог временных файлов во время работы кластера, я заметил, что закрытие кластера автоматически удалит все созданные временные файлы, поэтому мне пришлось выполнить функции merge и writeRaster внутри кластера, в противном случае произойдет сбой при ошибке, очень похожей на ваша.
Вы можете передать конкретные имена файлов calc
(или, например, reclassify
), и пусть ваша функция возвращает эти имена файлов как вектор для чтения в стек:
ff <- parSapply(cl, list.x, function(x) {
calc(x, function(x) x*10, filename=f <- tempfile(fileext='.tif'))
f
})
s <- stack(ff)
Но также посмотрите на ?clusterR
- Я подозреваю, что это будет работать с reclassify
, Из документов:
Эта функция работает только с функциями, имеющими объект Raster * в качестве первого аргумента и работающими по принципу "ячейка за ячейкой" (т. Е. Нет влияния соседних ячеек) и возвращающими объект с тем же числом ячеек, что и у входного растрового объекта., Первым аргументом вызываемой функции должен быть объект Raster *. Может быть только один аргумент объекта Raster *. Например, он работает с calc и также работает с оверлеем, если в качестве первого аргумента указывается один RasterStack или RasterBrick.