多个scipy.integrate.ode实例

时间:2015-12-15 14:23:18

标签: python scipy python-multithreading ode odeint

我想在多线程(每个CPU核心一个)中使用 scipy.integrate.ode (或scipy.integrate.odeint)实例来解决一次多个IVP。但文档说:“此集成器不可重入。您不能同时使用”vode“集成器的两个ode实例。

(如果文档没有说明,odeint会在多次实例化时导致内部错误。)

知道可以做些什么吗?

2 个答案:

答案 0 :(得分:9)

一种选择是使用multiprocessing(即使用进程而不是线程)。以下是使用map类的multiprocessing.Pool函数的示例。

函数solve采用一组初始条件并返回由odeint生成的解决方案。主要部分中代码的“序列”版本重复调用solve,对ics中的每组初始条件进行一次调用。 “多处理”版本使用map实例的multiprocessing.Pool函数同时运行多个进程,每个进程调用solvemap函数负责将参数传递给solve

我的计算机有四个内核,当我增加num_processes时,加速最大值大约为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.")

在我的电脑上,输出为:

multiprocessing:    6.904 seconds
serial:            24.756 seconds
num_processes = 5, speedup = 3.59

答案 1 :(得分:0)

SciPy.integrate.ode似乎使用LLNL SUNDIALS solvers,尽管SciPy不使用say so explicitly,但我认为应该使用。{p>

CVODE ode求解器的当前版本3.2.2是可重入的,这意味着它可以用于同时解决多个问题。相关信息显示在User Documentation for CVODE v3.2.0 (SUNDIALS v3.2.0)中。

  

cvode用于解决给定问题的所有状态信息都保存在一个结构中,并保存一个指针   将该结构返回给用户。 cvode软件包中没有全局数据,因此,在此   尊重,这是可重入的。线性求解器的特定状态信息保存在单独的结构中,   指向cvode内存结构中的指针。 cvode的重新进入是有动机的   通过预期的多计算机扩展,但在单处理器设置中也是必不可少的,其中两个   或通过在单个用户程序中混合调用该程序包可以解决更多问题。

但是我不知道SciPy.integrate.ode或其他scikits.odes.ode之类的ode求解器是否支持这种并发。