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!