并行化python函数而不存储中间结果
我需要为一些输出大结果的查询积累许多树的结果。因为所有树都可以独立处理,所以它是令人尴尬的并行的,除了结果需要求和这一事实之外,我无法将所有树的中间结果存储在内存中。下面是一个简单的问题代码示例,它将所有中间结果保存在内存中(当然,函数在实际问题中是相同的,因为这将做重复的工作) 解决方案可以是以下修改:并行化python函数而不存储中间结果,python,parallel-processing,Python,Parallel Processing,我需要为一些输出大结果的查询积累许多树的结果。因为所有树都可以独立处理,所以它是令人尴尬的并行的,除了结果需要求和这一事实之外,我无法将所有树的中间结果存储在内存中。下面是一个简单的问题代码示例,它将所有中间结果保存在内存中(当然,函数在实际问题中是相同的,因为这将做重复的工作) 解决方案可以是以下修改: import numpy as np from joblib import Parallel, delayed functions=[[abs,np.round] for i in rang
import numpy as np
from joblib import Parallel, delayed
functions=[[abs,np.round] for i in range(500)] # Dummy functions
functions=[function for sublist in functions for function in sublist]
X=np.random.normal(size=(5,5)) # Dummy data
results_out = np.zeros(results[0].shape)
def helper_function(function,X=X,results=results_out):
result = function(X)
results += result
Parallel(n_jobs=-1,)(
map(delayed(helper_function), [functions[i] for i in range(1000)]))
但这可能会导致种族冲突。因此,它不是最优的
您是否有任何建议,可以在不存储中间结果的情况下执行此操作,并且仍然使其并行?答案在中给出
将并行(n_作业=2)作为并行:
累加器=0。
n_iter=0
当蓄能器<1000时:
结果=并联(延迟(sqrt)(累加器+i**2)
对于范围(5)中的i)
累加器+=总和(结果)#同步屏障
n_iter+=1
您可以分块进行计算,并在即将耗尽内存时减少块。答案在中给出
将并行(n_作业=2)作为并行:
累加器=0。
n_iter=0
当蓄能器<1000时:
结果=并联(延迟(sqrt)(累加器+i**2)
对于范围(5)中的i)
累加器+=总和(结果)#同步屏障
n_iter+=1
您可以分块进行计算,并在即将耗尽内存时减少块。谢谢您的回答。直到我添加了具有潜在种族的解决方案后,我才看到您的回复。它解决了您的问题吗?如果是这样,请考虑接受答案,如果不是,我会好奇为什么:-我想它解决了问题99%,因为它可以在实践中工作。但它仍然为应用程序保留了一个hyperparameter(累加器的篮子大小),并提供了一个同步障碍。出于好奇,我想知道是否可以执行安全的就地操作,这样所有线程都可以更新结果。我认为在其他并行编程模式中,比如tensorflow,也包含了类似的内容。谢谢你的回答。直到我添加了具有潜在种族的解决方案后,我才看到您的回复。它解决了您的问题吗?如果是这样,请考虑接受答案,如果不是,我会好奇为什么:-我想它解决了问题99%,因为它可以在实践中工作。但它仍然为应用程序保留了一个hyperparameter(累加器的篮子大小),并提供了一个同步障碍。出于好奇,我想知道是否可以执行安全的就地操作,这样所有线程都可以更新结果。我认为在其他并行编程模式中,比如tensorflow,也包含了类似的内容。
import numpy as np
from joblib import Parallel, delayed
functions=[[abs,np.round] for i in range(500)] # Dummy functions
functions=[function for sublist in functions for function in sublist]
X=np.random.normal(size=(5,5)) # Dummy data
results_out = np.zeros(results[0].shape)
def helper_function(function,X=X,results=results_out):
result = function(X)
results += result
Parallel(n_jobs=-1,)(
map(delayed(helper_function), [functions[i] for i in range(1000)]))
with Parallel(n_jobs=2) as parallel:
accumulator = 0.
n_iter = 0
while accumulator < 1000:
results = parallel(delayed(sqrt)(accumulator + i ** 2)
for i in range(5))
accumulator += sum(results) # synchronization barrier
n_iter += 1