当并行执行进程时,计算不会存储在传递的参数中

时间:2017-10-30 14:39:38

标签: python python-3.x parallel-processing

我有一个函数,我将其应用于不同的数据块。由于每个块都独立于其余块,我希望并行执行所有块的功能。

我有一个result字典,它应该保存每个块的计算输出。

我是这样做的:

from joblib import Parallel, delayed
import multiprocessing

cpu_count = multiprocessing.cpu_count() 

# I have 8 cores, so I divide the data into 8 chunks.
endIndeces = divideIndecesUniformly(myData.shape[0], cpu_count) # e.g., [0, 125, 250, ..., 875, 1000]

# initialize result dictionary with empty lists.
result = dict()
for i in range(cpu_count):
    result[i] = []

# Parallel execution for 8 chunks
Parallel(n_jobs=cpu_count)(delayed(myFunction)(myData, start_idx=endIndeces[i], end_idx=endIndeces[i+1]-1, result, i) for i in range(cpu_count))

但是,执行完成时result包含所有初始空列表。我想如果我在每个数据块上串行执行该函数,它就可以正常工作。例如,如果我用以下内容替换最后一行,result将包含所有计算值。

# Instead of parallel execution, call the function in a for-loop.
for i in range(cpu_count):
    myFunction(myData, start_idx=endIndeces[i], end_idx=endIndeces[i+1]-1, result, i)

在这种情况下,result值会更新。

当函数并行执行时,它似乎无法写入给定的字典(result)。那么,我想知道如何获得每个数据块的函数输出?

1 个答案:

答案 0 :(得分:0)

joblib,默认使用python中的multiprocessing模块。根据{{​​3}},当参数传递给新进程时,它们会创建一个fork,其中复制当前进程的内存空间。这意味着myFunction基本上处理result的副本,并且不会修改原始文件。

我的建议是让myFunction将所需数据作为列表返回。然后,对Process的调用将返回myFunction生成的列表列表。从那里,将它们添加到结果中很简单。它可能看起来像这样:

from joblib import Parallel, delayed
import multiprocessing

if __name__ == '__main__':
    cpu_count = multiprocessing.cpu_count() 

    endIndeces = divideIndecesUniformly(myData.shape[0], cpu_count)

    # make sure myFunction returns the grouped results in a list
    r = Parallel(n_jobs=cpu_count)(delayed(myFunction)(myData, start_idx=endIndeces[i], end_idx=endIndeces[i+1]-1, result, i) for i in range(cpu_count))

    result = dict()
    for i, data in enumerate(r):  # cycles through each resultant chunk, numbered and in the original order
        result[i] = data