English NewsSunday, 15 November 2026
Latest

GEMM in CUDA C++ and Triton, torch.compile and ROCm portability

2026-11-15

Illustrative electricity transmission towers, not GPU hardware.

Illustrative electricity transmission towers, not GPU hardware.

An analytical deep dive into those three frontier areas—GEMM implementation in CUDA C++ vs. Triton, torch.compile (TorchInductor) automated code generation, and AMD ROCm cross-vendor portability—reveals the practical engineering trade-offs behind modern AI systems.

1. Side-by-Side Analysis: Matrix Multiplication (GEMM) in CUDA C++ vs. Triton

Matrix multiplication (C = A × B) is the ultimate benchmark for GPU programming because it is compute-bound and must feed Tensor Cores continuously without stalling on memory.

  • Modern CUDA C++ (CUTLASS / CuTe Approach):
  • Manual Hardware Orchestration: In CUDA C++, achieving peak GEMM speed requires dividing work across a strict hierarchy: Grid → Thread Block (CTA) → Warpgroup (4 warps) → Warp → Tensor Core instruction (wgmma).
  • Explicit Pipelining & Swizzling: Engineers must manually allocate double- or triple-buffered Shared Memory stages (cp.async or TMA) so that while Tensor Cores multiply Tile N, asynchronous hardware engines load Tile N+1. They must also apply XOR memory swizzling to prevent Shared Memory bank conflicts.
  • Analytical Verdict: Unmatched peak performance (90%–98% of theoretical Tensor Core FLOPS), but requires hundreds of lines of brittle, architecture-specific C++ template code.
  • OpenAI Triton Approach:
  • Declarative Tile Math: In Triton, a high-performance tiled GEMM takes roughly 40 lines of Python. The engineer writes a loop over the inner dimension K, loading 2D blocks (tl.load) and calling tl.dot(a, b) to accumulate partial sums.
  • Compiler-Driven Pipelining: Triton’s MLIR backend automatically infers software pipelining stages (num_stages=3), inserts Shared Memory swizzling, and emits Tensor Core instructions. Additionally, @triton.autotune tests different tile sizes (BLOCK_M, BLOCK_N, BLOCK_K) on the target GPU to pick the fastest configuration automatically.
  • Analytical Verdict: Delivers 85%–95% of CUTLASS performance with 10× less code, making it superior for custom fused GEMMs (e.g., GEMM + Bias + GeLU + Quantization) where standard libraries fall short.

2. Analysis of torch.compile (TorchInductor): How PyTorch Writes Triton Automatically

PyTorch 2.0’s torch.compile bridges the gap between eager Python flexibility and compiled kernel speed by using TorchInductor to generate Triton code automatically.

[Eager Python Code] 
       │  1. TorchDynamo (Bytecode Capture)
       ▼
[FX Graph (ATen Ops)] 
       │  2. AOTAutograd (Forward + Backward Decomposition)
       ▼
[TorchInductor Loop IR] 
       │  3. Operator Fusion & Memory Layout Analysis
       ▼
[Generated Triton Python Kernel] ──► [PTX / SASS Binary]
  • How Automated Fusion Works:
  • When you decorate a model with @torch.compile, TorchDynamo intercepts Python bytecode and captures a static computation graph without Python interpreter overhead.
  • TorchInductor lowers ~2,000 high-level PyTorch operators into ~250 core primitives, then analyzes memory dependencies to group adjacent pointwise (e.g., add, mul, silu) and reduction (e.g., sum, mean, softmax) operations together.
  • Instead of calling separate pre-compiled C++ kernels, TorchInductor emits a brand-new Triton Python script on disk (viewable via TORCH_LOGS="output_code"), compiles it via Triton's MLIR backend, and caches the resulting GPU binary.
  • Analytical Trade-Offs (Strengths vs. Limits):
  • Strength: Eliminates manual kernel writing for 80%–90% of standard model bottlenecks, routinely accelerating training and inference by 1.5× to 2.5× with a single line of code.
  • Limitation: Suffers from graph breaks when encountering unsupported dynamic Python control flow, and still struggles to automatically discover complex algorithmic reformulations (such as FlashAttention's online Softmax tiling), which still require hand-written Triton or CUDA kernels.

3. Analysis of Cross-Vendor Portability: NVIDIA CUDA vs. AMD ROCm

For years, NVIDIA’s proprietary CUDA ecosystem created a near-monopoly on AI compute. Modern compiler stacks have systematically eroded this moat by decoupling high-level AI code from vendor-specific hardware backends.

Portability LayerNVIDIA EcosystemAMD ROCm EcosystemAnalytical Comparison
Low-Level C++ KernelsCUDA C++ (nvcc → PTX → SASS)HIP (hipcc → AMDGPU LLVM → GCN/CDNA)High Friction. AMD’s hipify tool translates CUDA syntax to HIP, but warp sizes differ (32 threads on NVIDIA vs. 64 threads on AMD CDNA), breaking hardcoded warp-shuffle math.
Block-Level KernelsOpenAI Triton (NVPTX Backend)OpenAI Triton (AMDGPU Backend)Near-Seamless. Because Triton abstracts away warp sizes behind 2D blocks, a single Triton kernel runs natively on both NVIDIA H100/B200 and AMD Instinct MI300X/MI325X.
Framework LevelPyTorch + torch.compile + vLLMPyTorch + torch.compile + vLLMMature Parity. Major inference engines (vLLM, SGLang) and PyTorch run out-of-the-box on ROCm by routing custom ops through Triton and AMD’s rocBLAS/CK (Composable Kernel).
  • Strategic Takeaway: While hand-written CUDA C++ remains locked to NVIDIA silicon and requires manual porting to AMD HIP, OpenAI Triton acts as a portable hardware abstraction layer. AI teams that standardize custom kernels on Triton can deploy the exact same codebase across NVIDIA and AMD clusters without maintaining separate C++ codebases.

More AI technology news