R - Почему foreach% dopar% висит на компьютере с Windows 7, но не на сервере Windows NT? - PullRequest
0 голосов
/ 25 июня 2019

ОБНОВЛЕНИЕ Ну, «в корне неправильно» не было преувеличением. Я даже не смог запустить самую простую команду foreach% dopar% на машине, которую я использовал, - Win7 64x с 8 ядрами, работающей с R 3.4.4 и последними пакетами. Windows Server (Windows NT с 16 ядрами) может использовать те же версии программного обеспечения и пакетов.

Итак, теперь я хочу знать, почему я мог инициализировать кластер на машине Win7 без ошибок, но потом не смог его использовать?

Для потомков, вот успешная версия оператора foreach, который работал на Windows Server, но все еще зависал на машине Win7:

y <- foreach(i=1:length(x), .packages = c("raster")) %dopar%
    dpave(x[i], m)

Моя конечная цель - создать единый растр взвешенных по глубине метрик почвы для каждой из 5 метрик. Входные данные (почвы Polaris, http://hydrology.cee.duke.edu/POLARIS) имеют отдельные геотифы для каждой метрики на 5 глубинах (которые меня интересуют) на плитках с 1 градусом по всей США. Моя область исследования имеет размер 223 плит с 1 градусом.

То, что я надеялся сделать, это получить средневзвешенное значение глубины для каждой плитки, а затем объединить усредненные плитки вместе в один растр для каждой метрики. Я пытаюсь использовать параллельную обработку с doSNOW , но я абсолютно застрял с моим оператором foreach - он запускается, но ничего не происходит.

У меня есть начальный вложенный оператор foreach, который выполняется последовательно для создания списка символов имен файлов геотифов. Это работает, я получаю список x из 223 списков по 5 файлов в каждом. Так что x [1] выглядит так:

> x[1]
[[1]]
[1] "E:/Polaris/clay_0_5_lat4849_lon-113-112.tif"    "E:/Polaris/clay_5_15_lat4849_lon-113-112.tif"  
[3] "E:/Polaris/clay_15_30_lat4849_lon-113-112.tif"  "E:/Polaris/clay_30_60_lat4849_lon-113-112.tif" 
[5] "E:/Polaris/clay_60_100_lat4849_lon-113-112.tif"

Затем у меня есть функция dpave, которая берет каждый список из 5 и возвращает один RasterLayer средневзвешенного по глубине для этого тайла. Эта функция работает, когда выполняется вручную (например, t <- dpave (x [1], m)). </p>

Но когда я пытаюсь запустить функцию параллельно - так, чтобы несколько списков из 5 обрабатывались одновременно, R говорит мне, что она работает, но не используется ЦП или память, не возвращаются ошибки, ничего. Вот код:

library(raster)
library(rgdal)
library(doSNOW)
library(readr)

polaris_tiles <- read_csv("polaris_tiles.csv")
metrics <- c("clay", "sand", "bd", "om", "ph")
depths <- c("0_5", "5_15", "15_30", "30_60", "60_100")
wkdir <- "E:/Polaris/"

# Start parallel cluster of workers
cl <- makeCluster(7, type = 'SOCK')
registerDoSNOW(cl)

# depth-weighted average function
dpave <- function(raslist, m){
  dpct <- c(0.05, 0.1, 0.15, 0.3, 0.4)
  trulist <- as.list(unlist(raslist))
  rastack <- stack(trulist)
  if(m == "om"){  #organic matter is in log10(%)
    tmpstack <- 10 ^ rastack
    tile <- sum(tmpstack * dpct)
  } else {
    tile <- sum(rastack * dpct)
  }
  return(tile)
}

for (m in metrics){
  prefix <- paste(wkdir, m, sep = "")
  # this nested foreach works:
  x <- foreach(s=polaris_tiles$suffix) %:%
    foreach(d=depths, .combine = "c") %do%
      paste(prefix, d, s, sep = "_")

  # this is the function that goes nowhere
  y <- foreach(i=1:length(x), .combine = list, .errorhandling="remove",
               .multicombine = TRUE, .packages = c("raster")) %dopar% {
                 dpave(x[i], m)
  }

  # ...and code continues but it never gets to this point...
}

# Release the cluster
stopCluster(cl)

Я пробовал несколько вариантов, назначая функцию переменной:

  t <- dpave(x[i], m)

пытается перебрать x напрямую:

  foreach(i=x, ...
     dpave(i, m)

пробует несколько разных опций для .combine , .multicombine , .errorhandling , yatta yatta, но ничего не меняет поведение.

Так ясно, что я в основном неправильно понимаю утверждение. Кто-нибудь может помочь?

...