Python中的多处理内存错误

Python中的多处理内存错误,python,memory,multiprocessing,Python,Memory,Multiprocessing,我试图用Python执行一些昂贵的科学计算。我必须读取csv文件中存储的大量数据,然后进行处理。由于每个进程都需要很长时间,而且我有大约8个处理器要使用,所以我尝试使用多处理中的池方法 这就是我构造多处理调用的方式: pool = Pool() vector_components = [] for sample in range(samples): vector_field_x_i = vector_field_samples_x[sample]

我试图用Python执行一些昂贵的科学计算。我必须读取csv文件中存储的大量数据,然后进行处理。由于每个进程都需要很长时间,而且我有大约8个处理器要使用,所以我尝试使用
多处理
中的
方法

这就是我构造多处理调用的方式:

    pool = Pool()
    vector_components = []
    for sample in range(samples):
        vector_field_x_i = vector_field_samples_x[sample]
        vector_field_y_i = vector_field_samples_y[sample]
        vector_component = pool.apply_async(vector_field_decomposer, args=(x_dim, y_dim, x_steps, y_steps,
                                                                           vector_field_x_i, vector_field_y_i))
        vector_components.append(vector_component)
    pool.close()
    pool.join()

    vector_components = map(lambda k: k.get(), vector_components)

    for vector_component in vector_components:
        CsvH.write_vector_field(vector_component, '../CSV/RotationalFree/rotational_free_x_'+str(sample)+'.csv')
我运行了一个500个样本的数据集,大小等于100(x\u dim)乘以100(y\u dim

在那之前,一切都很顺利

然后我收到一个500个样本的400 x 400的数据集

运行它时,调用
get
时出错

我还尝试运行一个400 x 400的样本,但得到了相同的错误

Traceback (most recent call last):
  File "__init__.py", line 33, in <module>
    VfD.samples_vector_field_decomposer(samples, x_dim, y_dim, x_steps, y_steps, vector_field_samples_x, vector_field_samples_y)
  File "/export/home/pceccon/VectorFieldDecomposer/Sources/Controllers/VectorFieldDecomposerController.py", line 43, in samples_vector_field_decomposer
    vector_components = map(lambda k: k.get(), vector_components)
  File "/export/home/pceccon/VectorFieldDecomposer/Sources/Controllers/VectorFieldDecomposerController.py", line 43, in <lambda>
    vector_components = map(lambda k: k.get(), vector_components)
  File "/export/home/pceccon/.pyenv/versions/2.7.5/lib/python2.7/multiprocessing/pool.py", line 554, in get
    raise self._value
MemoryError
回溯(最近一次呼叫最后一次):
文件“\uuuu init\uuuuu.py”,第33行,在
VfD.samples\u vector\u field\u分解器(samples,x\u dim,y\u dim,x\u步长,y\u步长,vector\u field\u samples\x,vector\u field\u samples\y)
文件“/export/home/pceccon/vectorfieldecomposer/Sources/Controllers/vectorfieldecompositercontroller.py”,第43行,在samples\u vector\u field\u decomposer中
向量分量=映射(lambda k:k.get(),向量分量)
文件“/export/home/pceccon/vectorfieldcollector/Sources/Controllers/vectorfieldcollector.py”,第43行,在
向量分量=映射(lambda k:k.get(),向量分量)
get中的文件“/export/home/pceccon/.pyenv/versions/2.7.5/lib/python2.7/multiprocessing/pool.py”,第554行
提升自我价值
记忆者
我该怎么办


提前谢谢。

现在您在内存中保留了几个列表-
向量场
向量场
向量分量
,然后在
映射
调用期间(实际上是在内存耗尽时)保存一个单独的
向量分量副本。您可以使用而不是
池来避免需要
向量组件列表的任何一个副本。将\u async
与手动创建的列表一起应用
imap
返回一个迭代器而不是一个完整的列表,因此您永远不会将所有结果都存储在内存中

通常,
pool.map
将传递给它的iterable分解成块,并将这些块发送给子进程,而不是一次发送一个元素。这有助于提高性能。因为
imap
使用迭代器而不是列表,所以它不知道传递给它的iterable的完整大小。在不知道iterable的大小的情况下,它不知道每个块的大小,因此它默认为
chunksize
为1,这将起作用,但可能无法很好地执行。为了避免这种情况,您可以为它提供一个好的
chunksize
参数,因为您知道iterable是
sample
元素长的。它可能对你的500元素列表没有多大影响,但值得尝试一下

下面是一些示例代码,演示了所有这些:

import multiprocessing
from functools import partial


def vector_field_decomposer(x_dim, y_dim, x_steps, y_steps, vector_fields):
    vector_field_x_i = vector_fields[0]
    vector_field_y_i = vector_fields[1]
    # Do whatever is normally done here.


if __name__ == "__main__":
    num_workers = multiprocessing.cpu_count()
    pool = multiprocessing.Pool(num_workers)
    # Calculate a good chunksize (based on implementation of pool.map)
    chunksize, extra = divmod(samples // 4 * num_workers)
    if extra:
        chunksize += 1

    # Use partial so many arguments can be passed to vector_field_decomposer
    func = partial(vector_field_decomposer, x_dim, y_dim, x_steps, y_steps)
    # We use a generator expression as an iterable, so we don't create a full list.
    results = pool.imap(func, 
                        ((vector_field_samples_x[s], vector_field_samples_y[s]) for s in xrange(samples)),
                        chunksize=chunksize)
    for vector in results:
        CsvH.write_vector_field(vector_component, 
                                '../CSV/RotationalFree/rotational_free_x_'+str(sample)+'.csv')
    pool.close()
    pool.join()

这应该允许您避免
MemoryError
问题,但如果没有,您可以尝试在整个样本的较小部分上运行
imap
,只需进行多次传递。不过,我不认为您会有任何问题,因为您没有构建任何其他列表,除了您开始使用的
vector\u field.*
列表。

您的可用ram用完了吗?现在您提到了(我通过ssh运行此操作)似乎是这样的。一旦完全填充了
矢量_组件
的内容,您希望如何处理这些内容?目前,您的样本量似乎太大,无法存储在内存中,因此您一次只能将其中的一部分存储在内存中。那么,您只有3种解决方案-更小的数据集/将数据分解成块并独立处理/获取更多数据,因为它们已被处理,所以我希望将它们保存在另一个csv中。我可以用Python中的Pool实现吗?