多个scipy.integrate.ode实例 [英] Multiple scipy.integrate.ode instances
问题描述
我想在多个线程(每个CPU内核一个)中使用 scipy.integrate.ode (或scipy.integrate.odeint)实例,以便解决一次有多个IVP.但是文档中说:"该集成器不是可重入的.您不能同时使用"vode"集成器来拥有两个ode实例."
I would like to use scipy.integrate.ode (or scipy.integrate.odeint) instances in multiple threads (one for each CPU core) in order to solve multiple IVPs at a time. However the documentation says: "This integrator is not re-entrant. You cannot have two ode instances using the "vode" integrator at the same time."
(尽管文档未说明,但多次实例化odeint也会导致内部错误.)
(Also odeint causes internal errors if instantiated multiple times although the documentation does not say so.)
任何想法都可以做什么?
Any idea what can be done?
推荐答案
一种选择是使用 multiprocessing
(即使用进程而不是线程).这是一个使用multiprocessing.Pool
类的map
函数的示例.
One option is to use multiprocessing
(i.e. use processes instead of threads). Here's an example that uses the map
function of the multiprocessing.Pool
class.
函数solve
具有一组初始条件,并返回由odeint
生成的解决方案.主要部分中代码的串行"版本重复调用solve
,对于ics
中的每个初始条件集一次. 多重处理"版本使用multiprocessing.Pool
实例的map
函数来同时运行多个进程,每个进程都调用solve
. map
函数负责将参数分配给solve
.
The function solve
takes a set of initial conditions and returns a solution generated by odeint
. The "serial" version of the code in the main section calls solve
repeatedly, once for each set of initial conditions in ics
. The "multiprocessing" version uses the map
function of a multiprocessing.Pool
instance to run several processes simultaneously, each calling solve
. The map
function takes care of doling out the arguments to solve
.
我的计算机有四个核心,并且随着我增加num_processes
,其加速最高可达到3.6.
My computer has four cores, and as I increase num_processes
, the speedup maxes out at about 3.6.
from __future__ import division, print_function
import sys
import time
import multiprocessing as mp
import numpy as np
from scipy.integrate import odeint
def lorenz(q, t, sigma, rho, beta):
x, y, z = q
return [sigma*(y - x), x*(rho - z) - y, x*y - beta*z]
def solve(ic):
t = np.linspace(0, 200, 801)
sigma = 10.0
rho = 28.0
beta = 8/3
sol = odeint(lorenz, ic, t, args=(sigma, rho, beta), rtol=1e-10, atol=1e-12)
return sol
if __name__ == "__main__":
ics = np.random.randn(100, 3)
print("multiprocessing:", end='')
tstart = time.time()
num_processes = 5
p = mp.Pool(num_processes)
mp_solutions = p.map(solve, ics)
tend = time.time()
tmp = tend - tstart
print(" %8.3f seconds" % tmp)
print("serial: ", end='')
sys.stdout.flush()
tstart = time.time()
serial_solutions = [solve(ic) for ic in ics]
tend = time.time()
tserial = tend - tstart
print(" %8.3f seconds" % tserial)
print("num_processes = %i, speedup = %.2f" % (num_processes, tserial/tmp))
check = [(sol1 == sol2).all()
for sol1, sol2 in zip(serial_solutions, mp_solutions)]
if not all(check):
print("There was at least one discrepancy in the solutions.")
在我的计算机上,输出为:
On my computer, the output is:
multiprocessing: 6.904 seconds
serial: 24.756 seconds
num_processes = 5, speedup = 3.59
这篇关于多个scipy.integrate.ode实例的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!