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

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

问题描述

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

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.)

知道可以做什么吗?

推荐答案

一种选择是使用 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天全站免登陆