Heim  >  Artikel  >  Backend-Entwicklung  >  Eine detaillierte Einführung in das Schreiben von CUDA-Programmen mit Python

Eine detaillierte Einführung in das Schreiben von CUDA-Programmen mit Python

高洛峰
高洛峰Original
2017-03-28 09:29:194245Durchsuche

Der folgende Editor bringt Ihnen einen Artikel darüber, wie Sie CUDA-Programme mit Python schreiben. Der Herausgeber findet es ziemlich gut, deshalb werde ich es jetzt mit Ihnen teilen und es allen als Referenz geben. Folgen wir dem Editor und werfen wir einen Blick darauf.

Es gibt zwei Möglichkeiten, Python zum Schreiben von CUDA-Programmen zu verwenden:

* Numba
* PyCUDA

Numbapro ist jetzt veraltet und die Funktionen wurden aufgeteilt und in Accelerate bzw. Numba integriert.

Beispiel

numba

Numba verwendet Just-in- Zeitkompilierungsmechanismus (JIT) zur Optimierung von Python-Code. Numba kann für die lokale Hardwareumgebung optimiert werden, unterstützt sowohl CPU- als auch GPU-Optimierung und kann in Numpy integriert werden, sodass Python-Code auf der GPU ausgeführt werden kann, nur im Funktion Fügen Sie oben relevante Befehls-Tags hinzu,

wie folgt:

import numpy as np 
from timeit import default_timer as timer
from numba import vectorize
@vectorize(["float32(float32, float32)"], target='cuda')
def vectorAdd(a, b):
  return a + b
def main():
  N = 320000000
  A = np.ones(N, dtype=np.float32 )
  B = np.ones(N, dtype=np.float32 )
  C = np.zeros(N, dtype=np.float32 )
  start = timer()
  C = vectorAdd(A, B)
  vectorAdd_time = timer() - start
  print("c[:5] = " + str(C[:5]))
  print("c[-5:] = " + str(C[-5:]))
  print("vectorAdd took %f seconds " % vectorAdd_time)
if name == 'main':
  main()

PyCUDA

Die Kernelfunktion (Kernel) von PyCUDA ist tatsächlich in C/C++ geschrieben. Sie wird dynamisch in GPU-Mikrocode kompiliert und der Python-Code interagiert mit dem GPU-Code, wie unten gezeigt:

import pycuda.autoinit
import pycuda.driver as drv
import numpy as np
from timeit import default_timer as timer
from pycuda.compiler import SourceModule
mod = SourceModule("""
global void func(float *a, float *b, size_t N)
{
 const int i = blockIdx.x * blockDim.x + threadIdx.x;
 if (i >= N)
 {
  return;
 }
 float temp_a = a[i];
 float temp_b = b[i];
 a[i] = (temp_a * 10 + 2 ) * ((temp_b + 2) * 10 - 5 ) * 5;
 // a[i] = a[i] + b[i];
}
""")
func = mod.get_function("func")  
def test(N):
  # N = 1024 * 1024 * 90  # float: 4M = 1024 * 1024
  print("N = %d" % N)
  N = np.int32(N)
  a = np.random.randn(N).astype(np.float32)
  b = np.random.randn(N).astype(np.float32)  
  # copy a to aa
  aa = np.empty_like(a)
  aa[:] = a
  # GPU run
  nTheads = 256
  nBlocks = int( ( N + nTheads - 1 ) / nTheads )
  start = timer()
  func(
      drv.InOut(a), drv.In(b), N,
      block=( nTheads, 1, 1 ), grid=( nBlocks, 1 ) )
  run_time = timer() - start 
  print("gpu run time %f seconds " % run_time)  
  # cpu run
  start = timer()
  aa = (aa * 10 + 2 ) * ((b + 2) * 10 - 5 ) * 5
  run_time = timer() - start 
  print("cpu run time %f seconds " % run_time) 
  # check result
  r = a - aa
  print( min(r), max(r) )
def main():
 for n in range(1, 10):
  N = 1024 * 1024 * (n * 10)
  print("------------%d---------------" % n)
  test(N)
if name == 'main':
  main()

Vergleich

numba verwendet einige Anweisungen, um bestimmte Funktionen für die Beschleunigung zu markieren (Kernelfunktionen können auch in Python geschrieben werden), was ähnlich ist OpenACC und PyCUDA Sie müssen den Kernel selbst schreiben und zur Laufzeit kompilieren. Die unterste Ebene wird basierend auf C/C++ implementiert. Durch Tests sind die Beschleunigungsverhältnisse dieser beiden Methoden grundsätzlich gleich. Allerdings ähnelt Numba eher einer Blackbox und man weiß nicht, was intern geschieht, während PyCUDA sehr intuitiv zu sein scheint. Daher haben diese beiden Methoden unterschiedliche Anwendungen:

* Wenn Sie nur Ihren eigenen Algorithmus beschleunigen möchten und sich nicht um die CUDA-Programmierung kümmern, ist es besser, Numba direkt zu verwenden.

* Wenn Sie CUDA-Programmierung erlernen und erforschen oder mit der Machbarkeit eines bestimmten Algorithmus unter CUDA experimentieren möchten, dann verwenden Sie PyCUDA.

* Wenn das von Ihnen geschriebene Programm in Zukunft nach C/C++ portiert wird, müssen Sie PyCUDA verwenden, da der mit PyCUDA selbst geschriebene Kernel in CUDA C/C++ geschrieben ist.

Das obige ist der detaillierte Inhalt vonEine detaillierte Einführung in das Schreiben von CUDA-Programmen mit Python. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn