2016-01-24 82 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