title: CUDA
text: CUDA, wat staat voor Compute Unified Device Architecture, is een GPGPU-technologie die het de programmeur mogelijk maakt om gebruik te maken van de programmeertaal C om algoritmes uit te voeren op de GPU.
  
  CUDA is ontwikkeld door NVIDIA en om gebruik te maken van deze computerarchitectuur is er een NVIDIA-GPU en een speciale stream processing-driver vereist. CUDA werkt alleen op de nieuwere grafische kaarten GeForce 8-serie, die gebruikmaken van de G8x GPU's; NVIDIA garandeert dat programma's ontwikkeld voor de GeForce 8-serie zonder enige aanpassing zullen werken op alle toekomstige NVIDIA-grafische kaarten. 
  
  CUDA geeft ontwikkelaars toegang tot de native instruction-set en geheugen van de omvangrijke parallelle computerelementen in CUDA GPU-s. Gebruikmakend van CUDA worden de NVIDIA GeForce-gebaseerde GPU's effectief krachtige, programmeerbare open architecturen, zoals hedendaagse CPU's.
  
  Voor- en nadelen 
  CUDA heeft enkele voor- en nadelen ten opzichte van traditionele 'general-purpose computation' op GPU's (GPGPU) door gebruik van API's.
  
  Voordelen:
  Maakt gebruik van standaard C, met enkele simpele extensies;
  Scattered writes - code kan naar willekeurige adressen in het geheugen schrijven;
  Shared memory;
  Snellere downloads en readbacks van en naar de GPU;
  Volledige ondersteuning voor integer- en bit-wise-bewerkingen.
  
  Nadelen:
  Ondersteunt alleen bilinear texture filtering - mipmapped textures en anisotropic filtering worden heden nog niet ondersteund;
  Recursieve functies worden niet ondersteund;
  Enkele afwijkingen ten opzichte van IEEE 754-standaard. Denormals en signalling NaN's worden niet ondersteund, alleen twee afrondingsmethodes worden ondersteund (chop en round-to-nearest even);
  CUDA-enabled GPU's worden alleen door NVIDIA gemaakt (GeForce, Quadro, Tesla).
  
  Ondersteuning 
  Een tabel van apparaten welke officieel ondersteuning van CUDA hebben (Veel applicaties vereisen minstens 256 MB VRAM).
  
  Voorbeeld
  Deze voorbeeldcode in C++ laadt een texture van een afbeelding in een array op de GPU:
  cudaArray* cu_array;
  texture<float, 2> tex;
  
  // Alloceert array
  cudaChannelFormatDesc description = cudaCreateChannelDesc<float>();
  cudaMallocArray(&cu_array, &description, width, height);
  
  // Kopieert afbeelding data naar array
  cudaMemcpy(cu_array, image, width*height*sizeof(float), cudaMemcpyHostToDevice);
  
  // Bindt de array naar de texture
  cudaBindTextureToArray(tex, cu_array);
  
  // Start kernel
  dim3 blockDim(16, 16, 1);
  dim3 gridDim(width / blockDim.x, height / blockDim.y, 1);
  kernel<<< gridDim, blockDim, 0 >>>(d_odata, height, width);
  cudaUnbindTexture(tex);
  
  __global__ void kernel(float* odata, int height, int width)
  {
     unsigned int x = blockIdx.x*blockDim.x + threadIdx.x;
     unsigned int y = blockIdx.y*blockDim.y + threadIdx.y;
     float c = tex2D(tex, x, y);
     odata[y*width+x] = c;
  }
  
  Hieronder is een voorbeeld in Python die het product berekent van twee arrays op de GPU. De onofficiële Python-bindings kunnen worden verkregen van PyCUDA.
  import pycuda.driver as drv
  import numpy
  import pycuda.autoinit
  
  mod = drv.SourceModule("""
  __global__ void multiply_them(float *dest, float *a, float *b)
  {
    const int i = threadIdx.x;
    dest[i] = a[i] * b[i];
  }
  """)
  
  multiply_them = mod.get_function("multiply_them")
  
  a = numpy.random.randn(400).astype(numpy.float32)
  b = numpy.random.randn(400).astype(numpy.float32)
  
  dest = numpy.zeros_like(a)
  multiply_them(
          drv.Out(dest), drv.In(a), drv.In(b),
          block=(400,1,1))
  
  print dest-a*b
  
  Aanvullende Python-bindings om matrixvermenigvuldiging te vereenvoudigen kunnen worden gevonden in het programma pycublas.
  
  import numpy
  from pycublas import CUBLASMatrix
  A = CUBLASMatrix( numpy.mat([[1,2,3], [4,5,6]],numpy.float32) )
  B = CUBLASMatrix( numpy.mat([[2,3], [4,5], [6,7]],numpy.float32) )
  C = A*B
  print C.np_mat()
  
  Programmeerhulpmiddelen 
   Python - PyCUDA
   Java - jCUDA, JCuda, JCublas, JCufft
   .NET - CUDA.NET
   MATLAB - MATLAB plug-in for CUDA, GPUmat, Jacket
   Fortran - FORTRAN CUDA, PGI CUDA Fortran Compiler
  
  Generaties GPU's
  
  Fermi 
  De generatie GPU's met de codenaam Fermi (uitgebracht 27 maart 2010, GeForce 400 Series [GF100]) werd vanaf het begin ontworpen om ondersteuning te bieden voor meer programmeertalen zoals C++. Er wordt verwacht om acht keer de piek double-precision floating-point prestaties te bereiken in vergelijking met Nvidia's vorige-generatie Tesla-GPU. Het introduceert ook een aantal nieuwe functies zoals:
   Tot 512 CUDA-cores en 3 miljard transistors
   NVIDIA Parallel DataCache
   NVIDIA GigaThread engine
   Ondersteuning voor ECC-geheugen
   Gedegen ondersteuning voor Microsoft Visual Studio
  
  Kepler 
  Kepler (2016) ondersteunt eveneens CUDA.
  
  Volta 
  Volta is anno 2018 de meest recente generatie van grafische kaarten. Deze ondersteunt ook CUDA.
  
  Zie ook 
   OpenCL
   GPU cluster
   Jacket, een CUDA-engine voor MATLAB
   Scalable Link Interface (SLI)
  
  Externe link 
   Officiële website
  
  Grafische kaart
  Computerrandapparatuur
  3D-computergraphics
  C (programmeertaal)
  Freeware