Tensor cores and matrix operations
What Are Tensor Cores?
How Matrix Multiplication Works (From Scratch)

Traditional Approach: Element-by-Element
For C = A × B where A is M×K, B is K×N, C is M×N:
On CUDA cores: Each thread computes one C[i][j] by:
- Loading row i of A (K elements)
- Loading column j of B (K elements)
- Performing K multiply-adds serially
- Writing result to C[i][j]
Problem: For 1024×1024 matrices, that's 1024³ ≈ 1 billion FMAs (≈ 2 billion FLOPs). At 10 TFLOPS (10×10¹² FLOPS), that's about ms of pure compute — but memory stalls and poor reuse make the real CUDA-core time much worse.
Tensor Core Approach: Tiled Matrix Operations
Key insight: Break large matrix multiply into small tiles and use specialized hardware for each tile.
Complete Algorithm for Large Matrix Multiply
Problem: Multiply 1024×1024 matrices using 4×4 Tensor Cores.
Solution: Tiled multiply with accumulation
# Pseudocode for C = A × B using Tensor Cores
M, N, K = 1024, 1024, 1024
TILE = 4
for i in range(0, M, TILE): # Tile rows of A
for j in range(0, N, TILE): # Tile columns of B
D_tile = zeros(TILE, TILE) # Accumulator
for k in range(0, K, TILE): # Tile inner dimension
A_tile = A[i:i+TILE, k:k+TILE]
B_tile = B[k:k+TILE, j:j+TILE]
# SINGLE TENSOR CORE INSTRUCTION
D_tile = mma_sync(A_tile, B_tile, D_tile)
C[i:i+TILE, j:j+TILE] = D_tileWhy this works:
- Tiling preserves correctness: Matrix multiply is associative, so we can sum partial products
- Each iteration computes a 4×4 partial product:
A[i:i+4, k:k+4] × B[k:k+4, j:j+4] - Accumulation in
D_tilesums all K/4 partial products for final result - Outer loops cover all tiles of output matrix C
Performance calculation:
- Scalar FMAs: 1024³ ≈ 1.07 billion FMAs
- Number of Tensor Core ops: (1024/4)³ = 256³ ≈ 16.8 million
- Ratio: → 64× instruction reduction compared to scalar (each Tensor Core op does 4×4×4 = 64 FMAs)
Precision Modes and Their Impact
Programming Tensor Cores
WMMA API (Warp-level Matrix Multiply Accumulate)
#include <mma.h>
using namespace nvcuda::wmma;
__global__ void matmul_tensor_core(
half *A, half *B, float *C, int M, int N, int K) {
// Each warp computes a 16×16 tile of C
int warpM = (blockIdx.x * blockDim.x + threadIdx.x) / 32;
int warpN = (blockIdx.y * blockDim.y + threadIdx.y);
// Declare fragments (distributed across warp)
fragment<matrix_a, 16, 16, 16, half, row_major> a_frag;
fragment<matrix_b, 16, 16, 16, half, col_major> b_frag;
fragment<accumulator, 16, 16, 16, float> c_frag;
fill_fragment(c_frag, 0.0f); // Initialize accumulator
// Tile K dimension
for (int i = 0; i < K; i += 16) {
// Load tiles (each thread gets its portion)
load_matrix_sync(a_frag, A + warpM*16*K + i, K);
load_matrix_sync(b_frag, B + i*N + warpN*16, N);
// TENSOR CORE OPERATION
mma_sync(c_frag, a_frag, b_frag, c_frag);
}
// Store result
store_matrix_sync(C + warpM*16*N + warpN*16, c_frag, N, mem_row_major);
}Why each step?
fragment: Data distributed across 32 threads of warp (each thread holds a piece of the tile)load_matrix_sync: Warp-level load, each thread fetches its portion from global memorymma_sync: The Tensor Core instruction — all 32 threads participate cooperativelystore_matrix_sync: Warp-level store, accumulator fragment → global memory
cuBLAS and cuDNN Automatic Use
import torch
# PyTorch automatically uses Tensor Cores when:
# 1. Input dtype is float16, bfloat16, or TF32
# 2. Dimensions are multiples of 8
# 3. torch.backends.cuda.matmul.allow_tf32 = True (default on Ampere+)
A = torch.randn(1024, 1024, dtype=torch.float16, device='cuda')
B = torch.randn(1024, 1024, dtype=torch.float16, device='cuda')
# Uses Tensor Cores automatically
C = torch.matmul(A, B)Why dimensions should be multiples of 8?
- Tensor Core API tiles are 16×16 (with K in multiples of 8/16 depending on precision)
- Padding to multiples ensures full tile coverage
- Partial tiles need fallback handling (performance cliff)
Common Mistakes and Fixes
Performance Characteristics
Memory Layout and Optimization
When to Use Tensor Cores vs CUDA Cores
| Scenario | Choice | Reason |
|---|---|---|
| Matrix multiply, M=N=K=4096, FP16 | Tensor Cores | Perfect fit: large, aligned, FP16 |
| Matrix multiply, M=N=K=32, FP16 | CUDA Cores | Too small, overhead dominates |
| Element-wise ops (ReLU, exp) | CUDA Cores | No matrix structure to exploit |
| Convolution (large channels) | Tensor Cores | Conv2D is matrix multiply via im2col |
| Attention mechanism (Q, K, V) | Tensor Cores | Multiple batched matmuls |
| FP64 scientific computing | CUDA Cores / FP64 TC | Early Tensor Cores lacked FP64 |
| Sparse matrix multiply | Special | Use Ampere sparse Tensor Cores (2:4 sparsity) |
Recall Explain to a 12-Year-Old
Imagine you have a huge pile of homework: 1000 multiplication problems.
CUDA cores are like having a calculator. You solve one problem, write down the answer, solve the next, write that down... It works, but it's slow. Tensor Cores are like having a magic calculator that solves 64 problems at once. You show it a big grid of numbers, and it instantly gives you the whole grid of answers.
But there's a catch: the magic calculator only works if you give it exactly 64 problems arranged in a neat grid. If you give it 7 problems, it can't help — you have to use the regular calculator.
Deep learning (teaching computers to recognize images, understand speech) is FULL of these big grids of multiplication problems. That's why Tensor Cores make AI computers so much faster!
Connections
- 6.2.1-GPU-vs-CPU-architecture — Why GPUs need specialized units
- 6.2.8-Memory-hierarchy-in-GPUs — How shared memory enables tiling
- 6.2.10-Warp-scheduling-and-execution — How warps map to Tensor Core fragments
- 8.3.4-Mixed-precision-training — Using Tensor Cores in deep learning
- 8.4.2-Quantization-techniques — INT8 and INT4 Tensor Core modes
- 9.1.5-Roofline-model — Analyzing Tensor Core performance limits
- 7.3.6-cuBLAS-and-cuDNN — Libraries that abstract Tensor Core usage
#flashcards/hardware
What is a Tensor Core?
What operation does a Tensor Core perform in one instruction?
Why do Tensor Cores use mixed precision (FP16 input, FP32 accumulate)?
What is the minimum matrix size to efficiently use Tensor Cores?
Why should matrix dimensions be multiples of 8 or 16 for Tensor Cores?
What is the instruction-count reduction from scalar FMAs to 4×4 Tensor Core ops?
What is the correct PTX instruction name for Tensor Core matrix multiply?
mma.sync (exposed in the WMMA API as wmma::mma_sync).How is a 4×4 Tensor Core sub-multiply distributed across a warp on Volta?
What is the theoretical speedup of A100 Tensor Cores over CUDA cores? :::
Concept Map
Hinglish (regional understanding)
Intuition Hinglish mein samjho
Hinglish (regional understanding)
Intuition Hinglish mein samjho
Dekho, yahan core intuition simple hai: deep learning me sabse zyada kaam matrix multiplication ka hota hai — jaise C = A × B — aur ye kaam bahut bada hota hai, 1000×1000 matrices me billions of multiply-add operations lag jaate hain. Traditional CUDA cores ek clock me sirf ek multiply-add karte hain, matlab har number ko digit-by-digit multiply karne jaisa slow process. Isiliye NVIDIA ne Tensor Cores banaye — ye special fixed-function hardware units hain jo ek hi instruction me pura chhota matrix tile (jaise 4×4) ka multiply-accumulate D = A×B + C kar dete hain. Ek instruction me 64 FMAs, matlab CUDA cores se 8-16× zyada throughput!
Ab kaam kaise hota hai bade matrices ke liye? Simple — bada matrix ko chhote-chhote tiles me tod dete hain, phir har tile pe Tensor Core ka mma_sync instruction chalate hain aur results ko accumulate karte jaate hain (woh tiled loop wala pseudocode yahi kar raha hai). Ek interesting detail ye hai ki Volta me ek warp ke 32 threads ko 4 groups of 8 threads me baanta jaata hai, aur har 4×4 sub-multiply cooperatively 8 threads milke karte hain — har thread apna chhota fragment hold karta hai, aur ye mapping WMMA API internally manage karta hai, humein tension lene ki zaroorat nahi. Alag-alag generations (Volta, Turing, Ampere, Hopper) me precision support badhta gaya — FP16 se lekar INT8, INT4, BF16, TF32, aur FP8 tak.
Ye matter isliye karta hai ki aaj ke saare AI models — chahe woh image recognition ho ya ChatGPT jaise LLMs — inki speed literally Tensor Cores pe depend karti hai. Jab tum sunte ho ki koi GPU "AI ke liye fast" hai, toh mostly uske Tensor Cores ki wajah se hi hai. Agar tum ML ya hardware field me jaana chahte ho, toh ye samajhna zaroori hai ki hardware ko matrix operations ke around specialize karke hi itni bari performance gains milti hai — yahi modern deep learning ka backbone hai.