在Python 3.6上,我定义了一个类foo
,该类实例化了一个对象p
。在实例化时,该类执行计算量大的插值并将插值函数“附加”到对象。
完成此操作后,就可以调用其他类方法,而无需再次插值。到目前为止,一切都很好。
下面的代码显示了一个最小的工作示例:
import numpy as np
from scipy.integrate import quad
from scipy.interpolate import interp1d
class foo(object):
def __init__(self):
self.func = self.interp()
def interp(self):
def integrand(x): return self.shape(x)
xpoints = np.arange(100)
ypoints = [quad(
integrand, a=-np.inf, b=np.inf
)[0]/x for x in xpoints]
I = interp1d(xpoints, ypoints)
return I
def shape(self, x):
F = x**2 # complicated maths here
return F
然后我使用p
对象执行繁重的任务。我将其并行化以进行优化。我像这样使用multiprocessing
库:
import multiprocessing as mp
with mp.Pool(mp.cpu_count()) as pool:
results = pool.map(func, list(bar)) # func uses my p instance
我收到一个错误MaybeEncodingError: Error sending result...
,它的回溯表明我的插值函数无法修复。
我不知道如何腌制interp1d
,并且我不想更改当前代码的结构,因为这已经经过了深思熟虑,而且我认为它是最有效的格式。我可以增加几行以使插值函数成为顶级函数吗?
我尝试使用joblib
,它一直抱怨内存问题(即使使用了1个CPU)。
就我而言,multiprocessing
确实可以胜任。它实际上完成了工作,在终端中输出结果,但是无法将所有结果汇总在一起。我要并行化的可迭代项中的所有项都是完全独立的。
答案 0 :(得分:2)
池使用多处理队列在进程之间传输数据。这些队列仅对可腌制数据起作用。腌制的功能仅按名称存储,然后由取消腌制的人重新导入。自然,这意味着它们必须是可导入的。
通常有一些方法可以解决这些酸洗问题,但可以避免麻烦,而安装pathos
。它的多处理池使用dill
可以腌制几乎所有东西。