多个scipy.integrate.ode实例 [英] Multiple scipy.integrate.ode instances

查看:188
本文介绍了多个scipy.integrate.ode实例的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在多个线程(每个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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆