當前位置:
首頁 > 知識 > Numba:基於CUDA加速的高性能Python

Numba:基於CUDA加速的高性能Python


[注意:這篇文章最初於2013年9月19日發布,後於2017年9月19日更新。]

Python是一種高效率的動態編程語言,廣泛應用於科學,工程和數據分析等領域。導致python如此流行的原因有很多,主要有其簡潔且易於理解的語法和標準的數據結構,廣泛的功能齊備的標準庫,優秀的文檔,庫和工具構成的良好的生態系統,專業支持的可用性以及大而開放的社區。也許最重要的是,像Python這樣的動態類型解釋語言的高效率。Python是靈活的,這使其成為可用於快速原型設計的一種很好的語言,同時也能用於構建完整的系統。


但Python最大的優勢也可能是其最大的弱點:其靈活性和無類型的高級語法可能導致數據和計算密集型程序的性能不佳。因此,關心效率的Python程序員通常會用C重寫最內層的循環,並從Python調用編譯好的C函數。有許多旨在使此優化更容易的項目(如Cython),但它們通常需要學習新的語法。理想情況下,Python程序員希望使現有的Python代碼更快,而不需要使用另一種編程語言,而且自然,很多人希望使用加速器從而使代碼具有更高的性能。


Numba:高效的高性能計算


這篇文章將向您介紹基於Anaconda的Python編譯器Numba,它可以編譯Python代碼,以便在支持CUDA在GPU或多核CPU上執行。由於Python通常不是編譯語言,您可能會想知道為什麼需要Python編譯器。答案當然是運行本地已編譯代碼比運行動態解釋代碼快許多倍。Numba通過允許您指定Python函數的類型簽名,從而在運行時進行編譯(這叫「即時編譯」或JIT編譯)。Numba動態編譯代碼的能力意味著可以不失Python的靈活性。這是提供高效率編程和高性能計算的理想組合的巨大一步。

使用Numba可以編寫標準的Python函數,並在支持CUDA的GPU上運行它們。Numba專為面向數組的計算任務而設計,就像廣泛使用的NumPy庫一樣。面向數組的計算任務中的數據並行性對於像GPU這樣的加速器來說是恰好適合的。Numba可以讀取NumPy數組類型,並使用它們來生成有效的編譯代碼,用於在GPU或多核CPU上執行。所需的編程工作可以像添加函數裝飾器來指示Numba為GPU編譯一樣簡單。例如,以下代碼中的@vectorize裝飾器在運行時生成標量函數的一個編譯的,向量化版本Add函數,以便可以在GPU上並行處理數據數組。



要在CPU上編譯和運行相同的函數,我們只需將目標更改為「cpu」,從而在CPU上提供編譯,向量化的C代碼級別的性能。這種靈活性可以幫助您生成更多可重用的代碼,並可讓您在沒有GPU的機器上進行開發。


Python的GPU加速庫


CUDA並行計算平台的優勢之一是其可用的GPU加速庫的廣泛性。Numba團隊的另一個項目叫做pyculib,為CUDA cuBLAS(密集線性代數),cuFFT(快速傅里葉變換)和cuRAND(隨機數生成)庫提供了一個Python介面。許多應用程序將能夠從使用這些庫中得到明顯加速,而無需編寫任何特定於GPU的代碼。例如,以下代碼使用「XORWOW」偽隨機數生成器在GPU上生成百萬個均勻分布的隨機數。


CUDA Python的大規模並行


Anaconda(以前的Continuum Analytics)認識到,在某些計算上實現大幅度加速需要一個更易於理解的編程介面,與庫和自動循環向量化相比需要對並行度有更細節上的控制。因此,Numba具有另一個重要的功能,它們構成了被稱為「CUDA Python」的功能。Numba公開了CUDA編程模型,就像CUDA C/C ++一樣,但使用純python語法,以便程序員可以創建自定義調優的並行內核,而不會丟失Python的舒適和優點。Numba的CUDA JIT(可通過裝飾器或函數調用獲得)在運行時編譯CUDA Python函數,專門針對您使用的類型,其CUDA Python API提供對數據傳輸和CUDA流的顯式控制以及其他功能。



以下代碼示例使用簡單的Mandelbrot集內核來示範。注意,mandel_kernel函數使用Numba提供的cuda.threadIdx, cuda.blockIdx, cuda.blockDim和cuda.gridDim結構來計算當前線程的全局X和Y像素索引。與其他CUDA語言一樣,我們通過在函數名稱和參數列表(mandel_kernel[griddim, blockdim](-2.0, 1.0, -1.0, 1.0, d_image, 20))之間的括弧中插入一個「執行配置」(CUDA--用於運行內核的線程數和線程塊)來啟動內核。您還可以看到使用to_host和to_device API函數將數據複製到GPU或從GPU複製數據。

您可以在Github上獲得Mandelbrot示例的完整Jupyter Notebook。




在具有NVIDIA Tesla P100 GPU和Intel Xeon E5-2698 v3 CPU的伺服器上,該CUDA Python Mandelbrot代碼運行速度比純Python版本快近1700倍。1700x似乎是一個不切實際的加速,但請記住,我們進行比較的是編譯並行GPU加速的Python代碼與CPU上的解釋型單線程Python代碼。

Numba入門


Numba為Python開發人員提供了一個輕鬆入門GPU加速計算的途徑,為越來越複雜的CUDA代碼提供了最新的語法和行話。您可以從簡單的函數裝飾器開始來自動編譯您的函數,或使用由pyculib公開的功能強大的CUDA庫。當您對並行編程概念的理解提高後,當您需要對並行線程進行易於理解且靈活的控制時,CUDA可以提供幫助,而不需要您在一開始就使用。


Numba是一個BSD許可的開源項目,它本身在很大程度上依賴於LLVM編譯器的功能。Numba的GPU後端使用基於LLVM的NVIDIA編譯器SDK。該pyculib圍繞CUDA包裝的庫也是BSD許可的開源項目。


要開始使用Numba,第一步是下載並安裝Anaconda Python發行版,這是一個「完全免費的企業級Python發行版,用於大規模數據處理,預測分析和科學計算」,包括許多流行的包(Numpy, Scipy,Matplotlib,iPython等)和「conda」,一個強大的包管理器。安裝Anaconda後,通過輸入conda install numba cudatoolkit pyculib安裝所需的CUDA包。然後在ContinuumIO github資源庫中查看CUDA的Numba教程。我也建議您在Anaconda博客上查看關於Numba的帖子。





英文原文:https://devblogs.nvidia.com/parallelforall/numba-python-cuda-acceleration/


譯者:Chara

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 Python程序員 的精彩文章:

Django2.0即將帶來3個重要特性
不能錯過的10篇經典推文
Python王者都是這樣處理文件路徑的
Python3.6初體驗:數字字元串神操作
月考+Python軟體也會中毒,請謹慎預防並及時殺毒。

TAG:Python程序員 |