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

2024-07-05 14:40:30 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个应用于不同数据块的函数。因为每个块都独立于其余的块,所以我希望并行地执行所有块的函数

我有一个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)上写入。所以,我想知道如何获得每个数据块的函数输出


Tags: 数据函数inimportfor字典parallelcount
1条回答
网友
1楼 · 发布于 2024-07-05 14:40:30

joblib,默认情况下使用python中的multiprocessing模块。根据this SO Answer,当参数传递给新进程时,它们会创建一个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

相关问题 更多 >