我有一个函数,我将其应用于不同的数据块。由于每个块都独立于其余块,我希望并行执行所有块的功能。
我有一个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
)。那么,我想知道如何获得每个数据块的函数输出?
答案 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