使用多处理时Pickle中的MemoryError

2024-04-25 23:02:48 发布

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

我正在运行一些物理系统的蒙特卡罗模拟,我需要增加模拟时间步长的粒度(因此n_timesteps=t/dt,其中t是固定的)。这显然会延长每次模拟的运行时间(以及增加内存使用)。 正因为如此,我改变了我的代码,使我的所有处理器都使用pythons多重处理。 这适用于粗略模拟(较大的dt),但一旦降低dt,就会出现酸洗错误:

multiprocessing.pool.MaybeEncodingError: Error sending result: '<multiprocessing.pool.ExceptionWithTraceback object at 0x000000000B5D6EC8>'. Reason: 'PicklingError("Can't pickle <class 'MemoryError'>: it's not the same object as builtins.MemoryError")'

我使用一个软件包,它基本上完成了所有的模拟。因此,我的代码与此类似:

import numpy as np
import multiprocessing as mp
from specific_package import system_simulator

def subsimulation(parameter, other_parameters):
    n_montecarlo = 2
    simulator = system_simulator(other_parameters, n_montecarlo)
    # parameter is an numpy array of shape(n_timesteps, 13)
    simulator.set_parameters(parameter)  # At this point the error gets thrown
    results = simulator.calculate()
    # results will be a list of length n_montecarlo with each element contatining a list of length 
    # n_timesteps each containg a (4, 4) matrix (in a for the package specific dataformat)
    # results is then reduced to 4 numpy arrays of length n_timesteps each:
    a, b, c, d = np.ones(n_timesteps), np.ones(n_timesteps), np.ones(n_timesteps), np.ones(n_timesteps)
    return [a, b, c, d]


def run_simulation(foo):
    # does some stuff then run the simulations in parallel:
    runs = [i+1 for i in range(96)]  # As in total I want to have ~200 single simulations
    pool = mp.Pool(mp.cpu_count())
    results = pool.starmap_async(subsimulation, [(parameter, other_parameters) for run in runs]).get()
    pool.close()
    avg_res = np.mean(np.array(results), axis=0)
    return [avg_res[0], avg_res[1], avg_res[2], avg_res[3]]

例如,这个例子不适用于n_timesteps = 60000,我认为这实际上应该是可管理的。 我已经将每个子模拟中的模拟数量减少到了2个,这样内存使用量就相当小(以换取速度),并且pickle不必处理大型阵列。 但我真正不明白的是,当执行set_参数时会抛出错误,我不希望出现任何pickle操作

每个模拟都是相互独立的,并且需要相当长的时间,所以我认为:多处理在这里是个好主意。然而,由于我不是很有经验,特别是在多重处理方面,我真的不确定什么是解决这个问题的合适方法。 (我使用8核和8GB ram运行Windows-如果需要更多信息,我很乐意提供)


Tags: oftheinparameternp时间dtones
1条回答
网友
1楼 · 发布于 2024-04-25 23:02:48

好的,事实证明,问题实际上不是由pickle本身引起的,而是由模拟器包更新中的一个bug引起的,它试图创建一个大小为(n_timesteps,n_timesteps)的numpy数组。很抱歉搞混了

相关问题 更多 >