简体   繁体   English

使用池进行多处理时无法腌制本地 object。map

[英]Can't pickle local object when multiprocessing with pool.map

I am trying to use multiprocessing with the python Pool function, using functools.partial to input several arguments with constant value into the pool.map command (ie the first argument is the only varying). I am trying to use multiprocessing with the python Pool function, using functools.partial to input several arguments with constant value into the pool.map command (ie the first argument is the only varying).

The issue is that when I run the code I get the following error and I don't know how why or how to solve it:问题是当我运行代码时出现以下错误,我不知道为什么或如何解决它:

AttributeError: Can't pickle local object 
    'get_MAX_SNR_for_eventdata_file.<locals>.get_SNR_multiprocess'

I don't know why it cannot pickle an object.我不知道为什么它不能腌制 object。 This is the code (which is inside a top-level function):这是代码(位于顶级函数内):

def get_SNR_multiprocess(binning, event_data, energy_interval, tstart, tstop, trigger_time):
    """ This function just changes the order of arguments to be able to use partial"""
    SNR=get_max_SNR_est(event_data, energy_interval, binning, tstart, tstop, trigger_time)
    return SNR

pool=multiprocessing.Pool(processes=4)

for i in range(len(energybands)-1):
    energy_interval=[energybands[i],energybands[i+1]]
    partial_func=partial(get_SNR_multiprocess, event_data=event_data, 
                         energy_interval=energy_interval, tstart=tstart, tstop=tstop, 
                         trigger_time=trigger_time)
    SNRlist=pool.map(partial_func,timescales)
pool.close()

I get a hint that the problem might have to do with the fact that only functions defined at top-level of a module can be pickled, according to What can be pickled?我得到一个提示,这个问题可能与只有在模块顶层定义的函数才能被腌制的事实有关,根据什么可以腌制? . . However, I cannot figure out exactly the problem in my code, or how to solve it.但是,我无法准确找出我的代码中的问题,或者如何解决它。

The function get_max_SNR_est in the code is a function defined in the same script and returns a value.代码中的 function get_max_SNR_est是在同一个脚本中定义的 function 并返回一个值。 This function is dependant on other function of the same script (which depends on another and so on...).这个 function 依赖于同一脚本的其他 function (这取决于另一个等等......)。

Just FYI, the code works without multiprocessing using a for loop, like:仅供参考,代码无需使用 for 循环进行多处理即可工作,例如:

SNRlist=[]
for i in range(len(energybands)-1):
    energy_interval=[energybands[i],energybands[i+1]]
    for binning in timescales:
        SNR=get_max_SNR_est(event_data, energy_interval, binning, tstart, tstop, 
                            trigger_time)
        SNRlist.append(SNR)

Edit : I forgot to put that the code that I am showing here is already in a function.编辑:我忘了说我在这里显示的代码已经在 function 中。 Based on @martineau's comment I took the function get_SNR_multiprocessing out of the aforementioned function, which solves the issue of pickling (see answer).根据@martineau 的评论,我将 function get_SNR_multiprocessing从上述 function 中取出,解决了酸洗问题(见答案)。

Thanks to @martineau's comment I found a solution for this issue.感谢@martineau 的评论,我找到了解决此问题的方法。 As I mentioned later in the edit of the questions, the code that I am showing here is already in a function.正如我稍后在问题编辑中提到的,我在这里显示的代码已经在 function 中。 I took the function get_SNR_multiprocessing out of the aforementioned function, which solves the issue of pickling.我从前面提到的function中取出了function get_SNR_multiprocessing ,解决了酸洗的问题。 The new code (where I am showing the function that contained the code shown above) looks like this:新代码(我在其中显示包含上述代码的 function)如下所示:

def get_SNR_multiprocess(binning, event_data, energy_interval, tstart, tstop, trigger_time):
    """ This function just changes the order of arguments to be able to use functools.partial for multiprocessing"""
    SNR=get_max_SNR_est(event_data, energy_interval, binning, tstart, tstop, trigger_time)
    return SNR

def get_MAX_SNR_for_eventdata_file(event_data, energybands, timescales, tstart, tstop, trigger_time):
    """
    Gives the maximum SNR of all timescales and energybands given for a given event_data file
    """ 
    SNRlist=[]
    for i in range(len(energybands)-1):
        energy_interval=[energybands[i],energybands[i+1]]

        with multiprocessing.Pool(processes=4) as pool:
            partial_func=partial(get_SNR_multiprocess, event_data=event_data, energy_interval=energy_interval, tstart=tstart, tstop=tstop, trigger_time=trigger_time)
            SNRlist=pool.map(partial_func,timescales)

Unfortunately, this method takes the same time as the original method with a for loop.不幸的是,此方法与带有for循环的原始方法所需的时间相同。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM