🧰Ökosystem: Compiler, Bibliotheken, Werkzeuge

Selbst geschriebene Kernels sind nur ein kleiner Teil der GPU-Welt. Meist ruft man hochoptimierte Bibliotheken auf – oder schreibt in Python. Und im Browser gibt es mit WebGPU sogar eine GPU-Schnittstelle zum Ausprobieren.

🏭Vom Quelltext zum GPU-Maschinencode

Klicke auf eine Stufe.
→
→
→
→
Eine .cu-Datei enthält beides: normalen C++-Code für die CPU und Kernels (__global__/__device__) für die GPU.
1nvcc -O3 -arch=sm_86 app.cu -o app

📚Bibliotheken

cuBLAS

Lineare Algebra (BLAS), vor allem Matrixmultiplikation (GEMM) – nutzt Tensor Cores.

cuDNN

Bausteine für neuronale Netze: Faltungen, Attention, Normalisierung. Basis von PyTorch & Co.

cuFFT · cuRAND · cuSPARSE

Fourier-Transformation, Zufallszahlen, dünnbesetzte Matrizen.

Thrust · CUB

C++-Algorithmen wie in der STL (sort, reduce, scan) bzw. Bausteine auf Block-/Warp-Ebene. Heute Teil der CUDA Core Compute Libraries (CCCL).

CUTLASS

C++-Templates für eigene GEMM- und Faltungs-Kernels bis hinunter zu Tensor-Core-Befehlen.

NCCL

Kollektive Kommunikation zwischen mehreren GPUs (All-Reduce …) über NVLink/InfiniBand.

TensorRT

Optimiert trainierte Modelle für schnelle Inferenz (Fusion, geringere Genauigkeit).

Triton

Python-basierte Sprache (von OpenAI) für eigene GPU-Kernels auf Block-Ebene; von PyTorch 2 (torch.compile) genutzt.

🐍GPU aus Python

Vier Wege, von „fertige Operationen aufrufen“ bis „eigene Kernels schreiben“.

PyTorch

Tensoren auf die GPU legen – Operationen rufen intern optimierte Kernels (cuBLAS, cuDNN) auf.

torch_demo.py
1import torch
2
3dev = "cuda" if torch.cuda.is_available() else "cpu"
4a = torch.randn(4096, 4096, device=dev)
5b = torch.randn(4096, 4096, device=dev)
6c = a @ b # Matrixmultiplikation über cuBLAS (ggf. Tensor Cores)
7torch.cuda.synchronize() # Kernel-Starts sind asynchron – vor Zeitmessung warten
8print(torch.cuda.get_device_name(0), torch.cuda.get_device_capability(0))

🔬Profiling und Fehlersuche

Werkzeuge im CUDA Toolkit bzw. Treiber
1nvidia-smi # GPUs, Treiber, Auslastung, Speicher, Prozesse
2nvidia-smi --query-gpu=name,utilization.gpu,memory.used --format=csv -l 1
3nsys profile -o bericht ./app # Nsight Systems: Zeitleiste CPU/GPU, Kopien, Streams
4ncu --set full -o kernel ./app # Nsight Compute: Detailanalyse je Kernel (Occupancy, Speicher, Warps)
5compute-sanitizer ./app # Speicherfehler und Race Conditions finden

🐳Treiber, Toolkit, Container

💡 Treiber ≠ Toolkit
nvidia-smi zeigt oben rechts „CUDA Version“ – das ist die höchste CUDA-Version, die der installierte Treiber unterstützt, nicht das installierte Toolkit. Das Toolkit (Compiler nvcc, Bibliotheken) zeigt nvcc --version. Ist die Laufzeit neuer als der Treiber, meldet CUDA „driver version is insufficient for CUDA runtime version“.
✅ Container
Das NVIDIA Container Toolkit reicht GPU und Treiberbibliotheken in den Container durch. Das CUDA-Laufzeitsystem bringt das Image selbst mit (z. B. nvidia/cuda:…-runtime oder -devel mit nvcc).
Docker mit GPU
1# Host: nur NVIDIA-Treiber + NVIDIA Container Toolkit (kein CUDA Toolkit nötig)
2sudo nvidia-ctk runtime configure --runtime=docker
3sudo systemctl restart docker
4
5# Test: nvidia-smi im Container
6docker run --rm --gpus all nvidia/cuda:12.4.1-base-ubuntu22.04 nvidia-smi
7docker run --rm --gpus '"device=0"' mein-image # nur GPU 0
8
9# docker-compose.yml
10# services:
11# train:
12# image: mein-image
13# deploy:
14# resources:
15# reservations:
16# devices:
17# - driver: nvidia
18# count: all
19# capabilities: [gpu]

🌍CUDA im Vergleich

Die Konzepte sind überall gleich – nur die Namen unterscheiden sich.
CUDAHIP / ROCmOpenCLSYCLMetalWebGPU (WGSL)
HerstellerNVIDIAAMD (HIP auch auf NVIDIA)herstellerübergreifend (Khronos)herstellerübergreifend (Khronos)AppleBrowser (W3C)
ThreadThreadThreadWork-ItemWork-ItemThreadInvocation
BlockBlockBlockWork-GroupWork-GroupThreadgroupWorkgroup
Gleichschritt-GruppeWarp (32)Wavefront (32 oder 64)Sub-GroupSub-GroupSIMD-GroupSubgroup (Erweiterung)
gemeinsamer Speicher__shared____shared__ (LDS)__locallocal_accessorthreadgroupvar<workgroup>
Barriere__syncthreads()__syncthreads()barrier(…)group_barrier(…)threadgroup_barrier(…)workgroupBarrier()

Wavefront-Breite bei AMD: 64 bei GCN/CDNA, bei RDNA wahlweise 32 oder 64. HIP-Code lässt sich mit hipify weitgehend aus CUDA-Code erzeugen.

⚡Live: Compute-Shader im Browser (WebGPU)

Echte GPU-Parallelität auf diesem Gerät: Jedes Element wird von einer eigenen Invocation bearbeitet – gemessen gegen dieselbe Rechnung in JavaScript auf einem CPU-Kern.
compute.wgsl – läuft über WebGPU auf der Grafikkarte dieses Geräts
1@group(0) @binding(0) var<storage, read_write> data: array<f32>;
2@group(0) @binding(1) var<uniform> params: vec4<u32>; // x = n, y = Iterationen
3
4@compute @workgroup_size(256) // 256 Invocations je Workgroup (≈ Block)
5fn main(@builtin(global_invocation_id) gid: vec3<u32>) {
6 let i = gid.x; // ≈ blockIdx.x * blockDim.x + threadIdx.x
7 if (i >= params.x) { return; } // Wächter wie in CUDA
8 var x = data[i];
9 for (var k = 0u; k < params.y; k = k + 1u) {
10 x = x * 0.999 + 0.001; // rechenlastige Schleife
11 }
12 data[i] = x;
13}
Elemente (Invocations)
Iterationen je Element

WebGPU-Begriffe entsprechen CUDA: Invocation ≈ Thread, Workgroup ≈ Block, dispatchWorkgroups(x) ≈ Grid,var<workgroup> ≈ __shared__, workgroupBarrier() ≈ __syncthreads().