2016-01-24 36 views
1

我使用Python来求解方程的反应扩散系统(Fitz-Hugh-Nagumo model)。我想了解如何使用Numba来加速计算。我目前进口下列laplacian.py模块到我的集成脚本:使用Numba来改善有限差分拉普拉斯算子

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的一维数组,它代表的领域之一。我试图在导入from numba import autojit后添加修饰符@autojit(target="cpu")。计算中我没有看到任何改进。任何人都可以给我一个提示,在这种情况下如何正确使用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

您是否有一些示例输入用于测试?你有一些表现指标吗? – M4rtini

+0

你使用哪个版本的numba?另外,如果您尝试将操作编写为标量元素的循环显式,您是否看到差异? 'u'的大小是多少? – JoshAdel

+0

@JoshAdel我使用numba 0.21.0 - 'print numba .__ version__ 0.21.0' – Ohm

回答

1

我无法复制你的结果。

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

numba版本:0.23.1

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 

我看到蟒2.7.11类似的结果和numba 0.23

>>100000 loops, best of 3: 19.1 µs per loop 
>>The slowest run took 8.55 times longer than the fastest. This could mean that an intermediate result is being cached 
>>100000 loops, best of 3: 2.4 µs per loop 
+0

我更新了Numba,我也看到了改进当我使用Numba时的性能。问题是如果我从不同的文件(这种情况下,实现FHN数学模型的类)导入此模块,我是否仍然会看到这种改进。据我了解,与Numba一起合作的课程有点问题.. – Ohm