天天看點

Python高性能計算庫——Numba

<b></b>

<b>1.那麼到底什麼是Numba?</b><b></b>

<b>2.怎麼才能get到Numba呢?</b><b></b>

安裝Numba的推薦方法是使用conda包管理

conda install numba

你也可以用pip來安裝Numba,但是最新版本的釋出才一天之久。但是,隻要你能夠使用conda,我會推薦使用它,因為它能夠為你安裝例如CUDA工具包,也許你想讓你的Python代碼GPU就緒(當然,這也是有可能的!)。

<b>3.如何使用Numba呢?</b><b></b>

使用它的要求不多。基本上,你寫一個自己的“普通”的Python函數,然後給函數定義添加一個裝飾(如果你不是很熟悉裝飾器,讀一下關于this或that)。你可以使用不同類型的裝飾器,但@jit可能是剛開始的選擇之一。其他裝飾器可用于例如建立numpy通用功能@vectorize或編寫将在CUDA GPU上執行的代碼@cuda。我不會在這篇文章中介紹這些裝飾。現在,讓我們來看看基本的步驟。他們提供的代碼示例是2d數組的求和函數,以下是代碼:

from numba import jit

from numpy import arange

# jit decorator tells Numba to compile this function.# The argument types will be inferred by Numba when function is called.

@jit

<b>def</b> <b>sum2d</b>(arr):

    M, N <b>=</b> arr<b>.</b>shape

    result <b>=</b> 0.0

    <b>for</b> i <b>in</b> range(M):

        <b>for</b> j <b>in</b> range(N):

            result <b>+=</b> arr[i,j]

    <b>return</b> result

a <b>=</b> arange(9)<b>.</b>reshape(3,3)

<b>print</b>(sum2d(a))

Okay,現在我們來看看我們get到了什麼。我們将使用最簡單的子產品之一,由MB Fiering在1967年出于教育目的開發的ABC模型,并将Python代碼的速度與Numba優化後Python代碼和Fortran實作進行比較。請注意這個模型不是我們在現實中使用的(正如名稱所示),但是我認為這可能是一個不錯的想法來舉例。

A、B、C子產品是一個三個參數子產品(a,b,c,習慣性命名),它隻接收下雨量為輸入,隻有一個存儲。土壤水分蒸發蒸騰損失總量(參數b),另一部分通過土壤滲透到地下水儲存(參數a),最後一個參數c代表地下水總量,離開地下變成河流。Python中的代碼,使用Numpy數組可能會像如下所示:

import numpy as np

<b>def</b> <b>abc_model_py</b>(a, b, c, rain):

    # initialize array for the stream discharge of each time step

    outflow <b>=</b> np<b>.</b>zeros((rain<b>.</b>size), dtype<b>=</b>np<b>.</b>float64)

    # placeholder, in which we save the storage content of the previous and

    # current timestep

    state_in <b>=</b> 0

    state_out <b>=</b> 0

    <b>for</b> i <b>in</b> range(rain<b>.</b>size):

        # Update the storage

        state_out <b>=</b> (1 <b>-</b> c) <b>*</b> state_in <b>+</b> a <b>*</b> rain[i]

        # Calculate the stream discharge

        outflow[i] <b>=</b> (1 <b>-</b> a <b>-</b> b) <b>*</b> rain[i] <b>+</b> c <b>*</b> state_out

        state_in <b>=</b> state_out

    <b>return</b> outflow

接下來我們使用Numba來實作相同的功能。

<b>def</b> <b>abc_model_numba</b>(a, b, c, rain):

我用随機數字作為輸入來運作這些子產品,這隻是為了比較計算時間,而且也比較了針對fortran實作的時間(詳見here)。我們來看看數字:

py_time <b>=</b> <b>%</b>timeit <b>-</b>r 5 <b>-</b>n 10 <b>-</b>o abc_model_py(0.2, 0.6, 0.1, rain)

<b>&gt;&gt;</b> 6.75 s ± 11.6 ms per loop (mean ± std<b>.</b> dev<b>.</b> of 5 runs, 10 loops each)

# Measure the execution time of the Numba implementation

numba_time <b>=</b> <b>%</b>timeit <b>-</b>r 5 <b>-</b>n 10 <b>-</b>o abc_model_numba(0.2, 0.6, 0.1, rain)

<b>&gt;&gt;</b> 30.6 ms ± 498 µs per loop (mean ± std<b>.</b> dev<b>.</b> of 5 runs, 10 loops each)

# Measure the execution time of the Fortran implementation

fortran_time <b>=</b> <b>%</b>timeit <b>-</b>r 5 <b>-</b>n 10 <b>-</b>o abc_model_fortran(0.2, 0.6, 0.1, rain)

<b>&gt;&gt;</b> 31.9 ms ± 757 µs per loop (mean ± std<b>.</b> dev<b>.</b> of 5 runs, 10 loops each)

# Compare the pure Python vs Numba optimized time

py_time<b>.</b>best <b>/</b> numba_time<b>.</b>best

<b>&gt;&gt;</b> 222.1521754580626

# Compare the time of the fastes numba and fortran run

numba_time<b>.</b>best <b>/</b> fortran_time<b>.</b>best

<b>&gt;&gt;</b> 0.9627960721576471

通過添加一個裝飾器,我們的計算速度比純Python代碼快222倍,甚至比Fortran也快很多。在計算能力決定未來的時代,Numba一定會被更多人接受。

以上就是我的介紹,希望有人現在有動力去看看Numba庫。我想在将來我會編寫一系列小的Numba文章/教程,并提供更多的技術資訊,讓更多的人使用Numba 庫。而本文僅作為一個開始。

文章原标題《Introduction to the Numba library》

作者:Flaire  

譯者:一隻高冷的貓,審校:袁虎。