Tensor Cores & WMMA: The Second Worklog
Tensor Cores & WMMA: The Second Worklog
Starting with the Volta architecture, NVIDIA GPUs include specialized mixed-precision execution hardware: Tensor Cores.
The Tensor Core Advantage
- Conventional CUDA cores execute 1 FMA (Fused Multiply-Add = 2 FLOPs) per cycle.
- Tensor Cores compute full matrix multiply-accumulate operations (\(D = A imes B + C\)) on small matrix fragments (e.g. \(16 imes 16 imes 16\)) in hardware every cycle.
- Speedup: ~5-10x higher theoretical compute density compared to FP32 CUDA cores.
Direct Programming via WMMA (Warp Matrix Multiply Accumulate)
CUDA provides the nvcuda::wmma C++ API to program Tensor Cores directly from device code:
#include <mma.h>
using namespace nvcuda;
// Cooperative 16x16x16 matrix multiply across 32 threads in a warp
__global__ void wmma_gemm_kernel(const half* A, const half* B, float* C, int M, int N, int K) {
// Declare WMMA fragments
wmma::fragment<wmma::matrix_a, 16, 16, 16, half, wmma::row_major> a_frag;
wmma::fragment<wmma::matrix_b, 16, 16, 16, half, wmma::col_major> b_frag;
wmma::fragment<wmma::accumulator, 16, 16, 16, float> c_frag;
wmma::fill_fragment(c_frag, 0.0f);
for (int k = 0; k < K; k += 16) {
// Load sub-matrices cooperatively across the warp
wmma::load_matrix_sync(a_frag, A + (blockIdx.y * 16 * K) + k, K);
wmma::load_matrix_sync(b_frag, B + (blockIdx.x * 16 * K) + k, K);
// Hardware Tensor Core Matrix Multiply
wmma::mma_sync(c_frag, a_frag, b_frag, c_frag);
}
// Store accumulator fragment back to global memory
wmma::store_matrix_sync(C + (blockIdx.y * 16 * N) + (blockIdx.x * 16), c_frag, N, wmma::mem_row_major);
}