5

我正在使用 python 脚本从 4D 图像(功能性 MRI 扫描)中操作和提取信息。部分分析设置为使用 multiprocessing 包并行运行(针对每个主题):

pool = Pool(processes=numberCores)
resultList = pool.map(SubjectProcesser, argList) # where arglist is the list of arguments passed to the process

这些适用于不同类型的文件和不同类型的分析。对于一种特定类型的分析,我收到以下错误:

Process PoolWorker-1:
Traceback (most recent call last):
File "/home2/user/epd/epd-7.2-2-rh5-x86_64/lib/python2.7/multiprocessing/process.py", line 258, in _bootstrap
  self.run()
File "/home2/user/epd/epd-7.2-2-rh5-x86_64/lib/python2.7/multiprocessing/process.py", line 114, in run
  self._target(*self._args, **self._kwargs)
File "/home2/surchs/epd/epd-7.2-2-rh5-x86_64/lib/python2.7/multiprocessing/pool.py", line 99, in worker
  put((job, i, result))
File "/home2/user/epd/epd-7.2-2-rh5-x86_64/lib/python2.7/multiprocessing/queues.py", line 392, in put
  return send(obj)
IOError: bad message length

我已将其缩小到失败的程度。并行进程显然执行正常(通过在脚本的不同阶段查看我的各种调试打印输出来确定),但随后在重新映射结果期间发生故障。

我已搜索此错误消息,但尚未找到任何解决方案。由于我的脚本确实适用于所有其他类型的分析,我想知道会发生什么。

关于分析的一点,因为我想这会导致问题

不同的分析或多或少是大脑中体素的时间序列提取(将大脑想象为 3D 矩阵,时间为第四维,矩阵元素称为体素)。大脑中的任何一点对于每个时间点都有一个激活值。那么时间序列是给定体素的所有激活值随时间变化的向量。

然后我计算所有体素之间的相关系数(给我一个平方相关矩阵,其维度为体素),并返回所有相关系数的向量(矩阵的下三角形)作为并行处理的输出。

现在对于所有不抛出错误的分析,我平均多个体素(基于区域节点),然后使用该区域的平均时间序列 - 有效地做两件事:

  1. 大幅减少体素数量(减少区域数量)
  2. 摆脱始终为零的体素(作为平均的结果。没有区域将仅包含零体素)

相比之下,给出上述错误的分析使用了大脑中的所有体素时间序列,从而产生了更大的相关矩阵。

我试图通过屏蔽每个主题文件来消除零体素,而且我没有得到任何“除以零”错误,但这是我能想到的唯一两件事。

此外,如上所述,处理的并行部分毫无问题地进行。运行后会抛出错误,可能是在重新映射结果期间。

任何帮助将不胜感激。另外,如果我应该提供更多详细信息,请告诉我。

4

1 回答 1

2

当我从子进程返回的对象变得太大(在我的情况下为数十千兆字节)时,我遇到了同样的问题。这些巨大的对象需要被腌制并通过进程通信发送回父进程,这可能是问题的原因。当然,即使我没有收到此错误,移动数十 GB 的数据也是一个坏主意。因此,我的解决方案是更改程序的结构,以消除传递如此大的对象的需要。

您可能能够做的一件事是使用Shared Memory。我对此不太走运,因为我的对象非常复杂,并且在没有大量代码更改的情况下不容易在共享内存中创建,但您的对象可能更易于管理。

另请参阅另一个线程:python multiprocessing 中的共享内存对象

于 2012-12-07T21:14:00.443 回答