使用Numba来改善laplacian的有限差分

时间:2016-01-24 14:58:50

标签: python numpy numba

我正在使用Python来解决反应扩散方程组(Fitz-Hugh-Nagumo model)。我想学习如何使用Numba来加速计算。我目前正在将以下laplacian.py模块导入我的集成脚本:

def neumann_laplacian_1d(u,dx2):
    """Return finite difference Laplacian approximation of 2d array.
    Uses Neumann boundary conditions and a 2nd order approximation.
    """
    laplacian = np.zeros(u.shape)
    laplacian[1:-1] =  ((1.0)*u[2:] 
                       +(1.0)*u[:-2]
                       -(2.0)*u[1:-1])
    # Neumann boundary conditions
    # edges
    laplacian[0]  =  ((2.0)*u[1]-(2.0)*u[0])
    laplacian[-1] =  ((2.0)*u[-2]-(2.0)*u[-1])

    return laplacian/ dx2

其中u是NumPy 1D数组,代表其中一个字段。我在导入@autojit(target="cpu")后尝试添加装饰器from numba import autojit。我没有看到计算方面的任何改进。在这种情况下,有人能给我一个如何正确使用Numba的提示吗?

我在这里使用的输入数组是

a = random.random(252)

因此我将性能与线路进行了比较:

%timeit(neumann_laplacian_1d(a,1.0))

凭借Numba,我得到了:

%timeit(neumann_laplacian_1d(a,1.0))
The slowest run took 22071.00 times longer than the fastest. This could mean that an intermediate result is being cached 
1 loops, best of 3: 14.1 µs per loop

没有Numba我得到了(!!):

%timeit(neumann_laplacian_1d(a,1.0))
The slowest run took 11.84 times longer than the fastest. This could mean that an intermediate result is being cached 
100000 loops, best of 3: 9.12 µs per loop

Numba实际上让它变慢了..

1 个答案:

答案 0 :(得分:1)

我无法复制您的搜索结果。

Python版本:3.4.4 | Anaconda 2.4.1(64位)| (默认,2016年1月19日,12:10:59)[MSC v.1600 64 bit(AMD64)]

numba版本:0.23.1

"fr"

我看到python 2.7.11和numba 0.23

的类似结果
import numba as nb
import numpy as np

def neumann_laplacian_1d(u,dx2):
    """Return finite difference Laplacian approximation of 2d array.
    Uses Neumann boundary conditions and a 2nd order approximation.
    """
    laplacian = np.zeros(u.shape)
    laplacian[1:-1] =  ((1.0)*u[2:] 
                       +(1.0)*u[:-2]
                       -(2.0)*u[1:-1])
    # Neumann boundary conditions
    # edges
    laplacian[0]  =  ((2.0)*u[1]-(2.0)*u[0])
    laplacian[-1] =  ((2.0)*u[-2]-(2.0)*u[-1])

    return laplacian/ dx2

@nb.autojit(nopython=True)
def neumann_laplacian_1d_numba(u,dx2):
    """Return finite difference Laplacian approximation of 2d array.
    Uses Neumann boundary conditions and a 2nd order approximation.
    """
    laplacian = np.zeros(u.shape)
    laplacian[1:-1] =  ((1.0)*u[2:] 
                       +(1.0)*u[:-2]
                       -(2.0)*u[1:-1])
    # Neumann boundary conditions
    # edges
    laplacian[0]  =  ((2.0)*u[1]-(2.0)*u[0])
    laplacian[-1] =  ((2.0)*u[-2]-(2.0)*u[-1])

    return laplacian/ dx2

a = np.random.random(252)
#run once to make the JIT do it's work before timing
neumann_laplacian_1d_numba(a, 1.0)


%timeit neumann_laplacian_1d(a, 1.0)
%timeit neumann_laplacian_1d_numba(a, 1.0)

>>10000 loops, best of 3: 21.5 µs per loop
>>The slowest run took 4.49 times longer than the fastest. This could mean that an intermediate result is being cached 
>>100000 loops, best of 3: 3.53 µs per loop
相关问题