0

我正在尝试做的事情:使用 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 和最大可用内核数之间时无效。

我希望它运行的系统是一个运行 CentOS 7 的具有 36 个内核的虚拟机。

单个工作人员应该根据文件 ID 访问唯一文件,因此我无法想象这是文件锁定或同时读取的问题,除非 linux 也存在同时读取和写入同一目录的问题。

老实说,我很高兴找到解决方法和解决方案。

谢谢!


我的会话信息:R 版本 3.3.1 (2016-06-21) 平台:x86_64-apple-darwin13.4.0 (64-bit) 运行条件: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
4

1 回答 1

0

下面是基于您的原始代码的可重现示例。我能够在 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))
}
于 2016-11-11T15:42:46.040 回答