【问题标题】:Understanding writeValues of raster by parallel processing. Is it possible to writevalues for each raster while using mclapply fork cluster. R通过并行处理了解光栅的 writeValues。是否可以在使用 mclapply fork 集群时为每个栅格写入值。 R
【发布时间】:2020-12-04 17:53:37
【问题描述】:

我试图了解如何在 R 中并行化光栅处理。我的目标是在具有多个光栅的多个内核上并行化以下内容。 我按块处理我的栅格,并尝试将其与 mclapply 或其他函数并行化。首先,我想获取一个栅格或栅格堆栈的值。然后我想将值写入对象。当我使用多个内核时,它不起作用,因为不同的子进程想要同时写入。有人知道解决方案吗?

所以这里是过程:

获取和创建数据

r <- raster(system.file("external/test.grd", package="raster"))
s <- raster(r)
tr <- blockSize(r)

然后使用 for 循环获取值和写入值

s <- writeStart(s[[1]], filename='test.grd',  overwrite=TRUE)
for (i in 1:tr$n) {
  v <- getValuesBlock(r, row=tr$row[i], nrows=tr$nrows[i])
  s <- writeValues(s, v, tr$row[i])
}
s <- writeStop(s)

这很好用

现在在 lapply 上尝试同样的方法

s <- writeStart(s[[1]], filename='test.grd',  overwrite=TRUE)
#working with lapply
lapply(1:tr$n, function(x){
  v <- getValues(r, tr$row[x], tr$nrows[x])
  s <- writeValues(s,v,tr$row[x])
})
s <- writeStop(s)

工作正常

现在正在尝试单核 mclapply

s <- writeStart(s[[1]], filename='test.grd',  overwrite=TRUE)

#does work with mclapply one core
parallel::mclapply(1:tr$n, function(x){
  v <- getValues(r, tr$row[x], tr$nrows[x])
  s <- writeValues(s,v,tr$row[x])
}, mc.cores = 1)
s <- writeStop(s)

也可以

现在尝试在多核上使用 mclapply

s <- writeStart(s[[1]], filename='test.grd',  overwrite=TRUE)
#does not work with multiple core
parallel::mclapply(1:tr$n, function(x){
  v <- getValues(r, tr$row[x], tr$nrows[x])
  s <- writeValues(s,v,tr$row[x])
}, mc.cores = 2)
s <- writeStop(s)

所以这行不通。我理解逻辑,为什么它不起作用。 我现在的问题是:假设我有一个包含 2 个栅格的栅格堆栈。我可以使用 mclapply 或并行包中的其他函数来以不同的方式编写此过程。所以我同时获得了两个网格的块值,但这些值只写入每个核心的一个评估者。

对于我正在寻找的解决方案,首先获取所有值,将它们安全地保存在一个对象中然后逐块写入值是不可接受的,因为我的栅格太大。

如果有人有解决方案或只是一个想法或建议,我会非常高兴。 谢谢。

【问题讨论】:

    标签: r parallel-processing raster r-raster mclapply


    【解决方案1】:

    我相信raster::writeStart()返回的对象只能在创建它的同一个R进程中处理。也就是说,不可能并行的 R 进程使用它。

    对象在内部使用外部指针这一事实强烈表明它不能被导出到另一个 R 进程或保存到文件或再次读回。您可以使用(非公开)future:::assert_no_references() 检查外部指针,例如

    > library(raster)
    > r <- raster(system.file("external/test.grd", package="raster"))
    > future:::assert_no_references(r)
    NULL     ## == no external pointer
    
    > s <- raster(r)
    > future:::assert_no_references(s)
    NULL     ## == no external pointer
    
    > s <- writeStart(s[[1]], filename='test.grd',  overwrite=TRUE)
    > future:::assert_no_references(s)
    Error: Detected a non-exportable reference ('externalptr') in one of the globals (<unknown>) used in the future expression
    

    【讨论】:

    • 是的,这正是问题所在。谢谢你说清楚。那么对于逐块光栅处理,不可能并行化?唯一的可能性是通过在光栅堆栈上循环进行逐块光栅处理。在我看来,这将是非常低效的。你有别的想法吗?
    • 对不起,我不知道。我建议联系 raster 的维护者,以获取有关使用他们的数据结构进行并行化的建议。
    猜你喜欢
    • 2021-09-30
    • 2023-03-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-09
    • 1970-01-01
    • 2017-08-13
    • 2020-03-05
    相关资源
    最近更新 更多