numba學習教程

1、對於python的基礎介紹python

     Python是一種高效的動態編程語言,普遍用於科學,工程和數據分析應用程序。。影響python普及的因素有不少,包括乾淨,富有表現力的語法和標準數據結構,全面的「電池包含」標準庫,優秀的文檔,普遍的圖書館和工具生態系統,專業支持的可用性以及大而開放社區。但也許最重要的是,像Python這樣的動態類型化解釋語言可以實現高效率。Python靈活靈活,使其成爲快速原型設計的理想語言,同時也是構建完整系統的理想語言。
可是Python的最大優點也多是它最大的弱點:它的靈活性和無類型的高級語法可能致使數據和計算密集型程序的性能不佳。git

2、numba--高性能高效率的計算程序員

     在這篇文章中,我將向您介紹Numba,一個來自Anaconda的Python編譯器,能夠編譯Python代碼,以便在支持CUDA的GPU或多核CPU上執行。因爲Python一般不是編譯語言,您可能想知道爲何要使用Python編譯器。答案固然是運行本機編譯代碼比運行動態解釋代碼快許多倍。 Numba容許您爲Python函數指定類型簽名,它能夠在運行時進行編譯(這是「即時」或JIT編譯)。 Numba動態編譯代碼的能力意味着您不會放棄Python的靈活性。這是向高效率編程和高性能計算提供理想組合的重要一步。    github

     使用Numba,如今能夠編寫標準的Python函數並在支持CUDA的GPU上運行它們。 Numba專爲面向陣列的計算任務而設計,就像普遍使用的NumPy庫同樣。面向陣列的計算任務中的數據並行性很是適合GPU等加速器。 Numba瞭解NumPy數組類型,並使用它們生成有效的編譯代碼,以便在GPU或多核CPU上執行。所需的編程工做能夠像添加函數裝飾器同樣簡單,以指示Numba爲GPU編譯。例如,如下代碼中的@vectorize裝飾器在運行時生成標量函數Add的已編譯矢量化版本,以便它可用於在GPU上並行處理數據數組編程

imort numpy as np
from numba import vectorize

@vectorize(['float32(float32, float32)'], target='cuda')
def Add(a, b):
  return a + b

# Initialize arrays
N = 100000
A = np.ones(N, dtype=np.float32)
B = np.ones(A.shape, dtype=A.dtype)
C = np.empty_like(A, dtype=A.dtype)

# Add arrays on GPU
C = Add(A, B)

     要在CPU上編譯和運行相同的函數,咱們只需將目標更改成「cpu」,從而在CPU上編譯的矢量化C代碼級別上產生性能。 這種靈活性可幫助您生成更多可重用的代碼,並容許您在沒有GPU的計算機上進行開發。  後端

3、用於Python的GPU加速庫
     CUDA並行計算平臺的優點之一是其普遍的GPU加速庫。 Numba團隊的另外一個名爲pyculib的項目爲CUDA cuBLAS(密集線性代數),cuFFT(快速傅立葉變換)和cuRAND(隨機數生成)庫提供了Python接口。 許多應用程序只需使用這些庫就能夠得到顯着的加速,而無需編寫任何特定於GPU的代碼。 例如,如下代碼使用「XORWOW」僞隨機數生成器在GPU上生成一百萬個均勻分佈的隨機數。
數組

import numpy as np
from pyculib import rand as curand

prng = curand.PRNG(rndtype=curand.PRNG.XORWOW)
rand = np.empty(100000)
prng.uniform(rand)
print rand[:10]

4、與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語言同樣,咱們經過在函數名稱和參數列表之間插入一個「執行配置」(CUDA-表明用於運行內核的線程數和線程數)來啓動內核:mandel_kernel [griddim,blockdim]( -  2.0,1.0,-1.0,1.0,d_image,20)。 您還能夠看到使用to_host和to_device API函數將數據複製到GPU或從GPU複製數據。數據結構

@cuda.jit(device=True)
def mandel(x, y, max_iters):
  """
  Given the real and imaginary parts of a complex number,
  determine if it is a candidate for membership in the Mandelbrot
  set given a fixed number of iterations.
  """
  c = complex(x, y)
  z = 0.0j
  for i in range(max_iters):
    z = z*z + c
    if (z.real*z.real + z.imag*z.imag) >= 4:
      return i

  return max_iters

@cuda.jit
def mandel_kernel(min_x, max_x, min_y, max_y, image, iters):
  height = image.shape[0]
  width = image.shape[1]

  pixel_size_x = (max_x - min_x) / width
  pixel_size_y = (max_y - min_y) / height

  startX = cuda.blockDim.x * cuda.blockIdx.x + cuda.threadIdx.x
  startY = cuda.blockDim.y * cuda.blockIdx.y + cuda.threadIdx.y
  gridX = cuda.gridDim.x * cuda.blockDim.x;
  gridY = cuda.gridDim.y * cuda.blockDim.y;

  for x in range(startX, width, gridX):
    real = min_x + x * pixel_size_x
    for y in range(startY, height, gridY):
      imag = min_y + y * pixel_size_y 
      image[y, x] = mandel(real, imag, iters)

gimage = np.zeros((1024, 1536), dtype = np.uint8)
blockdim = (32, 8)
griddim = (32,16)

start = timer()
d_image = cuda.to_device(gimage)
mandel_kernel[griddim, blockdim](-2.0, 1.0, -1.0, 1.0, d_image, 20) 
d_image.to_host()
dt = timer() - start

print "Mandelbrot created on GPU in %f s" % dt

imshow(gimage)
On a server with an NVIDIA Tesla P100 GPU and an Intel Xeon E5-2698 v3 CPU, this CUDA Python Mandelbrot code runs nearly 1700 times faster than the pure Python version. 1700x may seem an unrealistic speedup, but keep in mind that we are comparing compiled, parallel, GPU-accelerated Python code to interpreted, single-threaded Py

     在配備NVIDIA Tesla P100 GPU和Intel Xeon E5-2698 v3 CPU的服務器上,此CUDA Python Mandelbrot代碼的運行速度比純Python版快近1700倍。 1700x可能看起來不切實際,但請記住,咱們正在將編譯的,並行的,GPU加速的Python代碼與CPU上的解釋的單線程Python代碼進行比較。、編程語言

 4、 當即開始使用Numba      Numba爲Python開發人員提供了一種輕鬆進入GPU加速計算的途徑,以及使用日益複雜的CUDA代碼並使用最少的新語法和術語的途徑。您能夠從簡單的函數裝飾器開始,自動編譯您的函數,或使用pyculib公開的強大的CUDA庫。隨着您對並行編程概念的理解以及當您須要對並行線程進行表達和靈活控制時,CUDA可用,而無需您在第一天進入。     Numba是一個得到BSD許可的開源項目,它自己在很大程度上依賴於LLVM編譯器的功能。 Numba的GPU後端使用基於LLVM的NVIDIA編譯器SDK。   CUDA庫周圍的pyculib包裝器也是開源和BSD許可的。     要開始使用Numba,第一步是下載並安裝Anaconda Python發行版,這是一個「徹底免費的企業級Python發行版,用於大規模數據處理,預測分析和科學計算」,其中包括許多流行的軟件包(Numpy, Scipy,Matplotlib,iPython等)和「conda」,一個強大的包管理器。安裝Anaconda後,鍵入conda install numba cudatoolkit pyculib安裝所需的CUDA軟件包。而後在ContinuumIO github存儲庫上查看CumbA的Numba教程。我還建議您查看Anaconda博客上的Numba帖子。

相關文章
相關標籤/搜索