Открытие файлов изображений в R параллельно

Что я пытаюсь сделать:
Откройте стек изображений с помощью EBImage, обработайте их и сохраните обработанное изображение в новом файле. Я пытаюсь сделать это параллельно, используя пакет «doParallel»и » foreach».

Проблема:
Каждый раз, когда я использую несколько процессорных ядер для задачи, R возвращает ошибку:

Error in unserialize(node$con) : error reading from connection
Calls: <Anonymous> ... doTryCatch -> recvData -> recvData.SOCKnode -> unserialize
Execution halted

Я не знаю, как получить больше информации об этой ошибке. Если я попытаюсь использовать тот же сценарий, но только с одним процессорным ядром, я не получу никаких проблем.

Пример сценария:

library(EBImage)
library(foreach)
library(doParallel)

nCores = 1
registerDoParallel(makeCluster(nCores))

img_stack_ids = c("A", "B", "C", "D")
foreach(i = 1:384, .packages = c("EBImage")) %dopar% {
  imgs = tryCatch(readImage(sprintf("/INPUT_IMGS/%s_%s, i, img_stack_ids)), 
                  error = function(e) array(0, dim = c(0,0,0)))

  img_processed = processingFunction(img_list)
  writeImage(img_processed, sprintf("/OUTPUT_IMGS/%s", i))
}

Код работает, когда nCores = 1, он не работает, когда nCores находится между 1 и максимальным количеством доступных ядер.

Система, на которой я хочу это запустить, — это виртуальная машина с 36 ядрами под управлением CentOS 7.

Отдельные работники должны иметь доступ к уникальным файлам на основе идентификатора файла, поэтому я не могу представить, что это проблема с блокировкой файла или одновременным чтением, если только linux не имеет проблем с одновременным чтением и записью в тот же каталог.

Честно говоря, я был бы рад как обходному пути, так и решению.

Спасибо!


Информация о сеансе:
R версия 3.3.1 (2016-06-21)
Платформа: x86_64-apple-darwin13.4.0 (64-разрядный)
Работает под: OS X 10.11.6 (El Capitan)

locale:
[1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8

attached base packages:
[1] parallel  stats     graphics  grDevices utils     datasets  methods
    base     

other attached packages:
[1] doParallel_1.0.10  iterators_1.0.8    foreach_1.4.3
    ZProjection_0.99.0 EBImage_4.16.0    

loaded via a namespace (and not attached):
 [1] locfit_1.5-9.1      lattice_0.20-34     codetools_0.2-15
     png_0.1-7           fftwtools_0.9-7     tiff_0.1-5
     grid_3.3.1          tools_3.3.1         jpeg_0.1-8
     abind_1.4-5        
[11] rsconnect_0.5       BiocGenerics_0.20.0

1 ответ

  1. Ниже приведен воспроизводимый пример на основе исходного кода. Я смог успешно запустить его параллельно на RedHat Linux (Fedora и CentOS 6.5) и OS X Yosemite (10.10.5). Это указывает на то, что проблема может быть связана с системой или конфигурацией.

    library(EBImage)
    library(foreach)
    library(doParallel)
    
    nCores = detectCores()
    registerDoParallel(makeCluster(nCores))
    
    input_dir = "input_imgs"
    output_dir = "output_imgs"
    
    dir.create(input_dir)
    dir.create(output_dir)
    
    no_images = 384
    img_stack_ids = LETTERS[1:4]
    
    ## create sample images
    n = 8 # image dimensions
    
    for (i in 1:no_images)
      for (id in img_stack_ids)
        writeImage(Image(runif(n^2), c(n, n)),
                   sprintf("%s/%s_%s.png", input_dir, i, id))
    
    ## do the actual work
    foreach(i = 1:no_images, .packages = c("EBImage")) %dopar% {
      imgs = tryCatch(
        readImage(sprintf("%s/%s_%s.png", input_dir, i, img_stack_ids)), 
        error = function(e) array(0, dim = c(0,0,0))
      )
    
      ## do the processing
    
      writeImage(imgs, sprintf("output_imgs/%s.tif", i))
    }