并行化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