Docs  /  Matrix multiply and TF32

Matrix multiply and TF32

Documentation for the matrix multiply / TF32 work from this chat: concepts, implementation in _CutlassAccel, commands, Lua, correctness, and roadmap.

Related: Cutlass.md · BrainstormIntegrations.md · RemoteCUDA.md · MathNN.md


What TF32 is

TensorFloat-32 is an Ampere+ Tensor Core math mode:

Field Bits
Sign 1
Exponent 8 (same range as FP32)
Mantissa 10 (same as FP16)
  • Values stay stored as FP32 in memory.
  • Multiplies on Tensor Cores use TF32 rounding; accumulators stay FP32.
  • Higher throughput on large GEMMs; small numerical error vs true FP32.
  • Not the same as FP16/BF16 storage, and not available as a CPU instruction (host stays AVX FP32).

Call graph in this codebase

Caller (MathNN, RL, benches, Lua, typed commands)
    │
    ▼
_MathNNDevice::MatMul(device, A,B,C,M,N,K)
    │
    ├─ CPU     → _MatrixAcceleration::MatMul   (AVX / AVX-512 / scalar)
    ├─ GPU     → _CutlassAccel::Gemm
    └─ Remote  → _RemoteCuda::MatMul (+ local fallback)

_CutlassAccel::Gemm
    │
    ├─ precision Tf32 + GPU → cuBLAS GemmEx  CUBLAS_COMPUTE_32F_FAST_TF32  (SM ≥ 8)
    ├─ precision Fp32 + GPU → cuBLAS GemmEx  CUBLAS_COMPUTE_32F
    ├─ cuBLAS / CUDA fail   → host MatrixAcceleration
    └─ no GPU               → host MatrixAcceleration

Layout: host tensors are row-major C[M,N] = A[M,K] @ B[K,N]. cuBLAS is column-major; the implementation uses the standard operand/leading-dimension trick so row-major buffers work without explicit transpose copies of the math result.


Precision enum

enum class Precision { Fp32, Tf32, Fp16, Bf16 };
Value Behavior today
Fp32 cuBLAS FP32 compute, or host FP32
Tf32 cuBLAS TF32 Tensor Core compute when SM ≥ 8; else FP32 cuBLAS/host with note
Fp16 / Bf16 Selected for future conversion paths; currently fall through GPU GEMM policy with host fallback as needed

Typed commands

cutlass status
cutlass set precision fp32|tf32|fp16|bf16
cutlass gemm [M N K]          # default 64³
cutlass bench [size] [n]      # default 256, 5
cutlass check [size]          # default 64; FP32 golden + TF32 probe

Alias: cute ….

Examples:

cutlass set precision tf32
cutlass gemm 1024 1024 1024
cutlass check 128
cutlass bench 1024 10

C++ API

_CutlassAccel::Init();
_CutlassAccel::SetPrecision(_CutlassAccel::Precision::Tf32);

string detail;
bool ok = _CutlassAccel::Gemm(A, B, C, M, N, K, detail);
// detail e.g. "cublas_tf32 sm>=8 ms=..."

// Fused linear (GEMM + bias + optional ReLU)
_CutlassAccel::LinearFused(W, x, bias, y, batch, in_features, out_features, relu, detail);

MathNNDevice GPU path already prefers _CutlassAccel::Gemm first.


Lua API

Registered via BrainstormIntegrations::RegisterLuaGlobals:

cutlass_status()
cutlass_set_precision("tf32")   -- or "fp32", "fp16", "bf16"
ok, detail = cutlass_gemm(128, 128, 128)
print(cutlass_check(64))
print(cutlass_bench(256, 3))

Correctness policy

Check Tolerance / rule
FP32 GPU vs host AVX max_abs_diff < 1e-3 → PASS
TF32 vs host FP32 max_abs_diff < 5e-2 → TF32_OK (wider mantissa error)
Dry / no GPU Host-only; still returns filled C

cutlass check always runs a host golden and reports both FP32 and TF32 probe lines.

Never expect bit-exact TF32 == host FP32.


Performance notes

  • TF32 wins when MMA-bound (large M, N, K).
  • Tiny GEMMs may be faster on host (no PCIe).
  • Optional future: size threshold to skip GPU for small problems.
  • bench reports façade average ms vs pure host average ms.

Function Role TF32?
Gemm Core matmul Yes (cuBLAS)
LinearFused y = act(x @ Wᵀ + b) Via Gemm + host/device epilogue
Dot / BatchDot Embeddings / scores Host AVX (prefer FP32)
Softmax / LayerNorm Attention post-GEMM Prefer FP32
Remote matmul Hybrid worker Local fallback; precision flag future

Preprocessor Meaning
USE_CUDA cuBLAS FP32 GEMM available
AI_USE_TF32 TF32 Tensor Core path compiled in (still runtime-optional)
VS configuration TF32 compile (AI_USE_TF32)
Release-GPU-AVX2 / Release-GPU-AVX512 yes (property EnableTf32 defaults true)
Release-GPU-AVX2-Tensor / *-Tensor yes
Release / Debug / Release-CPU-* no
# TF32 available (then: cutlass set precision tf32)
msbuild /p:Configuration=Release-GPU-AVX2

# GPU but no TF32 code path
msbuild /p:Configuration=Release-GPU-AVX2 /p:EnableTf32=false

# Opt-in on plain Release
msbuild /p:Configuration=Release /p:EnableTf32=true
  • Links: cublas.lib / cublasLt.lib on GPU configs.
  • Requires CUDA 11+ for CUBLAS_COMPUTE_32F_FAST_TF32.
  • Runtime still needs Ampere+ (SM ≥ 8) for actual TF32; otherwise FP32 compute.
  • Optional later: AI_USE_CUTLASS + device .cu.

cutlass status reports tf32_compiled= and tf32_available=.


Roadmap (from brainstorm)

Phase Item
Done cuBLAS FP32 + TF32 behind CutlassAccel::Gemm
Done check / bench / precision command + Lua
Next Batched GEMM, size threshold, TFLOPS in bench
Next Remote worker precision: tf32
Later Real CUTLASS TensorOp TF32 .cu

Safety / product policy

Context Recommended precision
Unit tests / cutlass check Fp32 first
Large MathNN / RL GPU steps Tf32
Embedding cosine / ranking Host FP32 Dot
Logging benches Record prec=, max error, ms

Files

  • CutlassAccel.hpp / CutlassAccel.cpp
  • MatrixAcceleration.hpp / .cpp (+ AVX variants)
  • MathNNDevice.cpp (dispatch)
  • BrainstormIntegrations.cpp (Lua bindings)
  • docs/Cutlass.md (short command card)
Generated from the project markdown docs on 2026-07-24. This is a static, self-contained site.