loki loki - 19 days ago 8
R Question

Up-to-date multicore computing in triple for-loop in R

I want to calculate GLCM with 488 raster files. Because of the enormous calculation time i want to use all the power of my multicore processor (AMD Phenom II 6-core).

library("glcm")
library(raster)
library(devtools)
install_github('azvoleff/glcm')

setwd(working dir.)
rasters <- list.files()[grep("()\\w*.tif", list.files())]
statistics <- c("mean", "variance", "homogeneity", "contrast", "dissimilarity", "entropy","second_moment", "correlation")
shift1 <- c(0,0,1,1)
shift2 <- c(0,1,0,1)

for (j in 1:length(rasters)){
raster1 <- raster(rasters[j])
for (i in 1:length(statistics)){
for (k in 1:length(shift1)){
GLCM <- glcm(raster1, window=c(11,11), statistics=statistics[i], shift = c(shift1[k],shift2[k]), na_opt="ignore")

file <- paste("./GLCM/", substr(tiles[j],0,nchar(tiles[j])-4),"_", statistics[i], "_shift_",shift1[k], shift2[k] , ".tif", sep="")
writeRaster(GLCM, filename = file, type = "GTIFF")
}

}
gc()
}


I searched the internet for multicore solutions in R, but could not find out which one is up to date. So I hope someone can help me.

Answer

glcm is not coded to run in parallel, but given that you are processing 488 rasters, I wouldn't worry about running the algorithm itself in parallel - processing the rasters in parallel (say two at a time on an average laptop machine, more if you have more processing pwer and RAM) is the simplest approach here. glcm versions > 1.4 will automatically run block by block over large images (and will account for edge effects), so memory shouldn't be an issue.

Something like the below should get you started (based on your code):

library(glcm)
library(raster)
library(foreach)
library(doparallel)

cl <- makeCluster()
registerDoParallel(cl)

setwd(working dir.)
rasters <- list.files()[grep("()\\w*.tif", list.files())]
statistics <- c("mean", "variance", "homogeneity", "contrast",
                "dissimilarity", "entropy","second_moment",
                "correlation")
shift1 <- c(0, 0, 1, 1)
shift2 <- c(0, 1, 0, 1)

foreach (j in 1:length(rasters), .packages=c('raster', 'glcm')) %dopar% {
  raster1 <- raster(rasters[j])
  for (i in 1:length(statistics)) {
    for (k in 1:length(shift1)) {
      GLCM <- glcm(raster1, window=c(11,11), statistics=statistics[i],
                   shift = c(shift1[k],shift2[k]), na_opt="ignore")
      file <- paste("./GLCM/", substr(tiles[j], 0, nchar(tiles[j])-4),
                    "_", statistics[i], "_shift_",shift1[k], shift2[k],
                    ".tif", sep="")
      writeRaster(GLCM, filename = file, type = "GTIFF")
    }
  }
}

stopCluster(cl)