Search code examples
rparallel-processingrasterterra

Multiply a single band raster by a vector in parallel in R terra


I would like to perform the following vector*raster multiplication in parallel, since my vector is very long:

library(terra)

# Create a raster example

set.seed(123)

raster_example <- rast(nrow = 10, ncol = 10, vals = rnorm(100))

# Create a vector example
vector_ejemplo <- c(2, 3, 4, 5, 6, 7, 8, 9, 10, 11)

# Perform multiplication 
result_no_parallel <- vector_ejemplo * raster_example


print(result_no_parallel)

I tried with terra::app, but I am getting errors only.

Is there a way to do this?


Solution

  • Rast object cannot be serialized (have a look here and related links). But you can send names or paths to nodes, or you can wrap your raster to send it to nodes. Here is a toy example with your data. Note that this example has no time gain since the overheads of having multiple nodes are more significant than the speed gain. Since multiplication is a C++ function in terra optimized for speed and memory usage, I imagine your raster is enormous if you need to parallelize such a simple operation.

    library(terra)
    library(foreach)
    library(doParallel)
    # Create a raster example
    
    set.seed(123)
    
    raster_example <- rast(nrow = 10, ncol = 10, vals = rnorm(100))
    path <-file.path(tempdir(),"ejemplo.tif")
    writeRaster(raster_example,path)
    
    # Create a vector example
    vector_ejemplo <- c(2, 3, 4, 5, 6, 7, 8, 9, 10, 11)
    
    
    
    f <- function(path,n) {
      x <- rast(path)
      y <- x*n
      wrap(y)
    }
    
    cl <- makeCluster(10)
    registerDoParallel(cl)
    
    result <- foreach(n=vector_ejemplo,.packages="terra")%dopar%{
      f(path,n)
    }
    
    stopCluster(cl)
    x <- do.call(c,lapply(result, unwrap))
    

    See ?wrap for more details on this beautiful function that makes parallelization with rast objects possible.