Maison >développement back-end >Tutoriel Python >Une introduction détaillée à la façon d'écrire des programmes CUDA en utilisant Python

Une introduction détaillée à la façon d'écrire des programmes CUDA en utilisant Python

高洛峰
高洛峰original
2017-03-28 09:29:194314parcourir

L'éditeur ci-dessous vous proposera un article sur la façon d'écrire des programmes CUDA en utilisant Python. L'éditeur le trouve plutôt bon, je vais donc le partager avec vous maintenant et le donner comme référence pour tout le monde. Suivons l'éditeur et jetons un coup d'œil

Il existe deux façons d'utiliser Python pour écrire des programmes CUDA :

* Numba
* PyCUDA

Numbapro est désormais obsolète et les fonctions ont été divisées et intégrées respectivement dans Accélération et Numba.

Exemple

numba

Numba utilise le just-in -mécanisme de compilation temporelle (JIT) pour optimiser le code Python, Numba peut être optimisé pour l'environnement matériel local, prend en charge l'optimisation du CPU et du GPU et peut être intégré à Numpy afin que le code Python puisse s'exécuter sur le GPU, uniquement dans le fonction Ajoutez les balises de commande pertinentes ci-dessus,

comme suit :

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

La fonction noyau (noyau) de PyCUDA est en fait écrite en C/C++. Elle est compilée dynamiquement dans le microcode GPU, et le code Python interagit avec le code GPU, comme indiqué ci-dessous :

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()

Comparaison

numba utilise certaines instructions pour marquer certaines fonctions pour l'accélération (les fonctions du noyau peuvent également être écrites en Python), ce qui est similaire vers OpenACC et PyCUDA Vous devez écrire le noyau vous-même et le compiler au moment de l'exécution. La couche inférieure est implémentée sur la base de C/C++. Grâce aux tests, les taux d'accélération de ces deux méthodes sont fondamentalement les mêmes. Cependant, numba ressemble plus à une boîte noire, et on ne sait pas ce qui se fait en interne, alors que PyCUDA semble très intuitif. Ces deux méthodes ont donc des applications différentes :

* Si vous souhaitez simplement accélérer votre propre algorithme et que vous ne vous souciez pas de la programmation CUDA, il sera préférable d'utiliser directement numba.

* Si vous souhaitez apprendre et rechercher la programmation CUDA ou expérimenter la faisabilité d'un certain algorithme sous CUDA, utilisez PyCUDA.

* Si le programme que vous écrivez sera porté en C/C++ à l'avenir, vous devez utiliser PyCUDA, car le noyau écrit en utilisant PyCUDA lui-même est écrit en CUDA C/C++.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn